Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore(proxy)/openzeppelin v5 migration #1562

Open
wants to merge 9 commits into
base: dev
Choose a base branch
from
4 changes: 2 additions & 2 deletions contracts/src/proxy/Initializable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ abstract contract Initializable {
bool _initializing;
}

// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1))
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant _INITIALIZABLE_STORAGE =
0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;
0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;

/**
* @dev The contract is already initialized.
Expand Down
4 changes: 2 additions & 2 deletions contracts/src/proxy/UUPSProxiable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ abstract contract UUPSProxiable {
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
* NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
* NOTE: keccak256(abi.encode(uint256(keccak256("eip1967.proxy.implementation")) - 1)) & ~bytes32(uint256(0xff))
*/
bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
bytes32 private constant IMPLEMENTATION_SLOT = 0x75b20eef8615de99c108b05f0dbda081c91897128caa336d75dffb97c4132b00;

/**
* @dev Storage variable of the proxiable contract address.
Expand Down
4 changes: 2 additions & 2 deletions contracts/src/proxy/UUPSProxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ contract UUPSProxy {
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
* NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
* NOTE: keccak256(abi.encode(uint256(keccak256("eip1967.proxy.implementation")) - 1)) & ~bytes32(uint256(0xff))
*/
bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
bytes32 private constant IMPLEMENTATION_SLOT = 0x75b20eef8615de99c108b05f0dbda081c91897128caa336d75dffb97c4132b00;

// ************************************* //
// * Constructor * //
Expand Down
54 changes: 43 additions & 11 deletions contracts/src/proxy/mock/UUPSUpgradeableMocks.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,76 @@ import "../UUPSProxiable.sol";
import "../Initializable.sol";

