diff --git a/ethereum/gateway-eth-ts/src/service/testUtils.ts b/ethereum/gateway-eth-ts/src/service/testUtils.ts index d463043b5..e6edb2371 100644 --- a/ethereum/gateway-eth-ts/src/service/testUtils.ts +++ b/ethereum/gateway-eth-ts/src/service/testUtils.ts @@ -17,7 +17,7 @@ export const gatekeeperNetwork = 1n; // These addresses are the ones that hardhat deploys to in the local test environment // Note, they differ from the default create2 addresses used in production export const TEST_GATEWAY_TOKEN_ADDRESS = { - gatewayToken: "0x15a5e04e52CEA19E3b201AF6Bd60738FA0e84DBC", + gatewayToken: "0x76F54EB77CD5253478c4Aa600a39c8E5a8c73f61", forwarder: "0x8419F704CD6520E2C3EF477ef9BFA3159Ea1ACA7", flagsStorage: "0x74674d9fC457F48194Ce1D7dAaD1e7EDE3F2636E", }; diff --git a/ethereum/smart-contract/contracts/GatedERC2771.sol b/ethereum/smart-contract/contracts/GatedERC2771.sol index ae7693324..fd2d81d93 100644 --- a/ethereum/smart-contract/contracts/GatedERC2771.sol +++ b/ethereum/smart-contract/contracts/GatedERC2771.sol @@ -2,9 +2,9 @@ pragma solidity ^0.8.9; import {IGatewayTokenVerifier} from "./interfaces/IGatewayTokenVerifier.sol"; -import {MultiERC2771ContextNonUpgradeable} from "./MultiERC2771ContextNonUpgradeable.sol"; +import {MultiERC2771Context} from "./MultiERC2771Context.sol"; -abstract contract GatedERC2771 is MultiERC2771ContextNonUpgradeable { +abstract contract GatedERC2771 is MultiERC2771Context { address private _gatewayTokenContract; uint256 private _gatekeeperNetwork; @@ -19,10 +19,7 @@ abstract contract GatedERC2771 is MultiERC2771ContextNonUpgradeable { _; } - constructor( - address gatewayTokenContract, - uint256 gatekeeperNetwork - ) MultiERC2771ContextNonUpgradeable(new address[](0)) { + constructor(address gatewayTokenContract, uint256 gatekeeperNetwork) MultiERC2771Context(new address[](0)) { _gatewayTokenContract = gatewayTokenContract; _gatekeeperNetwork = gatekeeperNetwork; } diff --git a/ethereum/smart-contract/contracts/GatedERC2771Upgradeable.sol b/ethereum/smart-contract/contracts/GatedERC2771Upgradeable.sol index effe40d76..dc66c3a9c 100644 --- a/ethereum/smart-contract/contracts/GatedERC2771Upgradeable.sol +++ b/ethereum/smart-contract/contracts/GatedERC2771Upgradeable.sol @@ -2,9 +2,9 @@ pragma solidity ^0.8.9; import {IGatewayTokenVerifier} from "./interfaces/IGatewayTokenVerifier.sol"; -import {MultiERC2771Context} from "./MultiERC2771Context.sol"; +import {MultiERC2771ContextUpgradeable} from "./MultiERC2771ContextUpgradeable.sol"; -abstract contract GatedERC2771Upgradeable is MultiERC2771Context { +abstract contract GatedERC2771Upgradeable is MultiERC2771ContextUpgradeable { address private _gatewayTokenContract; uint256 private _gatekeeperNetwork; @@ -24,9 +24,9 @@ abstract contract GatedERC2771Upgradeable is MultiERC2771Context { address gatewayTokenContract, uint256 gatekeeperNetwork, address[] calldata trustedForwarders - ) internal initializer { + ) internal onlyInitializing { _gatewayTokenContract = gatewayTokenContract; _gatekeeperNetwork = gatekeeperNetwork; - __MultiERC2771Context_init(trustedForwarders); + __MultiERC2771ContextUpgradeable_init(trustedForwarders); } } diff --git a/ethereum/smart-contract/contracts/GatewayToken.sol b/ethereum/smart-contract/contracts/GatewayToken.sol index c33f135f2..8c1dabf41 100644 --- a/ethereum/smart-contract/contracts/GatewayToken.sol +++ b/ethereum/smart-contract/contracts/GatewayToken.sol @@ -15,7 +15,7 @@ import {IGatewayToken} from "./interfaces/IGatewayToken.sol"; import {IERC721Freezable} from "./interfaces/IERC721Freezable.sol"; import {IERC721Expirable} from "./interfaces/IERC721Expirable.sol"; import {IERC721Revokable} from "./interfaces/IERC721Revokable.sol"; -import {MultiERC2771Context} from "./MultiERC2771Context.sol"; +import {MultiERC2771ContextUpgradeable} from "./MultiERC2771ContextUpgradeable.sol"; import {Charge} from "./library/Charge.sol"; import {ParameterizedAccessControl} from "./ParameterizedAccessControl.sol"; import {Common__MissingAccount, Common__NotContract, Common__Unauthorized} from "./library/CommonErrors.sol"; @@ -35,7 +35,7 @@ import {BitMask} from "./library/BitMask.sol"; */ contract GatewayToken is UUPSUpgradeable, - MultiERC2771Context, + MultiERC2771ContextUpgradeable, ERC3525Upgradeable, ParameterizedAccessControl, IERC721Freezable, @@ -109,7 +109,7 @@ contract GatewayToken is } __ERC3525_init(_name, _symbol, 0); - __MultiERC2771Context_init(_trustedForwarders); + __MultiERC2771ContextUpgradeable_init(_trustedForwarders); _setFlagsStorage(_flagsStorage); _superAdmins[_superAdmin] = true; @@ -527,20 +527,20 @@ contract GatewayToken is internal view virtual - override(MultiERC2771Context, ContextUpgradeable) + override(MultiERC2771ContextUpgradeable, ContextUpgradeable) returns (address sender) { - return MultiERC2771Context._msgSender(); + return MultiERC2771ContextUpgradeable._msgSender(); } function _msgData() internal view virtual - override(MultiERC2771Context, ContextUpgradeable) + override(MultiERC2771ContextUpgradeable, ContextUpgradeable) returns (bytes calldata) { - return MultiERC2771Context._msgData(); + return MultiERC2771ContextUpgradeable._msgData(); } function _getTokenIdsByOwnerAndNetwork( diff --git a/ethereum/smart-contract/contracts/MultiERC2771Context.sol b/ethereum/smart-contract/contracts/MultiERC2771Context.sol index 284d38875..a54d83a3e 100644 --- a/ethereum/smart-contract/contracts/MultiERC2771Context.sol +++ b/ethereum/smart-contract/contracts/MultiERC2771Context.sol @@ -1,35 +1,25 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.9; -import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; +import {Context} from "@openzeppelin/contracts/utils/Context.sol"; /** * @dev Context variant with ERC2771 support for multiple trusted forwarders. */ -abstract contract MultiERC2771Context is ContextUpgradeable { +abstract contract MultiERC2771Context is Context { mapping(address => bool) private _trustedForwarders; - function isTrustedForwarder(address forwarder) public view virtual returns (bool) { - return _trustedForwarders[forwarder]; - } - - // because MultiERC2771Context is abstract we don't implement a - // constructor. It's the responsibility of the derived contract to - // disable the Initializers with "_disableInitializers()" - - // solhint-disable-next-line func-name-mixedcase - function __MultiERC2771Context_init(address[] calldata trustedForwarders) internal initializer { - __Context_init_unchained(); - __MultiERC2771Context_init_unchained(trustedForwarders); - } - - // solhint-disable-next-line func-name-mixedcase - function __MultiERC2771Context_init_unchained(address[] calldata trustedForwarders) internal initializer { + /// @custom:oz-upgrades-unsafe-allow constructor + constructor(address[] memory trustedForwarders) { for (uint i = 0; i < trustedForwarders.length; i++) { _trustedForwarders[trustedForwarders[i]] = true; } } + function isTrustedForwarder(address forwarder) public view virtual returns (bool) { + return _trustedForwarders[forwarder]; + } + // The overridden function should declare the appropriate access control// // keep init functions at the top by the constructor function _addForwarder(address forwarder) internal virtual { diff --git a/ethereum/smart-contract/contracts/MultiERC2771ContextNonUpgradeable.sol b/ethereum/smart-contract/contracts/MultiERC2771ContextUpgradeable.sol similarity index 65% rename from ethereum/smart-contract/contracts/MultiERC2771ContextNonUpgradeable.sol rename to ethereum/smart-contract/contracts/MultiERC2771ContextUpgradeable.sol index d47f94fc6..d4e948438 100644 --- a/ethereum/smart-contract/contracts/MultiERC2771ContextNonUpgradeable.sol +++ b/ethereum/smart-contract/contracts/MultiERC2771ContextUpgradeable.sol @@ -1,25 +1,37 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.9; -import {Context} from "@openzeppelin/contracts/utils/Context.sol"; +import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; /** * @dev Context variant with ERC2771 support for multiple trusted forwarders. */ -abstract contract MultiERC2771ContextNonUpgradeable is Context { +abstract contract MultiERC2771ContextUpgradeable is ContextUpgradeable { mapping(address => bool) private _trustedForwarders; - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address[] memory trustedForwarders) { + function isTrustedForwarder(address forwarder) public view virtual returns (bool) { + return _trustedForwarders[forwarder]; + } + + // because MultiERC2771ContextUpgradeable is abstract we don't implement a + // constructor. It's the responsibility of the derived contract to + // disable the Initializers with "_disableInitializers()" + + // solhint-disable-next-line func-name-mixedcase + function __MultiERC2771ContextUpgradeable_init(address[] calldata trustedForwarders) internal onlyInitializing { + __Context_init_unchained(); + __MultiERC2771ContextUpgradeable_init_unchained(trustedForwarders); + } + + // solhint-disable-next-line func-name-mixedcase + function __MultiERC2771ContextUpgradeable_init_unchained( + address[] calldata trustedForwarders + ) internal onlyInitializing { for (uint i = 0; i < trustedForwarders.length; i++) { _trustedForwarders[trustedForwarders[i]] = true; } } - function isTrustedForwarder(address forwarder) public view virtual returns (bool) { - return _trustedForwarders[forwarder]; - } - // The overridden function should declare the appropriate access control// // keep init functions at the top by the constructor function _addForwarder(address forwarder) internal virtual { diff --git a/ethereum/smart-contract/package.json b/ethereum/smart-contract/package.json index 7921c4f1a..54760d474 100644 --- a/ethereum/smart-contract/package.json +++ b/ethereum/smart-contract/package.json @@ -7,7 +7,7 @@ }, "scripts": { "analyze": "slither . --config-file slither.config.json", - "coverage": "NODE_ENV=test hardhat coverage && istanbul check-coverage --statements 60 --branches 38 --functions 62 --lines 60", + "coverage": "NODE_ENV=test hardhat coverage && istanbul check-coverage --statements 97 --branches 90 --functions 95 --lines 93", "test": "NODE_ENV=test hardhat test", "deploy": "hardhat deploy --tags GatewayToken --network $1", "upgrade-contract": "hardhat deploy --tags UpgradeV1 --network $1", diff --git a/ethereum/smart-contract/test/contracts/GatewayTokenUpgradeTest.sol b/ethereum/smart-contract/test/contracts/GatewayTokenUpgradeTest.sol index 167d20a8c..eb328db3d 100644 --- a/ethereum/smart-contract/test/contracts/GatewayTokenUpgradeTest.sol +++ b/ethereum/smart-contract/test/contracts/GatewayTokenUpgradeTest.sol @@ -1,28 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.9; -import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; -import {Address} from "@openzeppelin/contracts/utils/Address.sol"; -import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; -import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import {IERC3525MetadataUpgradeable} from "@solvprotocol/erc-3525/extensions/IERC3525MetadataUpgradeable.sol"; import {ERC3525Upgradeable} from "@solvprotocol/erc-3525/ERC3525Upgradeable.sol"; -import {IERC721} from "@solvprotocol/erc-3525/IERC721.sol"; -import {IERC3525} from "@solvprotocol/erc-3525/IERC3525.sol"; -import {TokenBitMask} from "../../contracts/TokenBitMask.sol"; -import {IGatewayToken} from "../../contracts/interfaces/IGatewayToken.sol"; -import {IERC721Freezable} from "../../contracts/interfaces/IERC721Freezable.sol"; -import {IERC721Expirable} from "../../contracts/interfaces/IERC721Expirable.sol"; -import {IERC721Revokable} from "../../contracts/interfaces/IERC721Revokable.sol"; -import {MultiERC2771Context} from "../../contracts/MultiERC2771Context.sol"; import {Charge} from "../../contracts/library/Charge.sol"; -import {ParameterizedAccessControl} from "../../contracts/ParameterizedAccessControl.sol"; -import { - Common__MissingAccount, - Common__NotContract, - Common__Unauthorized -} from "../../contracts/library/CommonErrors.sol"; import {GatewayToken} from "../../contracts/GatewayToken.sol"; /** diff --git a/ethereum/smart-contract/test/contracts/v0/GatewayTokenV0.sol b/ethereum/smart-contract/test/contracts/v0/GatewayTokenV0.sol index d25ba02fe..0d3a7fdd6 100644 --- a/ethereum/smart-contract/test/contracts/v0/GatewayTokenV0.sol +++ b/ethereum/smart-contract/test/contracts/v0/GatewayTokenV0.sol @@ -14,7 +14,7 @@ import {TokenBitMask} from "../../../contracts/TokenBitMask.sol"; import {IERC721Freezable} from "../../../contracts/interfaces/IERC721Freezable.sol"; import {IERC721ExpirableV0} from "./IERC721ExpirableV0.sol"; import {IERC721Revokable} from "../../../contracts/interfaces/IERC721Revokable.sol"; -import {MultiERC2771Context} from "../../../contracts/MultiERC2771Context.sol"; +import {MultiERC2771ContextUpgradeable} from "../../../contracts/MultiERC2771ContextUpgradeable.sol"; import {Charge} from "./ChargeV0.sol"; import {ParameterizedAccessControl} from "../../../contracts/ParameterizedAccessControl.sol"; import { @@ -37,7 +37,7 @@ import {IGatewayTokenV0} from "./IGatewayTokenV0.sol"; */ contract GatewayTokenV0 is UUPSUpgradeable, - MultiERC2771Context, + MultiERC2771ContextUpgradeable, ERC3525Upgradeable, ParameterizedAccessControl, IERC721Freezable, @@ -97,7 +97,7 @@ contract GatewayTokenV0 is } __ERC3525_init(_name, _symbol, 0); - __MultiERC2771Context_init(_trustedForwarders); + __MultiERC2771ContextUpgradeable_init(_trustedForwarders); _setFlagsStorage(_flagsStorage); _superAdmins[_superAdmin] = true; @@ -482,20 +482,20 @@ contract GatewayTokenV0 is internal view virtual - override(MultiERC2771Context, ContextUpgradeable) + override(MultiERC2771ContextUpgradeable, ContextUpgradeable) returns (address sender) { - return MultiERC2771Context._msgSender(); + return MultiERC2771ContextUpgradeable._msgSender(); } function _msgData() internal view virtual - override(MultiERC2771Context, ContextUpgradeable) + override(MultiERC2771ContextUpgradeable, ContextUpgradeable) returns (bytes calldata) { - return MultiERC2771Context._msgData(); + return MultiERC2771ContextUpgradeable._msgData(); } function _getTokenIdsByOwnerAndNetwork(address owner, uint network) internal view returns (uint[] memory, uint) {