Skip to content

Commit 1a99024

Browse files
committed
chore: deploy new FuelChainState implementation with 1 day to finalize
chore: add script to propose multisig transaction chore: propose to multisig
1 parent d0e0412 commit 1a99024

File tree

5 files changed

+355
-7
lines changed

5 files changed

+355
-7
lines changed

packages/solidity-contracts/.openzeppelin/mainnet.json

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,6 +1852,203 @@
18521852
},
18531853
"namespaces": {}
18541854
}
1855+
},
1856+
"089c07fdfa68201d9ca54d7980da0e780d3b8b08226fd1f10bbca8ad0c83aec5": {
1857+
"address": "0x621850dbB9160b54002B4a25b9fC9b2F26315f7e",
1858+
"txHash": "0x4ad4b9ae7bcc6a88d10cf05309f42061f9fc26d497b093caf142fb51c6c3fbc1",
1859+
"layout": {
1860+
"solcVersion": "0.8.9",
1861+
"storage": [
1862+
{
1863+
"label": "_initialized",
1864+
"offset": 0,
1865+
"slot": "0",
1866+
"type": "t_uint8",
1867+
"contract": "Initializable",
1868+
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63",
1869+
"retypedFrom": "bool"
1870+
},
1871+
{
1872+
"label": "_initializing",
1873+
"offset": 1,
1874+
"slot": "0",
1875+
"type": "t_bool",
1876+
"contract": "Initializable",
1877+
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68"
1878+
},
1879+
{
1880+
"label": "__gap",
1881+
"offset": 0,
1882+
"slot": "1",
1883+
"type": "t_array(t_uint256)50_storage",
1884+
"contract": "ContextUpgradeable",
1885+
"src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:40"
1886+
},
1887+
{
1888+
"label": "_paused",
1889+
"offset": 0,
1890+
"slot": "51",
1891+
"type": "t_bool",
1892+
"contract": "PausableUpgradeable",
1893+
"src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29"
1894+
},
1895+
{
1896+
"label": "__gap",
1897+
"offset": 0,
1898+
"slot": "52",
1899+
"type": "t_array(t_uint256)49_storage",
1900+
"contract": "PausableUpgradeable",
1901+
"src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:116"
1902+
},
1903+
{
1904+
"label": "__gap",
1905+
"offset": 0,
1906+
"slot": "101",
1907+
"type": "t_array(t_uint256)50_storage",
1908+
"contract": "ERC165Upgradeable",
1909+
"src": "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol:41"
1910+
},
1911+
{
1912+
"label": "_roles",
1913+
"offset": 0,
1914+
"slot": "151",
1915+
"type": "t_mapping(t_bytes32,t_struct(RoleData)23_storage)",
1916+
"contract": "AccessControlUpgradeable",
1917+
"src": "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol:57"
1918+
},
1919+
{
1920+
"label": "__gap",
1921+
"offset": 0,
1922+
"slot": "152",
1923+
"type": "t_array(t_uint256)49_storage",
1924+
"contract": "AccessControlUpgradeable",
1925+
"src": "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol:260"
1926+
},
1927+
{
1928+
"label": "__gap",
1929+
"offset": 0,
1930+
"slot": "201",
1931+
"type": "t_array(t_uint256)50_storage",
1932+
"contract": "ERC1967UpgradeUpgradeable",
1933+
"src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:169"
1934+
},
1935+
{
1936+
"label": "__gap",
1937+
"offset": 0,
1938+
"slot": "251",
1939+
"type": "t_array(t_uint256)50_storage",
1940+
"contract": "UUPSUpgradeable",
1941+
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:111"
1942+
},
1943+
{
1944+
"label": "_commitSlots",
1945+
"offset": 0,
1946+
"slot": "301",
1947+
"type": "t_array(t_struct(Commit)7068_storage)240_storage",
1948+
"contract": "FuelChainState",
1949+
"src": "contracts/fuelchain/FuelChainState.sol:67"
1950+
}
1951+
],
1952+
"types": {
1953+
"t_address": {
1954+
"label": "address",
1955+
"numberOfBytes": "20"
1956+
},
1957+
"t_array(t_struct(Commit)7068_storage)240_storage": {
1958+
"label": "struct Commit[240]",
1959+
"numberOfBytes": "15360"
1960+
},
1961+
"t_array(t_uint256)49_storage": {
1962+
"label": "uint256[49]",
1963+
"numberOfBytes": "1568"
1964+
},
1965+
"t_array(t_uint256)50_storage": {
1966+
"label": "uint256[50]",
1967+
"numberOfBytes": "1600"
1968+
},
1969+
"t_bool": {
1970+
"label": "bool",
1971+
"numberOfBytes": "1"
1972+
},
1973+
"t_bytes32": {
1974+
"label": "bytes32",
1975+
"numberOfBytes": "32"
1976+
},
1977+
"t_mapping(t_address,t_bool)": {
1978+
"label": "mapping(address => bool)",
1979+
"numberOfBytes": "32"
1980+
},
1981+
"t_mapping(t_bytes32,t_struct(RoleData)23_storage)": {
1982+
"label": "mapping(bytes32 => struct AccessControlUpgradeable.RoleData)",
1983+
"numberOfBytes": "32"
1984+
},
1985+
"t_struct(Commit)7068_storage": {
1986+
"label": "struct Commit",
1987+
"members": [
1988+
{
1989+
"label": "blockHash",
1990+
"type": "t_bytes32",
1991+
"offset": 0,
1992+
"slot": "0"
1993+
},
1994+
{
1995+
"label": "timestamp",
1996+
"type": "t_uint32",
1997+
"offset": 0,
1998+
"slot": "1"
1999+
},
2000+
{
2001+
"label": "reserved1",
2002+
"type": "t_address",
2003+
"offset": 4,
2004+
"slot": "1"
2005+
},
2006+
{
2007+
"label": "reserved2",
2008+
"type": "t_uint16",
2009+
"offset": 24,
2010+
"slot": "1"
2011+
}
2012+
],
2013+
"numberOfBytes": "64"
2014+
},
2015+
"t_struct(RoleData)23_storage": {
2016+
"label": "struct AccessControlUpgradeable.RoleData",
2017+
"members": [
2018+
{
2019+
"label": "members",
2020+
"type": "t_mapping(t_address,t_bool)",
2021+
"offset": 0,
2022+
"slot": "0"
2023+
},
2024+
{
2025+
"label": "adminRole",
2026+
"type": "t_bytes32",
2027+
"offset": 0,
2028+
"slot": "1"
2029+
}
2030+
],
2031+
"numberOfBytes": "64"
2032+
},
2033+
"t_uint16": {
2034+
"label": "uint16",
2035+
"numberOfBytes": "2"
2036+
},
2037+
"t_uint256": {
2038+
"label": "uint256",
2039+
"numberOfBytes": "32"
2040+
},
2041+
"t_uint32": {
2042+
"label": "uint32",
2043+
"numberOfBytes": "4"
2044+
},
2045+
"t_uint8": {
2046+
"label": "uint8",
2047+
"numberOfBytes": "1"
2048+
}
2049+
},
2050+
"namespaces": {}
2051+
}
18552052
}
18562053
}
18572054
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import path from 'path';
2+
import { password } from '@inquirer/prompts';
3+
import type { TransactionResponse } from 'ethers';
4+
import type { HardhatRuntimeEnvironment } from 'hardhat/types';
5+
import type { DeployFunction } from 'hardhat-deploy/dist/types';
6+
import { FuelChainState__factory as FuelChainState } from '../../typechain';
7+
8+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
9+
const {
10+
ethers,
11+
upgrades: { prepareUpgrade },
12+
deployments: { save },
13+
} = hre;
14+
15+
const privateKey = await password({ message: 'Enter private key' });
16+
const deployer = new ethers.Wallet(privateKey, ethers.provider);
17+
18+
console.log('Upgrading FuelChainState contract');
19+
20+
const contractDeployment = await hre.deployments.get('FuelChainState');
21+
22+
const BLOCKS_PER_COMMIT_INTERVAL = 10800;
23+
const TIME_TO_FINALIZE = 3600 * 24;
24+
const COMMIT_COOLDOWN = TIME_TO_FINALIZE;
25+
26+
const constructorArgs = [
27+
TIME_TO_FINALIZE,
28+
BLOCKS_PER_COMMIT_INTERVAL,
29+
COMMIT_COOLDOWN,
30+
];
31+
32+
const factory = await hre.ethers.getContractFactory(
33+
'FuelChainState',
34+
deployer
35+
);
36+
37+
const response = (await prepareUpgrade(contractDeployment.address, factory, {
38+
kind: 'uups',
39+
constructorArgs,
40+
getTxResponse: true,
41+
redeployImplementation: 'always',
42+
})) as TransactionResponse;
43+
await response.wait();
44+
45+
const receipt = await hre.ethers.provider.getTransactionReceipt(
46+
response.hash
47+
);
48+
49+
const implementation = receipt?.contractAddress ?? '';
50+
51+
if (implementation === '')
52+
throw new Error(
53+
`Upgrade proposal failed for FuelChainState proxy (${contractDeployment.address})`
54+
);
55+
56+
console.log(`Deployed FuelChainState ${implementation}`);
57+
58+
await save('FuelChainState', {
59+
address: contractDeployment.address,
60+
abi: [...FuelChainState.abi],
61+
implementation,
62+
transactionHash: response.hash,
63+
linkedData: {
64+
constructorArgs,
65+
factory: 'FuelChainState',
66+
},
67+
});
68+
69+
return true;
70+
};
71+
72+
func.tags = [path.basename(__filename)];
73+
func.id = path.basename(__filename);
74+
export default func;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import path from 'path';
2+
import { password } from '@inquirer/prompts';
3+
import SafeApiKit from '@safe-global/api-kit';
4+
import SafeProtocolKit from '@safe-global/protocol-kit';
5+
import type { MetaTransactionData } from '@safe-global/safe-core-sdk-types';
6+
import type {
7+
HardhatRuntimeEnvironment,
8+
HttpNetworkConfig,
9+
} from 'hardhat/types';
10+
import type { DeployFunction } from 'hardhat-deploy/dist/types';
11+
12+
import { MAINNET_MULTISIG_ADDRESS } from '../../protocol/constants';
13+
import { FuelChainState__factory } from '../../typechain';
14+
15+
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
16+
const privateKey = await password({ message: 'Enter private key' });
17+
const senderAddress = new hre.ethers.Wallet(privateKey).address;
18+
const provider = (hre.config.networks['mainnet'] as HttpNetworkConfig).url;
19+
20+
const { address: chainStateAddress, implementation: newImplementation } =
21+
await hre.deployments.get('FuelChainState');
22+
23+
if (!newImplementation) {
24+
throw new Error('No implementations found in artifacts');
25+
}
26+
27+
const safeAddress = MAINNET_MULTISIG_ADDRESS;
28+
const apiKit = new SafeApiKit({ chainId: 1n });
29+
const protocolKit = await SafeProtocolKit.init({
30+
signer: privateKey,
31+
provider,
32+
safeAddress,
33+
});
34+
35+
const transactions: MetaTransactionData[] = [];
36+
37+
const { data: upgradeTransactionData } =
38+
await FuelChainState__factory.connect(
39+
chainStateAddress,
40+
hre.ethers.provider
41+
).upgradeTo.populateTransaction(newImplementation);
42+
transactions.push({
43+
to: chainStateAddress,
44+
data: upgradeTransactionData,
45+
value: '0',
46+
});
47+
48+
const safeTransaction = await protocolKit.createTransaction({
49+
transactions,
50+
});
51+
52+
const safeTxHash = await protocolKit.getTransactionHash(safeTransaction);
53+
54+
const signature = await protocolKit.signHash(safeTxHash);
55+
56+
await apiKit.proposeTransaction({
57+
safeAddress,
58+
safeTransactionData: safeTransaction.data,
59+
safeTxHash,
60+
senderAddress,
61+
senderSignature: signature.data,
62+
});
63+
64+
return true;
65+
};
66+
67+
func.tags = [path.basename(__filename)];
68+
func.id = path.basename(__filename);
69+
export default func;

