Skip to content

Commit 0f80d0a

Browse files
author
ilitteri
committed
Add example upgrades
1 parent 7c1a15e commit 0f80d0a

File tree

3 files changed

+181
-0
lines changed

3 files changed

+181
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.19;
3+
4+
// import "../src/TestToken.sol";
5+
import "../src/ExampleAlignedTokenV2.sol";
6+
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
7+
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
8+
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
9+
import "forge-std/Script.sol";
10+
import {Vm} from "forge-std/Vm.sol";
11+
import {Utils} from "./Utils.sol";
12+
13+
/// @notice This script upgrades the ClaimableAirdrop contract to ClaimableAirdropV2.
14+
/// @dev The `ProxyAdmin` owner must be the runner of this script since it is the
15+
/// one that will call the upgradeAndCall function of the `ProxyAdmin`.
16+
contract UpgradeToAlignedTokenV2 is Script {
17+
function run(string memory config) public {
18+
string memory root = vm.projectRoot();
19+
string memory path = string.concat(
20+
root,
21+
"/script-config/config.",
22+
config,
23+
".json"
24+
);
25+
string memory config_json = vm.readFile(path);
26+
27+
address _currentTokenProxy = stdJson.readAddress(
28+
config_json,
29+
".tokenProxy"
30+
);
31+
32+
vm.broadcast();
33+
ExampleAlignedTokenV2 _newToken = new ExampleAlignedTokenV2();
34+
35+
bytes memory _tokenUpgradeData = abi.encodeCall(
36+
ProxyAdmin.upgradeAndCall,
37+
(
38+
ITransparentUpgradeableProxy(_currentTokenProxy),
39+
address(_newToken),
40+
abi.encodeCall(ExampleAlignedTokenV2.reinitialize, ())
41+
)
42+
);
43+
44+
console.log(
45+
"To finalize the upgrade, call",
46+
getAdminAddress(_currentTokenProxy),
47+
"with the following calldata"
48+
);
49+
console.logBytes(_tokenUpgradeData);
50+
}
51+
52+
function getAdminAddress(address proxy) internal view returns (address) {
53+
address CHEATCODE_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D;
54+
Vm vm = Vm(CHEATCODE_ADDRESS);
55+
56+
bytes32 adminSlot = vm.load(proxy, ERC1967Utils.ADMIN_SLOT);
57+
return address(uint160(uint256(adminSlot)));
58+
}
59+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.19;
3+
4+
// import "../src/TestToken.sol";
5+
import "../src/ExampleAlignedTokenV3.sol";
6+
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
7+
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
8+
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
9+
import "forge-std/Script.sol";
10+
import {Vm} from "forge-std/Vm.sol";
11+
import {Utils} from "./Utils.sol";
12+
13+
/// @notice This script upgrades the ClaimableAirdrop contract to ClaimableAirdropV2.
14+
/// @dev The `ProxyAdmin` owner must be the runner of this script since it is the
15+
/// one that will call the upgradeAndCall function of the `ProxyAdmin`.
16+
contract UpgradeToAlignedTokenV3 is Script {
17+
function run(string memory config) public {
18+
string memory root = vm.projectRoot();
19+
string memory path = string.concat(
20+
root,
21+
"/script-config/config.",
22+
config,
23+
".json"
24+
);
25+
string memory config_json = vm.readFile(path);
26+
27+
address _currentTokenProxy = stdJson.readAddress(
28+
config_json,
29+
".tokenProxy"
30+
);
31+
32+
vm.broadcast();
33+
ExampleAlignedTokenV3 _newToken = new ExampleAlignedTokenV3();
34+
35+
bytes memory _tokenUpgradeData = abi.encodeCall(
36+
ProxyAdmin.upgradeAndCall,
37+
(
38+
ITransparentUpgradeableProxy(_currentTokenProxy),
39+
address(_newToken),
40+
abi.encodeCall(ExampleAlignedTokenV3.reinitialize, ())
41+
)
42+
);
43+
44+
console.log(
45+
"To finalize the upgrade, call",
46+
getAdminAddress(_currentTokenProxy),
47+
"with the following calldata"
48+
);
49+
console.logBytes(_tokenUpgradeData);
50+
}
51+
52+
function getAdminAddress(address proxy) internal view returns (address) {
53+
address CHEATCODE_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D;
54+
Vm vm = Vm(CHEATCODE_ADDRESS);
55+
56+
bytes32 adminSlot = vm.load(proxy, ERC1967Utils.ADMIN_SLOT);
57+
return address(uint160(uint256(adminSlot)));
58+
}
59+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.19;
3+
4+
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
5+
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
6+
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
7+
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";
8+
import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
9+
10+
contract ExampleAlignedTokenV3 is
11+
Initializable,
12+
ERC20Upgradeable,
13+
ERC20PermitUpgradeable,
14+
ERC20BurnableUpgradeable,
15+
Ownable2StepUpgradeable
16+
{
17+
/// @notice Name of the token.
18+
string public constant NAME = "Test Token";
19+
20+
/// @notice Symbol of the token.
21+
string public constant SYMBOL = "TESTITO";
22+
23+
/// @custom:oz-upgrades-unsafe-allow constructor
24+
constructor() {
25+
_disableInitializers();
26+
}
27+
28+
/// @notice Initializes the contract.
29+
/// @dev This initializer should be called only once.
30+
/// @dev The _foundation must accept the ownership of the contract
31+
/// after deployment in another transaction.
32+
/// @param _foundation address of the foundation.
33+
/// @param _claimSupplier address of the claim supplier. This is the address
34+
/// that will give the tokens to the users that claim them.
35+
function initialize(
36+
address _foundation,
37+
address _claimSupplier
38+
) public initializer {
39+
require(
40+
_foundation != address(0) && _claimSupplier != address(0),
41+
"Invalid _foundation or _claimSupplier"
42+
);
43+
__ERC20_init(NAME, SYMBOL);
44+
__ERC20Permit_init(NAME);
45+
__ERC20Burnable_init();
46+
__Ownable2Step_init(); // default is msg.sender
47+
_transferOwnership(_foundation);
48+
_mint(_foundation, 7_300_000_000e18); // 7.3 billion
49+
_mint(_claimSupplier, 2_700_000_000e18); // 2.7 billion
50+
}
51+
52+
function reinitialize() public reinitializer(3) {}
53+
54+
/// @notice Mints `amount` of tokens.
55+
function mint(address to, uint256 amount) external onlyOwner {
56+
_mint(to, amount * 2);
57+
}
58+
59+
/// @notice Prevents the owner from renouncing ownership.
60+
function renounceOwnership() public view override onlyOwner {
61+
revert("Cannot renounce ownership");
62+
}
63+
}

0 commit comments

Comments
 (0)