Appearance
Protocol Upgradeability Overview
Introduction
Textile Protocol v2.1 uses a hybrid upgradeability approach designed to balance security, efficiency, and operational flexibility.
Upgradeability Patterns
BeaconProxy Pattern (Pools & Tranches)
All StructuredPool and Tranche instances use the BeaconProxy pattern.
How It Works
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Pool 1 │────▶│ │ │ │
├────────────┤ │ Beacon │────▶│ Pool Impl │
│ Pool 2 │────▶│ (Pool) │ │ V2.1.0 │
├────────────┤ │ │ │ │
│ Pool 3 │────▶│ │ └────────────┘
└────────────┘ └────────────┘
BeaconProxies Upgradeable Implementation- Each pool/tranche: Lightweight BeaconProxy (~$5-10 to deploy)
- Beacon: Central contract storing current implementation address
- Upgrade: Update beacon → all instances upgraded simultaneously
Benefits
✅ Mass Upgrades: Update all pools and tranches at once ✅ Gas Efficient: Similar cost to minimal clones ✅ No Size Limits: Avoids 24KB contract limit ✅ Timelock Protected: 2-day delay on beacon upgrades ✅ Operationally Simple: Maintain single version across all instances ✅ Consolidated Architecture: StructuredPool includes integrated credit line (no separate controller needed)
Trade-offs
⚠️ All-or-nothing: Cannot upgrade individual instances ⚠️ Coordinated rollout: All instances change simultaneously
UUPS Pattern (Infrastructure)
Infrastructure contracts (Registry, future additions) use UUPS with timelock.
How It Works
┌────────────┐
│ Users │
└──────┬─────┘
│
▼
┌────────────┐ ┌───────────────┐
│ ERC1967 │──────▶│ Registry │
│ Proxy │ deleg │ Implementation│
└────────────┘ call └───────────────┘
(State) (Logic)- Individual control: Each contract upgrades independently
- Time lock: 2-day delay enforced
- Flexible: Can add custom upgrade logic
Benefits
✅ Independent upgrades: Don't affect other contracts ✅ Proven pattern: Well-audited OpenZeppelin standard ✅ Custom logic: Can add special requirements
Access Control
Separate Admin Roles
All upgradeable contracts use two independent roles:
PROTOCOL_ADMIN
- Schedules upgrades
- Executes upgrades (after timelock)
- Cancels pending upgrades
- Manages protocol operations
TIMELOCK_ADMIN
- Configures upgrade delay (1 hour to 30 days)
- Cannot schedule or execute upgrades
- Independent governance
Two-Party Security
To rush an upgrade (reduce delay), both admins must cooperate:
TIMELOCK_ADMINreduces delay to minimum (1 hour)PROTOCOL_ADMINschedules and executes upgrade
This prevents a single compromised admin from pushing malicious upgrades.
Multi-Sig Recommendations
For production deployments:
- Protocol Admin: 5/9 multi-sig (execution power)
- Timelock Admin: 3/5 multi-sig (veto power)
- Key requirement: Different signers for each multi-sig
Upgrade Workflows
Beacon Upgrade (Pools/Tranches)
Upgrades all pool or tranche instances:
Steps:
- Deploy new
StructuredPoolimplementation - Schedule upgrade on beacon (PROTOCOL_ADMIN)
- Wait for timelock period (2 days default)
- Execute upgrade (PROTOCOL_ADMIN)
- All pools instantly use new implementation ✅
Example:
solidity
// 1. Deploy new implementation
StructuredPoolV2 newImpl = new StructuredPoolV2();
// 2. Get beacon from factory
UpgradeableBeaconWithTimelock beacon = factory.poolBeacon();
// 3. Schedule upgrade
beacon.connect(protocolAdmin).scheduleUpgrade(address(newImpl));
// 4. Wait 2 days...
// 5. Execute
beacon.connect(protocolAdmin).executeUpgrade(address(newImpl));Cost Example (Celo Mainnet):
- Schedule upgrade: ~1.25 CELO ($0.31)
- Execute upgrade: ~2.5 CELO ($0.62)
- Total: ~3.75 CELO ($0.93) to upgrade ALL instances
UUPS Upgrade (Registry)
Upgrades single infrastructure contract:
Steps:
- Deploy new
Registryimplementation - Schedule upgrade on Registry (PROTOCOL_ADMIN)
- Wait for timelock period (2 days default)
- Call
upgradeToAndCall()(PROTOCOL_ADMIN) - Contract uses new implementation ✅
Example:
solidity
// 1. Deploy new implementation
RegistryV2 newImpl = new RegistryV2();
// 2. Schedule on Registry
registry.connect(protocolAdmin).scheduleUpgrade(address(newImpl));
// 3. Wait 2 days...
// 4. Execute
registry.connect(protocolAdmin).upgradeToAndCall(address(newImpl), "0x");Emergency Procedures
Cancel Pending Upgrade
If vulnerability discovered in scheduled implementation:
solidity
// Cancel immediately (as PROTOCOL_ADMIN)
beacon.connect(protocolAdmin).cancelUpgrade();
// or
registry.connect(protocolAdmin).cancelUpgrade();Rush Emergency Fix
If critical bug requires immediate fix:
Timelock Admin reduces delay to 1 hour:
soliditybeacon.connect(timelockAdmin).setUpgradeDelay(1 hours);Protocol Admin schedules fix:
soliditybeacon.connect(protocolAdmin).scheduleUpgrade(emergencyFixImpl);Wait 1 hour (minimum timelock)
Protocol Admin executes:
soliditybeacon.connect(protocolAdmin).executeUpgrade(emergencyFixImpl);Timelock Admin restores normal delay:
soliditybeacon.connect(timelockAdmin).setUpgradeDelay(2 days);
Monitoring
Critical Events
Monitor these events 24/7:
Beacon Events
solidity
event UpgradeScheduled(address indexed implementation, uint256 scheduledTime);
event UpgradeCancelled(address indexed implementation);
event Upgraded(address indexed implementation);
event UpgradeDelayUpdated(uint256 newDelay);Registry Events
solidity
event UpgradeScheduled(address indexed implementation, uint256 scheduledTime);
event UpgradeCancelled(address indexed implementation);
event Upgraded(address indexed implementation);
event UpgradeDelayUpdated(uint256 newDelay);Alerting Strategy
- UpgradeScheduled: Immediate review of new implementation
- UpgradeDelayUpdated: Verify timelock admin authorization
- UpgradeCancelled: Investigate cancellation reason
- Upgraded: Verify successful upgrade, monitor for anomalies
Gas Costs (Celo Mainnet)
Costs calculated with 25 Gwei gas price and $0.24867 CELO price
Deployment Costs
| Component | Gas | Cost (CELO) | Cost (USD) |
|---|---|---|---|
| Pool Beacon | 1.5M | 37.5 CELO | $9.33 |
| Tranche Beacon | 1.5M | 37.5 CELO | $9.33 |
| BeaconProxy (pool) | 200k | 5.0 CELO | $1.24 |
| BeaconProxy (tranche) | 200k | 5.0 CELO | $1.24 |
Operation Costs
- Delegate call overhead: +2k gas per call (~$0.01)
- Negligible compared to operation costs
Upgrade Costs
| Operation | Gas | Cost (CELO) | Cost (USD) |
|---|---|---|---|
| Schedule beacon upgrade | 50k | 1.25 CELO | $0.31 |
| Execute beacon upgrade | 100k | 2.5 CELO | $0.62 |
| Schedule UUPS upgrade | 50k | 1.25 CELO | $0.31 |
| Execute UUPS upgrade | 100k | 2.5 CELO | $0.62 |
Version Management
Checking Versions
solidity
// Pool/Tranche version (via beacon)
string memory poolVersion = pool.version(); // "2.1.0"
string memory trancheVersion = tranche.version(); // "2.1.0"
// Current implementations
(address poolImpl, address trancheImpl) = factory.getCurrentImplementations();
// Beacon addresses
address poolBeacon = address(factory.poolBeacon());
address trancheBeacon = address(factory.trancheBeacon());
// Registry version
string memory registryVersion = registry.version(); // "2.1.0"Version Compatibility
- Pool ↔ Tranche: Must use compatible versions
- All ↔ Registry: Registry version >= all other components
Best Practices
Pre-Upgrade Checklist
✅ New implementation thoroughly audited ✅ Formal verification completed (if applicable) ✅ Storage layout compatibility verified ✅ Tested on testnet with production-like state ✅ Emergency rollback plan prepared ✅ Community notified via governance forum ✅ Monitoring dashboards ready
During Upgrade
✅ Monitor events in real-time ✅ Have emergency cancellation ready ✅ Team on standby for 24h post-upgrade ✅ Gradual feature rollout if possible
Post-Upgrade
✅ Verify all contracts upgraded correctly ✅ Monitor for anomalies (48 hours minimum) ✅ Publish post-mortem if issues occurred ✅ Update documentation
Security Considerations
Attack Vectors
Compromised Protocol Admin
- ⚠️ Risk: Medium
- 🛡️ Mitigation: Cannot bypass timelock, multi-sig required
Compromised Timelock Admin
- ⚠️ Risk: Low
- 🛡️ Mitigation: Cannot execute upgrades, only adjust delay
Both Admins Compromised
- 🚨 Risk: Critical
- 🛡️ Mitigation: 1-hour minimum timelock, different multi-sig members, 24/7 monitoring
Malicious Implementation
- 🚨 Risk: Critical
- 🛡️ Mitigation: Audits, formal verification, community review during timelock
Storage Collision
- ⚠️ Risk: Medium
- 🛡️ Mitigation: OpenZeppelin storage gaps, automated validation tools
Defense in Depth
The protocol uses multiple security layers:
- Role Separation: PROTOCOL_ADMIN ≠ TIMELOCK_ADMIN
- Multi-sig: Multiple signers required for each role
- Timelock: Minimum 2-day delay for community review
- Monitoring: 24/7 event monitoring and alerting
- Audits: Professional security audits before upgrades
- Testnet: Full testing on testnet before mainnet
Migration Guide
From v2.0 to v2.1
Old pools (minimal clones) cannot be upgraded. Options:
- Keep running: Old pools remain functional
- Gradual migration: Deploy v2.1 pools, migrate liquidity over time
- Coordinated sunset: Close old pools, open new v2.1 pools
New deployments automatically use v2.1 with BeaconProxy pattern.