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

[gms-1363] Add OALUpgradeable to be used behind proxy #163

Merged
merged 2 commits into from
Jan 17, 2024
Merged

Conversation

jasonzwli
Copy link
Contributor

@jasonzwli jasonzwli commented Jan 17, 2024

Adding OperaterAllowlistUpgradeable. The reasoning for not just overwriting the original OAL code is because the repo is fairly out of date with its packages, i.e overwriting the existing contract requires ethers ^6.6.0, which will break 95% of our hardhat tests. This is time consuming to fix, so I made the decision to write a new contract and test the essential proxy functions in forge. I've also replaced the OAL in the ERC1155 test with the new OALUpgradeable to test its interactions with collections. The regular Allowlist contract will be removed from the repo once we fix the tests that are written in hardhat

@jasonzwli jasonzwli requested a review from a team as a code owner January 17, 2024 02:57
@jasonzwli jasonzwli force-pushed the jason/proxy branch 2 times, most recently from 89df76c to 6da134f Compare January 17, 2024 03:01
Copy link

openzeppelin-code bot commented Jan 17, 2024

[gms-1363] Add OALUpgradeable to be used behind proxy

Generated at commit: 9bfb7001f2d454e503688005cf95fd8c372f4b1b

🚨 Report Summary

Severity Level Results
Contracts Critical
High
Medium
Low
Note
Total
2
0
0
8
30
40
Dependencies Critical
High
Medium
Low
Note
Total
0
0
0
1
54
55

For more details view the full report in OpenZeppelin Code Inspector


import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix linter issue by importing {AccessControlUpgradeable} from

// SPDX-License-Identifier: Apache 2.0
pragma solidity 0.8.19;

import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix linter issue by importing specific contract

