Skip to content

Commit

Permalink
feat: add gap adjustment script and proposed storage layout
Browse files Browse the repository at this point in the history
  • Loading branch information
federava committed Feb 23, 2024
1 parent 0e7b47f commit f705e46
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 30 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
42 changes: 24 additions & 18 deletions upgrade/OFTWithFeePermitUpgradeable.json
Original file line number Diff line number Diff line change
Expand Up @@ -230,78 +230,78 @@
"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"
},
{
"astId": 5690,
"contract": "contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable",
"label": "_hashedVersion",
"offset": 0,
"slot": "445",
"slot": "407",
"type": "t_bytes32"
},
{
"astId": 5692,
"contract": "contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable",
"label": "_name",
"offset": 0,
"slot": "446",
"slot": "408",
"type": "t_string_storage"
},
{
"astId": 5694,
"contract": "contracts/contracts-upgradable/token/oft/v2/fee/OFTWithFeePermitUpgradeable.sol:OFTWithFeePermitUpgradeable",
"label": "_version",
"offset": 0,
"slot": "447",
"slot": "409",
"type": "t_string_storage"
},
{
"astId": 5952,
"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)"
},
{
"astId": 4410,
"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"
},
{
"astId": 4566,
"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"
}
],
Expand All @@ -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]",
Expand All @@ -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]",
Expand All @@ -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",
Expand Down
20 changes: 10 additions & 10 deletions upgrade/OFTWithFeePermitUpgradeable.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
20 changes: 19 additions & 1 deletion upgrade/UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
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.
63 changes: 63 additions & 0 deletions upgrade/adjustGaps.js
Original file line number Diff line number Diff line change
@@ -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
);
}
}

0 comments on commit f705e46

Please sign in to comment.