packages/solidity-contracts/deployments/mainnet/.migrations.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,7 @@
1818
"rate_limit_proposal": 1727884066,
1919
"pausers_proposal": 1728386955,
2020
"20_upgrade_portal": 1730892055,
21-
"21_deposit_caps_removal": 1730892323
21+
"21_deposit_caps_removal": 1730892323,
22+
"022.chain_state_prepare_upgrade.ts": 1755603304,
23+
"023.chain_state_propose_upgrade.ts": 1755617982
2224
}

packages/solidity-contracts/deployments/mainnet/FuelChainState.json

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
"name": "FinalizationIsGtCooldown",
3838
"type": "error"
3939
},
40+
{
41+
"inputs": [],
42+
"name": "InvalidTimeToFinalize",
43+
"type": "error"
44+
},
4045
{
4146
"inputs": [],
4247
"name": "TimeToFinalizeTooLarge",
@@ -572,14 +577,15 @@
572577
"type": "function"
573578
}
574579
],
575-
"numDeployments": 1,
580+
"transactionHash": "0x4ad4b9ae7bcc6a88d10cf05309f42061f9fc26d497b093caf142fb51c6c3fbc1",
581+
"numDeployments": 2,
576582
"linkedData": {
577-
"factory": "FuelChainState",
578583
"constructorArgs": [
579-
604800,
584+
86400,
580585
10800,
581-
604800
582-
]
586+
86400
587+
],
588+
"factory": "FuelChainState"
583589
},
584-
"implementation": "0x725B2b1a15D818E1f25c68be77816802e6036559"
590+
"implementation": "0x621850dbB9160b54002B4a25b9fC9b2F26315f7e"
585591
}

0 commit comments

Comments
 (0)