Files
script/AuthorizeUpgrade.s.sol
2026-02-09 21:51:51 -08:00

92 lines
3.5 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Script.sol";
import "../src/eMoneyToken.sol";
import "./helpers/EnvValidation.sol";
/**
* @title AuthorizeUpgrade
* @notice Helper script to authorize a token upgrade
* @dev This script should be run from a multisig wallet with DEFAULT_ADMIN_ROLE.
* IMPORTANT: Only use this after thorough testing and multisig approval.
*/
contract AuthorizeUpgrade is Script {
using EnvValidation for string;
function run() external {
// Validate environment variables
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
address tokenProxyAddr = vm.envAddress("TOKEN_PROXY_ADDRESS");
address newImplementationAddr = vm.envAddress("NEW_IMPLEMENTATION_ADDRESS");
EnvValidation.validateAddress(tokenProxyAddr, "TOKEN_PROXY_ADDRESS");
EnvValidation.validateAddress(newImplementationAddr, "NEW_IMPLEMENTATION_ADDRESS");
vm.startBroadcast(deployerPrivateKey);
address deployer = vm.addr(deployerPrivateKey);
eMoneyToken tokenProxy = eMoneyToken(tokenProxyAddr);
console.log("=== Authorize Upgrade ===");
console.log("Deployer:", deployer);
console.log("Token Proxy:", vm.toString(tokenProxyAddr));
console.log("New Implementation:", vm.toString(newImplementationAddr));
console.log("");
// Verify deployer has DEFAULT_ADMIN_ROLE
bytes32 adminRole = tokenProxy.DEFAULT_ADMIN_ROLE();
require(
tokenProxy.hasRole(adminRole, deployer),
"AuthorizeUpgrade: deployer does not have DEFAULT_ADMIN_ROLE"
);
console.log(" [OK] Deployer has DEFAULT_ADMIN_ROLE");
console.log("");
// Verify new implementation has code
require(newImplementationAddr.code.length > 0, "AuthorizeUpgrade: new implementation has no code");
console.log(" [OK] New implementation has code");
console.log("");
// Get current implementation
address currentImplementation = _getImplementation(tokenProxyAddr);
console.log("Current Implementation:", vm.toString(currentImplementation));
console.log("New Implementation:", vm.toString(newImplementationAddr));
console.log("");
// Confirm upgrade
console.log("⚠️ WARNING: This will upgrade the token implementation!");
console.log(" Make sure you have:");
console.log(" 1. Validated storage layout compatibility");
console.log(" 2. Tested on testnet");
console.log(" 3. Received multisig approval");
console.log("");
console.log("To proceed, uncomment the following line:");
console.log(" // tokenProxy.upgradeTo(newImplementationAddr);");
console.log("");
// Uncomment the following line to actually perform the upgrade
// tokenProxy.upgradeTo(newImplementationAddr);
console.log(" [SKIP] Upgrade not executed (commented out for safety)");
console.log(" [INFO] To execute upgrade, uncomment the upgradeTo() call above");
vm.stopBroadcast();
}
/**
* @notice Gets the implementation address from a UUPS proxy
* @param proxyAddr The proxy address
* @return implementation The implementation address
*/
function _getImplementation(address proxyAddr) internal view returns (address implementation) {
bytes32 slot = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
assembly {
implementation := sload(slot)
}
}
}