// Interface to retrieve the implemention stored inside the Proxy contract
interface IProxy {
// Returns the current implementation address used by the proxy contract
function PROXY_getImplementation() external view returns (address);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove linter issue by adding:
// solhint-disable-next-line var-name-mixedcase

@@ -0,0 +1,197 @@
// Copyright Immutable Pty Ltd 2018 - 2023
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This contract should be with the test code. That is in /test/allowlist

/// @notice Mapping of Allowlisted bytecodes
mapping(bytes32 => bool) private bytecodeAllowlist;

/// @notice storage gap for additional variables for upgrades
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storage gap should be at the end of the file.
Storage gap variable's name should be __OperatorAllowlistUpgradeableGap
Naming the gap variable makes it easier to read storage maps.


/// ===== Events =====

/// @notice Emitted when a target address is added or removed from the Allowlist
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Events should be before storage variables.

OperatorAllowlist is an implementation of a Allowlist registry, storing addresses and bytecode
which are allowed to be approved operators and execute transfers of interfacing token contracts (e.g. ERC721/ERC1155).
The registry will be a deployed contract that tokens may interface with and point to.
OperatorAllowlist is not designed to be upgradeable or extended.
Copy link
Contributor

@allan-almeida-imtbl allan-almeida-imtbl Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can probably remove OperatorAllowlist is not designed to be upgradeable or extended.

import {IOperatorAllowlist} from "./IOperatorAllowlist.sol";

// Interface to retrieve the implemention stored inside the Proxy contract
interface IProxy {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a separate file. Doing this will allow the same interface file to be used by all usages, rather than the code being copy and pasted.

The file name should be IWalletProxy. The description should be:

Interface for Passport Wallet's proxy contract.

__AccessControl_init();
_grantRole(DEFAULT_ADMIN_ROLE, _roleAdmin);
_grantRole(UPGRADE_ROLE, _upgradeAdmin);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also initialize the REGISTRAR role here.

/// ===== External functions =====

/**
* @notice Add a target address to Allowlist
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update notice to reflect that a set of addresses is being passed in.

* @notice Add a target address to Allowlist
* @param addressTargets the addresses to be added to the allowlist
*/
function addAddressToAllowlist(address[] calldata addressTargets) external onlyRole(REGISTRAR_ROLE) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function name should be addAddressToAllowLists. That is with an s at the end to imply multiple addresses.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would addAddressesToAllowList be clearer, as an alternative

}

/**
* @notice Remove a target address from Allowlist
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above

* @notice Remove a target address from Allowlist
* @param addressTargets the addresses to be removed from the allowlist
*/
function removeAddressFromAllowlist(address[] calldata addressTargets) external onlyRole(REGISTRAR_ROLE) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above

* @notice Allows admin to grant `user` `REGISTRAR_ROLE` role
* @param user the address that `REGISTRAR_ROLE` will be granted to
*/
function grantRegistrarRole(address user) external onlyRole(DEFAULT_ADMIN_ROLE) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is not needed. It is available in the AccessControl Open Zeppelin contract.

* @notice Allows admin to revoke `REGISTRAR_ROLE` role from `user`
* @param user the address that `REGISTRAR_ROLE` will be revoked from
*/
function revokeRegistrarRole(address user) external onlyRole(DEFAULT_ADMIN_ROLE) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function is not needed. The same functionality is available in AccessControl

@@ -0,0 +1,197 @@
// Copyright Immutable Pty Ltd 2018 - 2023
// SPDX-License-Identifier: Apache 2.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this contract could just extend the OperatorAllowlist contract, just adding the extra storage location and function(s)

@@ -0,0 +1,67 @@
pragma solidity 0.8.19;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add copyright and license

@@ -0,0 +1,25 @@
// SPDX-License-Identifier: Apache 2.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this contract is only needed by allow list tests, put it in test/allowlist

Copy link
Contributor Author

@jasonzwli jasonzwli Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also used by the erc1155 test

import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {OperatorAllowlistUpgradeable} from "../../contracts/allowlist/OperatorAllowlistUpgradeable.sol";

contract DeployOperatorAllowlist {
Copy link
Contributor

@drinkcoffee drinkcoffee Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment to the class so it is obvious what this class is for.

@@ -0,0 +1,189 @@
// Copyright Immutable Pty Ltd 2018 - 2023
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This contract has a lot in common with OperatorAllowlist. The two contracts should inherit from a common OperatorAllowlistBase that contains the common code and is written to be used by both of them.

Copy link
Contributor Author

@jasonzwli jasonzwli Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will delete the regular OperatorAllowlist contract once the repo's dependencies are fixed

uint256 registerarPrivateKey = 3;
uint256 feeReceiverKey = 4;

address admin = vm.addr(adminPrivateKey);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove and use:
address public roleAdmin = makeAddr("roleAdmin");

@@ -5,15 +5,16 @@ import "forge-std/Test.sol";
import {ImmutableERC1155} from "../../../contracts/token/erc1155/preset/draft-ImmutableERC1155.sol";
import {IImmutableERC1155Errors} from "../../../contracts/errors/Errors.sol";
import {OperatorAllowlistEnforcementErrors} from "../../../contracts/errors/Errors.sol";
import {OperatorAllowlist} from "../../../contracts/allowlist/OperatorAllowlist.sol";
import {OperatorAllowlistUpgradeable} from "../../../contracts/allowlist/OperatorAllowlistUpgradeable.sol";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implies that we are no longer testing OperatorAllowlist, and only testing the Upgradeable version. ???

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the plan is to no longer use and test OperatorAllowlist but it is a huge effort to rewrite all the tests for it in forge since ethers ^6.6.0(which we need to help test proxy deploys) will break a lot of the hardhat tests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The basic functionalities that are common between OperatorAllowlist and OperatorAllowlistUpgradeable are tested by existing hardhat tests

assertEq(address(immutableERC721.operatorAllowlist()), proxyAddr);
}

function testUpgradeToV2() public {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a test where the authorisation fails due to the account not being authorised.

The registry will be a deployed contract that tokens may interface with and point to.
*/

contract OperatorAllowlistUpgradeable is ERC165, AccessControlUpgradeable, UUPSUpgradeable, IOperatorAllowlist {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We must used AccessControlEnumerableUpgradeable
Being able to enumerate who the admins are is very important.

@jasonzwli jasonzwli force-pushed the jason/proxy branch 2 times, most recently from 951c8e0 to 948f228 Compare January 17, 2024 05:31
@jasonzwli jasonzwli enabled auto-merge (squash) January 17, 2024 23:25
@jasonzwli jasonzwli merged commit 929cbbb into main Jan 17, 2024
4 checks passed
@drinkcoffee drinkcoffee deleted the jason/proxy branch April 1, 2024 22:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants