diff --git a/package.json b/package.json index be3070f1..34f0a775 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "scripts": { "test": "npx hardhat test --parallel", "prettier": "prettier --write test/**/*.js && prettier --write test/*/*/*.js && prettier --write deploy/*.js && prettier --write tasks/*.js && prettier --write contracts/**/*.sol && prettier --write contracts/**/**/*.sol && prettier --write contracts/**/**/**/*.sol", - "lint": "yarn prettier && solhint 'contracts/*.sol' && solhint 'contracts/**/*.sol' && solhint 'contracts/**/**/*.sol' && solhint 'contracts/**/**/**/*.sol'" + "lint": "yarn prettier && solhint 'contracts/*.sol' && solhint 'contracts/**/*.sol' && solhint 'contracts/**/**/*.sol' && solhint 'contracts/**/**/**/*.sol'", + "postinstall": "node upgrade/adjustGaps.js" }, "engines": { "node": "==18" diff --git a/upgrade/OFTWithFeePermitUpgradeable.json b/upgrade/OFTWithFeePermitUpgradeable.json index 50874c79..9ee33ee3 100644 --- a/upgrade/OFTWithFeePermitUpgradeable.json +++ b/upgrade/OFTWithFeePermitUpgradeable.json @@ -230,14 +230,14 @@ "label": "__gap", "offset": 0, "slot": "399", - "type": "t_array(t_uint256)45_storage" + "type": "t_array(t_uint256)7_storage" }, { "astId": 5687, "contract": "contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable", "label": "_hashedName", "offset": 0, - "slot": "444", + "slot": "406", "type": "t_bytes32" }, { @@ -245,7 +245,7 @@ "contract": "contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable", "label": "_hashedVersion", "offset": 0, - "slot": "445", + "slot": "407", "type": "t_bytes32" }, { @@ -253,7 +253,7 @@ "contract": "contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable", "label": "_name", "offset": 0, - "slot": "446", + "slot": "408", "type": "t_string_storage" }, { @@ -261,7 +261,7 @@ "contract": "contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable", "label": "_version", "offset": 0, - "slot": "447", + "slot": "409", "type": "t_string_storage" }, { @@ -269,15 +269,15 @@ "contract": "contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable", "label": "__gap", "offset": 0, - "slot": "448", - "type": "t_array(t_uint256)48_storage" + "slot": "410", + "type": "t_array(t_uint256)7_storage" }, { "astId": 4402, "contract": "contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable", "label": "_nonces", "offset": 0, - "slot": "496", + "slot": "417", "type": "t_mapping(t_address,t_struct(Counter)5006_storage)" }, { @@ -285,7 +285,7 @@ "contract": "contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable", "label": "_PERMIT_TYPEHASH_DEPRECATED_SLOT", "offset": 0, - "slot": "497", + "slot": "418", "type": "t_bytes32" }, { @@ -293,15 +293,15 @@ "contract": "contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable", "label": "__gap", "offset": 0, - "slot": "498", - "type": "t_array(t_uint256)49_storage" + "slot": "419", + "type": "t_array(t_uint256)25_storage" }, { "astId": 2618, "contract": "contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable", "label": "ld2sdRate", "offset": 0, - "slot": "547", + "slot": "444", "type": "t_uint256" } ], @@ -311,6 +311,12 @@ "label": "address", "numberOfBytes": "20" }, + "t_array(t_uint256)25_storage": { + "encoding": "inplace", + "label": "uint256[25]", + "numberOfBytes": "800", + "base": "t_uint256" + }, "t_array(t_uint256)44_storage": { "encoding": "inplace", "label": "uint256[44]", @@ -323,12 +329,6 @@ "numberOfBytes": "1440", "base": "t_uint256" }, - "t_array(t_uint256)48_storage": { - "encoding": "inplace", - "label": "uint256[48]", - "numberOfBytes": "1536", - "base": "t_uint256" - }, "t_array(t_uint256)49_storage": { "encoding": "inplace", "label": "uint256[49]", @@ -341,6 +341,12 @@ "numberOfBytes": "1600", "base": "t_uint256" }, + "t_array(t_uint256)7_storage": { + "encoding": "inplace", + "label": "uint256[7]", + "numberOfBytes": "224", + "base": "t_uint256" + }, "t_bool": { "encoding": "inplace", "label": "bool", diff --git a/upgrade/OFTWithFeePermitUpgradeable.txt b/upgrade/OFTWithFeePermitUpgradeable.txt index 342ce72b..dc0b1c8d 100644 --- a/upgrade/OFTWithFeePermitUpgradeable.txt +++ b/upgrade/OFTWithFeePermitUpgradeable.txt @@ -28,13 +28,13 @@ | _totalSupply | uint256 | 396 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | | _name | string | 397 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | | _symbol | string | 398 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | -| __gap | uint256[45] | 399 | 0 | 1440 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | -| _hashedName | bytes32 | 444 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | -| _hashedVersion | bytes32 | 445 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | -| _name | string | 446 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | -| _version | string | 447 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | -| __gap | uint256[48] | 448 | 0 | 1536 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | -| _nonces | mapping(address => struct CountersUpgradeable.Counter) | 496 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | -| _PERMIT_TYPEHASH_DEPRECATED_SLOT | bytes32 | 497 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | -| __gap | uint256[49] | 498 | 0 | 1568 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | -| ld2sdRate | uint256 | 547 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | +| __gap | uint256[7] | 399 | 0 | 224 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | +| _hashedName | bytes32 | 406 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | +| _hashedVersion | bytes32 | 407 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | +| _name | string | 408 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | +| _version | string | 409 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | +| __gap | uint256[7] | 410 | 0 | 224 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | +| _nonces | mapping(address => struct CountersUpgradeable.Counter) | 417 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | +| _PERMIT_TYPEHASH_DEPRECATED_SLOT | bytes32 | 418 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | +| __gap | uint256[25] | 419 | 0 | 800 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | +| ld2sdRate | uint256 | 444 | 0 | 32 | contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable | diff --git a/upgrade/UPGRADE.md b/upgrade/UPGRADE.md index 9dae9e50..8bf44372 100644 --- a/upgrade/UPGRADE.md +++ b/upgrade/UPGRADE.md @@ -16,4 +16,22 @@ To output the same information add the ```--pretty``` flag. ## New contract layout -By using the same forge commands we can generate the storage layout files to compare the new implementaion layout with the current one. \ No newline at end of file +By using the same forge commands we can generate the storage layout files to compare the new implementaion layout with the current one. + +## Comparison + +The new contract adds two ```gap``` arrays and six other variables, shifting the storage slot of ```ld2sdRate``` from 444 to 547. The rest of the slots are not shifted. + +To make ```ld2sdRate``` slot match again, we reduce the gap size of three different OpenZeppelin contracts. This is done by running ```upgrade/adjustGaps.js``` after installing ```node_modules```, searching the gap definition line + +```solidity + uint256[49] private __gap; +``` + +and replacing it with + +```solidity + uint256[25] private __gap; +``` + +The storage layout files now are updated with the new layout, where variable ```ld2sdRate``` is in slot 444 again. \ No newline at end of file diff --git a/upgrade/adjustGaps.js b/upgrade/adjustGaps.js new file mode 100644 index 00000000..7fd1fad6 --- /dev/null +++ b/upgrade/adjustGaps.js @@ -0,0 +1,63 @@ +const fs = require('fs'); +const path = require('path'); + +const settings = { + ERC20Upgradeable: { + fileName: '@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol', + path: '../node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol', + searchValue: /uint256\[45\] private __gap;/g, + replaceValue: 'uint256[7] private __gap;', + }, + ERC20PermitUpgradeable: { + fileName: '@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol', + path: '../node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol', + searchValue: /uint256\[49\] private __gap;/g, + replaceValue: 'uint256[25] private __gap;', + }, + EIP712Upgradeable: { + fileName: '@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol', + path: '../node_modules/@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol', + searchValue: /uint256\[48\] private __gap;/g, + replaceValue: 'uint256[7] private __gap;', + } +} + +/** + * Modifies a file by replacing a specified string with another. + * @param {string} fileName - Name of the file to be consoled. + * @param {string} filePath - The path to the target file. + * @param {RegExp} searchValue - The string or RegExp to search for. + * @param {string} replaceValue - The string to replace the searchValue with. + */ +function modifyFile(fileName, filePath, searchValue, replaceValue) { + fs.readFile(filePath, 'utf8', (err, data) => { + if (err) { + console.error(`Error reading file: ${fileName}`, err); + return; + } + + const result = data.replace(searchValue, replaceValue); + + fs.writeFile(filePath, result, 'utf8', (err) => { + if (err) { + console.error(`Error writing file: ${fileName}`, err); + return; + } + console.log(`File successfully modified: ${fileName}`); + }); + }); +} + +// Adjust the gaps in OpenZeppelin contracts +console.log('yarn postinstall'); +for (const key in settings) { + if (settings.hasOwnProperty(key)) { + const setting = settings[key]; + modifyFile( + setting.fileName, + path.join(__dirname, setting.path), + setting.searchValue, + setting.replaceValue + ); + } +}