Skip to content

Commit 82ba4a7

Browse files
jrchatrucilitteri
andauthored
Upgrade instructions (#1685)
Co-authored-by: ilitteri <[email protected]>
1 parent 8b3e51d commit 82ba4a7

File tree

7 files changed

+142
-257
lines changed

7 files changed

+142
-257
lines changed

claim_contracts/Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,13 @@ deploy-token: ## 🚀 Deploy the token contract
3939
deploy-token-testnet: ## 🚀 Deploy the token contract
4040
cd script && \
4141
forge script DeployAlignedToken.s.sol \
42-
--sig "run(string)" sepolia
42+
--sig "run(string)" sepolia \
4343
--private-key $(DEPLOYER_PRIVATE_KEY) \
4444
--rpc-url $(RPC_URL) \
4545
--broadcast \
46-
--verbosity 3
46+
--verbosity 3 \
47+
--verify \
48+
--etherscan-api-key $(ETHERSCAN_API_KEY)
4749

4850
deploy-token-prod: ## 🚀 Deploy the token contract
4951
cd script && \

claim_contracts/README.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,141 @@ or
103103
```
104104
make deploy-example MERKLE_ROOT=<claims-merkle-root> TIMESTAMP=2733427549
105105
```
106+
107+
# Contract upgrade instructions
108+
109+
To upgrade a contract, first make sure you pause the contract if it's not paused already (NOTE: the erc20 cannot be paused, the claim contract can though). Once that's done, clone the `aligned_layer` repo and go into the `claim_contracts` directory:
110+
111+
> [!NOTE]
112+
> The ERC20 cannot be paused. Only the claimable airdrop proxy can be paused.
113+
114+
```
115+
git clone [email protected]:yetanotherco/aligned_layer.git && cd aligned_layer/claim_contracts
116+
```
117+
118+
## Write the new contract implementation
119+
120+
This implementation will most likely be a copy paste of the old implementation, only with one or few changes. In addition to that, there is one thing that MUST be done on this new contract:
121+
122+
- Add a public `reinitalize function` with a `reinitializer()` modifier that takes in the next version number of the contract (the first version is `1`). As an example, if this is the first upgrade being done, you should add this function to the contract:
123+
124+
> [!WARNING]
125+
> DO NOT UPDATE STORAGE VARIABLES IN THIS AND FOLLOWING UPGRADES, ONLY ADD NEW ONES.
126+
127+
```solidity
128+
function reinitialize() public reinitializer(2) {
129+
if (!paused()) {
130+
_pause();
131+
}
132+
}
133+
```
134+
135+
Put the new implementation in a file inside the `src` directory with an appropriate name.
136+
137+
## Write the deployment script
138+
139+
Under the `script` directory, create a new forge script (with the `.s.sol` extension) with a name like `UpgradeContract.s.sol`, with this code in it:
140+
141+
```solidity
142+
// SPDX-License-Identifier: MIT
143+
pragma solidity ^0.8.19;
144+
145+
import <path_to_upgrade_contract>;
146+
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
147+
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
148+
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
149+
import "forge-std/Script.sol";
150+
import {Vm} from "forge-std/Vm.sol";
151+
import {Utils} from "./Utils.sol";
152+
153+
/// @notice Upgrade contract template
154+
contract UpgradeContract is Script {
155+
function run(string memory config) public {
156+
string memory root = vm.projectRoot();
157+
string memory path = string.concat(
158+
root,
159+
"/script-config/config.",
160+
config,
161+
".json"
162+
);
163+
string memory config_json = vm.readFile(path);
164+
165+
address _currentContractProxy = stdJson.readAddress(
166+
config_json,
167+
".contractProxy"
168+
);
169+
170+
vm.broadcast();
171+
<NameOfUpgradeContract> _newContract = new <NameOfUpgradeContract>();
172+
173+
bytes memory _upgradeCalldata = abi.encodeCall(
174+
ProxyAdmin.upgradeAndCall,
175+
(
176+
ITransparentUpgradeableProxy(_currentContractProxy),
177+
address(_newContract),
178+
abi.encodeCall(<NameOfUpgradeContract>.reinitialize, ())
179+
)
180+
);
181+
182+
console.log(
183+
"Proxy Admin to call:",
184+
getAdminAddress(_currentContractProxy)
185+
);
186+
console.log("Calldata of the transaction: ");
187+
console.logBytes(_upgradeCalldata);
188+
}
189+
190+
function getAdminAddress(address proxy) internal view returns (address) {
191+
address CHEATCODE_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D;
192+
Vm vm = Vm(CHEATCODE_ADDRESS);
193+
194+
bytes32 adminSlot = vm.load(proxy, ERC1967Utils.ADMIN_SLOT);
195+
return address(uint160(uint256(adminSlot)));
196+
}
197+
}
198+
199+
```
200+
201+
then fill in the missing parts (between `<>` brackets), putting the path to the new contract code and the name of it.
202+
203+
> [!IMPORTANT]
204+
> Remember to fill the missing parts (between `<>` brackets) in the script, putting the path to the new contract code and the name of it where needed.
205+
206+
Go into the `config.mainnet.json` file inside the `script-config` directory and fill in the following values:
207+
208+
```
209+
{
210+
"foundation": "",
211+
"contractProxy": ""
212+
}
213+
214+
```
215+
216+
- `foundation` is the address of the foundation safe.
217+
- `contractProxy` is the address of the contract proxy to upgrade.
218+
219+
## Run the deployment script
220+
221+
Run the script with
222+
223+
```
224+
cd script && \
225+
forge script <name_of_the_script.s.sol> \
226+
--sig "run(string)" \
227+
mainnet \
228+
--private-key <private_key> \
229+
--rpc-url <mainnet_rpc_url> \
230+
--broadcast \
231+
--verify \
232+
--etherscan-api-key <etherscan_api_key>
233+
```
234+
235+
After running this script, it will show a message like this:
236+
237+
```
238+
Proxy Admin to call: 0xf447FD34D97317759777E242fF64cEAe9C58Bf9A
239+
Calldata of the transaction:
240+
0x9623609d0000000000000000000000000234947ce63d1a5e731e5700b911fb32ec54c3c3000000000000000000000000f7ac74dbc77e1afda093598c912a6b082dabc31a000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000046c2eb35000000000000000000000000000000000000000000000000000000000
241+
```
242+
243+
Go into the foundation safe, create a new transaction calling the proxy admin address shown in the message with the message's calldata. Done.

claim_contracts/script/UpgradeToAlignedTokenV2.s.sol

Lines changed: 0 additions & 59 deletions
This file was deleted.

claim_contracts/script/UpgradeToAlignedTokenV3.s.sol

Lines changed: 0 additions & 59 deletions
This file was deleted.

claim_contracts/script/UpgradeToken.s.sol

Lines changed: 0 additions & 53 deletions
This file was deleted.

claim_contracts/src/ExampleAlignedTokenV2.sol

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)