contract NonUpgradeableMock {
uint256 public _counter;
/// @custom:storage-location erc7201:kleros.storage.NonUpgradeableMockStorage
struct NonUpgradeableMockStorage {
uint256 counter;
}
// keccak256(abi.encode(uint256(keccak256("kleros.storage.NonUpgradeableMockStorage")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0x203890a1e96eaf39c35df205fbcedb580d4552ae7ac40780014dc281a7acd500;

function counter() external view returns (uint256) {
return _counter;
NonUpgradeableMockStorage storage $ = _getNonUpgradeableMockStorage();
return $.counter;
}

function increment() external {
_counter++;
NonUpgradeableMockStorage storage $ = _getNonUpgradeableMockStorage();
$.counter++;
}

function version() external pure virtual returns (string memory) {
return "NonUpgradeableMock 0.0.0";
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getNonUpgradeableMockStorage() private pure returns (NonUpgradeableMockStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}

contract UUPSUpgradeableMock is UUPSProxiable, NonUpgradeableMock {
bool public initialized;
address public governor;
/// @custom:storage-location erc7201:kleros.storage.UUPSUpgradeableMock
struct UUPSUpgradeableMockStorage {
bool initialized;
address governor;
}

uint256[50] __gap;
// keccak256(abi.encode(uint256(keccak256("kleros.storage.UUPSUpgradeableMock")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0x30d370aa3c43b12c906d59e729739fe781988b5aeb55fa9fb184b45129d6f900;

constructor() {
initialized = true;
UUPSUpgradeableMockStorage storage $ = _getInitializableStorage();
$.initialized = true;
}

function initialize(address _governor) external {
require(!initialized, "Contract instance has already been initialized");
governor = _governor;
initialized = true;
UUPSUpgradeableMockStorage storage $ = _getInitializableStorage();
require(!$.initialized, "Contract instance has already been initialized");
$.governor = _governor;
$.initialized = true;
}

function _authorizeUpgrade(address) internal view override {
require(governor == msg.sender, "No privilege to upgrade");
UUPSUpgradeableMockStorage storage $ = _getInitializableStorage();
require($.governor == msg.sender, "No privilege to upgrade");
}

function version() external pure virtual override returns (string memory) {
return "UUPSUpgradeableMock 1.0.0";
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (UUPSUpgradeableMockStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}

contract UUPSUpgradeableMockV2 is UUPSUpgradeableMock {
Expand Down
60 changes: 49 additions & 11 deletions contracts/src/proxy/mock/by-inheritance/UpgradedByInheritance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,86 @@ import "../../UUPSProxiable.sol";
import "../../Initializable.sol";

contract UpgradedByInheritanceV1 is UUPSProxiable, Initializable {
address public governor;
uint256 public counter;
uint256[50] __gap;
/// @custom:storage-location erc7201:kleros.storage.UpgradedByInheritance
struct UpgradedByInheritanceV1Storage {
address governor;
uint256 counter;
}

// keccak256(abi.encode(uint256(keccak256("kleros.storage.UpgradedByInheritance")) - 1)) & ~bytes32(uint256(0xff))
bytes32 internal constant INITIALIZABLE_STORAGE =
0xc17f29fd370bc39e93d9cb5467cf50e6788d12416f3c204ddea24c4b47412a00;

constructor() {
_disableInitializers();
}

function initialize(address _governor) external virtual reinitializer(1) {
governor = _governor;
counter = 1;
UpgradedByInheritanceV1Storage storage $ = _getInheritanceV1Storage();
$.governor = _governor;
$.counter = 1;
}

function _authorizeUpgrade(address) internal view override {
require(governor == msg.sender, "No privilege to upgrade");
UpgradedByInheritanceV1Storage storage $ = _getInheritanceV1Storage();
require($.governor == msg.sender, "No privilege to upgrade");
}

function increment() external {
++counter;
UpgradedByInheritanceV1Storage storage $ = _getInheritanceV1Storage();
++$.counter;
}

function version() external pure virtual returns (string memory) {
return "V1";
}
function _getInheritanceV1Storage() private pure returns (UpgradedByInheritanceV1Storage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
function governor() external view virtual returns (address) {
return _getInheritanceV1Storage().governor;
}
function counter() external view virtual returns (uint256) {
return _getInheritanceV1Storage().counter;
}
}

contract UpgradedByInheritanceV2 is UpgradedByInheritanceV1 {
string public newVariable;
uint256[50] __gap2;

/// @custom:storage-location erc7201:kleros.storage.UpgradedByInheritance
struct UpgradedByInheritanceV2Storage {
address governor;
uint256 counter;
string newVariable;
}
constructor() {
_disableInitializers();
}

function initializeV2(string memory _newVariable) external reinitializer(2) {
newVariable = _newVariable;
UpgradedByInheritanceV2Storage storage $ = _getInheritanceV2Storage();
$.newVariable = _newVariable;
this.increment();
}

function version() external pure virtual override returns (string memory) {
return "V2";
}
function _getInheritanceV2Storage() private pure returns (UpgradedByInheritanceV2Storage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
function governor() external view virtual override returns (address) {
return _getInheritanceV2Storage().governor;
}
function counter() external view virtual override returns (uint256) {
return _getInheritanceV2Storage().counter;
}
function newVariable() external view returns (string memory) {
return _getInheritanceV2Storage().newVariable;
}
}

contract UpgradedByInheritanceV3Bad is UpgradedByInheritanceV2 {
Expand Down
37 changes: 27 additions & 10 deletions contracts/src/proxy/mock/by-rewrite/UpgradedByRewrite.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,48 @@ import "../../UUPSProxiable.sol";
import "../../Initializable.sol";

contract UpgradedByRewrite is UUPSProxiable, Initializable {
//------------------------
// V1 State
//------------------------
address public governor;
uint256 public counter;
uint256[50] __gap;
/// @custom:storage-location erc7201:kleros.storage.UpgradedByRewriteStorage
struct UpgradedByRewriteStorage {
address governor;
uint256 counter;
}

// keccak256(abi.encode(uint256(keccak256("kleros.storage.UpgradedByRewriteStorage")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xbe8e07ee0d0f4fb183890b4b70057ae173e7270304bf720861e275e28be01e00;

constructor() {
_disableInitializers();
}

function initialize(address _governor) external virtual reinitializer(1) {
governor = _governor;
counter = 1;
UpgradedByRewriteStorage storage $ = _getUpgradedByRewriteStorage();
$.governor = _governor;
$.counter = 1;
}

function _authorizeUpgrade(address) internal view override {
require(governor == msg.sender, "No privilege to upgrade");
UpgradedByRewriteStorage storage $ = _getUpgradedByRewriteStorage();
require($.governor == msg.sender, "No privilege to upgrade");
}

function increment() external {
++counter;
UpgradedByRewriteStorage storage $ = _getUpgradedByRewriteStorage();
++$.counter;
}

function version() external pure virtual returns (string memory) {
return "V1";
}
function _getUpgradedByRewriteStorage() private pure returns (UpgradedByRewriteStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}

function governor() external view returns (address) {
return _getUpgradedByRewriteStorage().governor;
}
function counter() external view returns (uint256) {
return _getUpgradedByRewriteStorage().counter;
}
}
44 changes: 30 additions & 14 deletions contracts/src/proxy/mock/by-rewrite/UpgradedByRewriteV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,52 @@ import "../../UUPSProxiable.sol";
import "../../Initializable.sol";

contract UpgradedByRewrite is UUPSProxiable, Initializable {
//------------------------
// V1 State
//------------------------
address public governor;
uint256 public counter;
uint256[50] __gap;

//------------------------
// V2 State
//------------------------
string public newVariable;
/// @custom:storage-location erc7201:kleros.storage.UpgradedByRewriteStorage
struct UpgradedByRewriteV2 {
address governor;
uint256 counter;
string newVariable;
}

// keccak256(abi.encode(uint256(keccak256("kleros.storage.UpgradedByRewriteStorage")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xbe8e07ee0d0f4fb183890b4b70057ae173e7270304bf720861e275e28be01e00;

constructor() {
_disableInitializers();
}

function initialize(string memory _newVariable) external reinitializer(2) {
newVariable = _newVariable;
UpgradedByRewriteV2 storage $ = _getStorageUpgradedByRewrite();
$.newVariable = _newVariable;
this.increment();
}

function _authorizeUpgrade(address) internal view override {
require(governor == msg.sender, "No privilege to upgrade");
UpgradedByRewriteV2 storage $ = _getStorageUpgradedByRewrite();
require($.governor == msg.sender, "No privilege to upgrade");
}

function increment() external {
++counter;
UpgradedByRewriteV2 storage $ = _getStorageUpgradedByRewrite();
++$.counter;
}

function version() external pure virtual returns (string memory) {
return "V2";
}

function _getStorageUpgradedByRewrite() private pure returns (UpgradedByRewriteV2 storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
function governor() external view returns (address) {
return _getStorageUpgradedByRewrite().governor;
}
function counter() external view returns (uint256) {
return _getStorageUpgradedByRewrite().counter;
}
function newVariable() external view returns (string memory) {
return _getStorageUpgradedByRewrite().newVariable;
}
}
Loading