← Back to list

upgrade-safety
by IvanTorresEdge
⭐ 0🍴 1📅 Jan 13, 2026
SKILL.md
name: upgrade-safety description: Safe upgrade practices for upgradeable smart contracts. Use when planning or executing contract upgrades.
Upgrade Safety Skill
Reference skill for safe upgrade practices. Detailed upgrade security checklist is in the security-audit skill.
When to Use
Use this skill when:
- Planning contract upgrades
- Executing upgrades
- Reviewing upgrade implementations
- Testing upgrade scenarios
Related Skills
For comprehensive upgrade security, see:
- security-audit:
checklists/upgrade-checklist.md- Complete upgrade security checklist - proxy-patterns: Proxy pattern selection and implementation
- contract-patterns:
patterns/upgradeable-contracts.mdandexamples/upgradeable-example.sol
Upgrade Safety Rules
Storage Layout Safety
Never:
- Delete state variables
- Change variable types
- Change variable order
- Reorder inherited contracts
Always:
- Add new variables at the end
- Use storage gaps
- Document storage layout
- Test storage compatibility
Example:
// V1
contract V1 {
uint256 public value;
address public owner;
uint256[48] private __gap; // Reserve space
}
// V2 - ✅ Safe
contract V2 {
uint256 public value;
address public owner;
uint256 public newValue; // Added at end
uint256[47] private __gap; // Reduced gap
}
Initializer Safety
Always:
- Use
_disableInitializers()in constructor - Use
initializermodifier for init function - Use
reinitializer(version)for upgrade init - Call parent initializers
Example:
contract MyContract is Initializable, UUPSUpgradeable {
constructor() {
_disableInitializers(); // ✅ Required
}
function initialize() public initializer {
__UUPSUpgradeable_init();
}
function initializeV2() public reinitializer(2) {
// V2 initialization
}
}
Authorization Safety
UUPS:
- Always keep
_authorizeUpgradefunction - Use appropriate access control
- Consider timelock for critical upgrades
function _authorizeUpgrade(address) internal override onlyOwner {}
Never remove this function in UUPS upgrades!
Upgrade Process
Pre-Upgrade Checklist
- Storage layout verified compatible
- New implementation tested
- Initializers properly protected
- Authorization functions present
- Tests passing
- Storage verification tool run
- Deployment addresses verified
- Backup plan prepared
Verification Tools
Foundry:
# Check storage layout
forge inspect MyContract storage-layout
# Compare layouts
forge inspect MyContractV1 storage-layout > v1.json
forge inspect MyContractV2 storage-layout > v2.json
diff v1.json v2.json
Hardhat:
# Validate upgrade
npx hardhat verify-upgrade <PROXY> <NEW_IMPL>
Slither:
# Check upgradeability
slither-check-upgradeability . MyContract
During Upgrade
- Pause if applicable
- Deploy new implementation
- Verify implementation
- Execute upgrade
- Verify proxy points to new implementation
- Test critical functions
- Unpause if paused
Post-Upgrade
- Verify implementation address
- Test all critical functions
- Monitor for issues
- Document changes
- Update documentation
Testing Upgrades
Storage Preservation Test
function test_UpgradePreservesStorage() public {
// Deploy V1
MyContractV1 v1 = new MyContractV1();
v1.initialize(owner);
v1.setValue(42);
// Deploy V2 implementation
MyContractV2 implementation = new MyContractV2();
// Simulate upgrade (actual upgrade depends on proxy pattern)
// ...
// Cast to V2 interface
MyContractV2 v2 = MyContractV2(address(v1));
// Verify storage preserved
assertEq(v2.getValue(), 42);
assertEq(v2.owner(), owner);
}
Fork Testing
function test_UpgradeOnFork() public {
// Fork mainnet
vm.createSelectFork(vm.envString("MAINNET_RPC_URL"));
// Get existing proxy
MyContract proxy = MyContract(PROXY_ADDRESS);
// Deploy new implementation
MyContract newImpl = new MyContract();
// Upgrade
vm.prank(OWNER);
proxy.upgradeTo(address(newImpl));
// Verify
assertEq(proxy.version(), 2);
}
Common Upgrade Mistakes
❌ 1. Storage Collision
// V1
contract V1 {
uint256 public value;
}
// V2 - ❌ Wrong!
contract V2 {
address public owner; // Overwrites value!
uint256 public value;
}
❌ 2. Uninitialized Implementation
// ❌ Missing constructor protection
contract MyContract {
function initialize() public initializer {
// Attacker can initialize implementation!
}
}
❌ 3. Removed Authorization
// V1
contract V1 is UUPSUpgradeable {
function _authorizeUpgrade(address) internal override onlyOwner {}
}
// V2 - ❌ Removed authorization!
contract V2 is UUPSUpgradeable {
// Missing _authorizeUpgrade - contract is now non-upgradeable!
}
❌ 4. Selfdestruct in Implementation
// ❌ Never use selfdestruct in upgradeable contracts
function destroy() public {
selfdestruct(payable(owner)); // Kills implementation for all proxies!
}
Security Considerations
- Multi-sig for upgrades - Never use single key in production
- Timelock delays - Give users time to exit before upgrade
- Pause before upgrade - Prevent state changes during upgrade
- Test on testnet - Always test upgrades before mainnet
- Emergency procedures - Have rollback plan ready
Best Practices
- Always use OpenZeppelin upgradeable contracts
- Test upgrades on fork before mainnet
- Use storage gaps (50 slots) in base contracts
- Document storage layout changes
- Never remove _authorizeUpgrade in UUPS
- Use reinitializer for upgrade initialization
- Verify storage compatibility with tools
- Multi-sig + timelock for production
- Monitor after upgrade
- Have rollback plan
Tools
| Tool | Purpose | Command |
|---|---|---|
| Foundry | Storage layout | forge inspect Contract storage-layout |
| Hardhat | Verify upgrade | npx hardhat verify-upgrade |
| Slither | Check upgrade safety | slither-check-upgradeability |
| OpenZeppelin Defender | Upgrade automation | Web interface |
Related Documentation
- Detailed checklist:
security-audit/checklists/upgrade-checklist.md - Proxy patterns:
proxy-patterns/SKILL.md - Implementation examples:
contract-patterns/patterns/upgradeable-contracts.md - Example contract:
contract-patterns/examples/upgradeable-example.sol
Note: This is a reference skill. For the complete upgrade security checklist, see security-audit/checklists/upgrade-checklist.md.
Score
Total Score
60/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
Reviews
💬
Reviews coming soon