diff --git a/implementations/contracts/ERC725.sol b/implementations/contracts/ERC725.sol index 9cfe4a7a..7e1ed219 100644 --- a/implementations/contracts/ERC725.sol +++ b/implementations/contracts/ERC725.sol @@ -2,15 +2,8 @@ pragma solidity ^0.8.5; // modules -import {OwnableUnset} from "./custom/OwnableUnset.sol"; -import {ERC725XCore} from "./ERC725XCore.sol"; -import {ERC725YCore} from "./ERC725YCore.sol"; - -// constants -import {_INTERFACEID_ERC725X, _INTERFACEID_ERC725Y} from "./constants.sol"; - -// errors -import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol"; +import {ERC725X} from "./ERC725X.sol"; +import {ERC725Y} from "./ERC725Y.sol"; /** * @title ERC725 bundle. @@ -19,7 +12,7 @@ import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol"; * * @custom:warning This implementation does not have by default a `receive()` or `fallback()` function. */ -contract ERC725 is ERC725XCore, ERC725YCore { +contract ERC725 is ERC725X, ERC725Y { /** * @notice Deploying an ERC725 smart contract and setting address `initialOwner` as the contract owner. * @dev Deploy a new ERC725 contract with the provided `initialOwner` as the contract {owner}. @@ -28,22 +21,16 @@ contract ERC725 is ERC725XCore, ERC725YCore { * @custom:requirements * - `initialOwner` CANNOT be the zero address. */ - constructor(address initialOwner) payable { - if (initialOwner == address(0)) { - revert OwnableCannotSetZeroAddressAsOwner(); - } - OwnableUnset._setOwner(initialOwner); - } + constructor( + address initialOwner + ) payable ERC725X(initialOwner) ERC725Y(initialOwner) {} /** - * @inheritdoc ERC725XCore + * @inheritdoc ERC725X */ function supportsInterface( bytes4 interfaceId - ) public view virtual override(ERC725XCore, ERC725YCore) returns (bool) { - return - interfaceId == _INTERFACEID_ERC725X || - interfaceId == _INTERFACEID_ERC725Y || - super.supportsInterface(interfaceId); + ) public view virtual override(ERC725X, ERC725Y) returns (bool) { + return super.supportsInterface(interfaceId); } } diff --git a/implementations/contracts/ERC725InitAbstract.sol b/implementations/contracts/ERC725InitAbstract.sol index 114309b6..788d3dda 100644 --- a/implementations/contracts/ERC725InitAbstract.sol +++ b/implementations/contracts/ERC725InitAbstract.sol @@ -2,15 +2,8 @@ pragma solidity ^0.8.5; // modules -import { - Initializable -} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import {OwnableUnset} from "./custom/OwnableUnset.sol"; -import {ERC725XCore} from "./ERC725XCore.sol"; -import {ERC725YCore} from "./ERC725YCore.sol"; - -// constants -import {_INTERFACEID_ERC725X, _INTERFACEID_ERC725Y} from "./constants.sol"; +import {ERC725XInitAbstract} from "./ERC725XInitAbstract.sol"; +import {ERC725YInitAbstract} from "./ERC725YInitAbstract.sol"; // errors import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol"; @@ -23,35 +16,48 @@ import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol"; * @custom:warning This implementation does not have by default a `receive()` or `fallback()` function. */ abstract contract ERC725InitAbstract is - Initializable, - ERC725XCore, - ERC725YCore + ERC725XInitAbstract, + ERC725YInitAbstract { /** * @dev Internal function to initialize the contract with the provided `initialOwner` as the contract {owner}. * @param initialOwner the owner of the contract. * + * NOTE: we can safely override this function and not call the parent `_initialize(...)` functions from `ERC725XInitAbstract` and `ERC725YInitAbstract` + * as the code logic from this `_initialize(...)` is the exactly the same. + * + * @custom:warning If a child contract that inherits `ERC725InitAbstract` needs to override the logic of the `_initialize` function, make sure it calls + * also this function inside this logic via `super._initialize(initialOwner)` or `ERC725InitAbstract._initialize(initialOwner)`. + * * @custom:requirements * - `initialOwner` CANNOT be the zero address. */ function _initialize( address initialOwner - ) internal virtual onlyInitializing { + ) + internal + virtual + override(ERC725XInitAbstract, ERC725YInitAbstract) + onlyInitializing + { if (initialOwner == address(0)) { revert OwnableCannotSetZeroAddressAsOwner(); } - OwnableUnset._setOwner(initialOwner); + _transferOwnership(initialOwner); } /** - * @inheritdoc ERC725XCore + * @inheritdoc ERC725XInitAbstract */ function supportsInterface( bytes4 interfaceId - ) public view virtual override(ERC725XCore, ERC725YCore) returns (bool) { - return - interfaceId == _INTERFACEID_ERC725X || - interfaceId == _INTERFACEID_ERC725Y || - super.supportsInterface(interfaceId); + ) + public + view + virtual + override(ERC725XInitAbstract, ERC725YInitAbstract) + returns (bool) + { + return super.supportsInterface(interfaceId); } } diff --git a/implementations/contracts/ERC725X.sol b/implementations/contracts/ERC725X.sol index 47c223ba..928a23ec 100644 --- a/implementations/contracts/ERC725X.sol +++ b/implementations/contracts/ERC725X.sol @@ -1,22 +1,51 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.5; +// interfaces +import {IERC725X} from "./interfaces/IERC725X.sol"; + +// libraries +import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; +import {Address} from "@openzeppelin/contracts/utils/Address.sol"; +import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol"; + // modules -import {OwnableUnset} from "./custom/OwnableUnset.sol"; -import {ERC725XCore} from "./ERC725XCore.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; + +// constants +import { + _INTERFACEID_ERC725X, + OPERATION_0_CALL, + OPERATION_1_CREATE, + OPERATION_2_CREATE2, + OPERATION_3_STATICCALL, + OPERATION_4_DELEGATECALL +} from "./constants.sol"; // errors -import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol"; +import { + ERC725X_InsufficientBalance, + ERC725X_UnknownOperationType, + ERC725X_MsgValueDisallowedInStaticCall, + ERC725X_MsgValueDisallowedInDelegateCall, + ERC725X_CreateOperationsRequireEmptyRecipientAddress, + ERC725X_ContractDeploymentFailed, + ERC725X_NoContractBytecodeProvided, + ERC725X_ExecuteParametersLengthMismatch, + ERC725X_ExecuteParametersEmptyArray, + OwnableCannotSetZeroAddressAsOwner +} from "./errors.sol"; /** - * @title Deployable implementation with `constructor` of ERC725X, a generic executor. - * @author Fabian Vogelsteller + * @title Deployable implementation with `constructor` of ERC725X sub-standard, a generic executor. + * @author Fabian Vogelsteller and , , , * @dev ERC725X provides the ability to call arbitrary functions on any other smart contract (including itself). * It allows to use different type of message calls to interact with addresses such as `call`, `staticcall` and `delegatecall`. * It also allows to deploy and create new contracts via both the `create` and `create2` opcodes. * This is the basis for a smart contract based account system, but could also be used as a proxy account system. */ -contract ERC725X is ERC725XCore { +contract ERC725X is Ownable, ERC165, IERC725X { /** * @notice Deploying an ERC725X smart contract and setting address `initialOwner` as the contract owner. * @dev Deploy a new ERC725X contract with the provided `initialOwner` as the contract {owner}. @@ -29,6 +58,306 @@ contract ERC725X is ERC725XCore { if (initialOwner == address(0)) { revert OwnableCannotSetZeroAddressAsOwner(); } - OwnableUnset._setOwner(initialOwner); + Ownable._transferOwnership(initialOwner); + } + + /** + * @inheritdoc ERC165 + */ + function supportsInterface( + bytes4 interfaceId + ) public view virtual override returns (bool) { + return + interfaceId == _INTERFACEID_ERC725X || + super.supportsInterface(interfaceId); + } + + /** + * @inheritdoc IERC725X + * @custom:requirements + * - SHOULD only be callable by the {owner} of the contract. + * - if a `value` is provided, the contract MUST have at least this amount to transfer to `target` from its balance and execute successfully. + * - if the operation type is `STATICCALL` (`3`) or `DELEGATECALL` (`4`), `value` transfer is disallowed and SHOULD be 0. + * - `target` SHOULD be `address(0)` when deploying a new contract via `operationType` `CREATE` (`1`), or `CREATE2` (`2`). + * + * @custom:events + * - {Executed} event when a call is made with `operationType` 0 (CALL), 3 (STATICCALL) or 4 (DELEGATECALL). + * - {ContractCreated} event when deploying a new contract with `operationType` 1 (CREATE) or 2 (CREATE2). + */ + function execute( + uint256 operationType, + address target, + uint256 value, + bytes memory data + ) public payable virtual override onlyOwner returns (bytes memory) { + return _execute(operationType, target, value, data); + } + + /** + * @inheritdoc IERC725X + * @custom:requirements + * - All the array parameters provided MUST be equal and have the same length. + * - SHOULD only be callable by the {owner} of the contract. + * - The contract MUST have in its balance **at least the sum of all the `values`** to transfer and execute successfully each calldata payloads. + * + * @custom:warning + * - The `msg.value` should not be trusted for any method called with `operationType`: `DELEGATECALL` (4). + * + * @custom:events + * - {Executed} event, when a call is made with `operationType` 0 (CALL), 3 (STATICCALL) or 4 (DELEGATECALL) + * - {ContractCreated} event, when deploying a contract with `operationType` 1 (CREATE) or 2 (CREATE2) + */ + function executeBatch( + uint256[] memory operationsType, + address[] memory targets, + uint256[] memory values, + bytes[] memory datas + ) public payable virtual override onlyOwner returns (bytes[] memory) { + return _executeBatch(operationsType, targets, values, datas); + } + + /** + * @dev check the `operationType` provided and perform the associated low-level opcode after checking for requirements (see {execute}). + */ + function _execute( + uint256 operationType, + address target, + uint256 value, + bytes memory data + ) internal virtual returns (bytes memory) { + // CALL + if (operationType == OPERATION_0_CALL) { + return _executeCall(target, value, data); + } + + // Deploy with CREATE + if (operationType == OPERATION_1_CREATE) { + if (target != address(0)) { + revert ERC725X_CreateOperationsRequireEmptyRecipientAddress(); + } + return _deployCreate(value, data); + } + + // Deploy with CREATE2 + if (operationType == OPERATION_2_CREATE2) { + if (target != address(0)) { + revert ERC725X_CreateOperationsRequireEmptyRecipientAddress(); + } + return _deployCreate2(value, data); + } + + // STATICCALL + if (operationType == OPERATION_3_STATICCALL) { + if (value != 0) { + revert ERC725X_MsgValueDisallowedInStaticCall(); + } + return _executeStaticCall(target, data); + } + + // DELEGATECALL + // + // WARNING! delegatecall is a dangerous operation type! use with EXTRA CAUTION + // + // delegate allows to call another deployed contract and use its functions + // to update the state of the current calling contract. + // + // this can lead to unexpected behaviour on the contract storage, such as: + // - updating any state variables (even if these are protected) + // - update the contract owner + // - run selfdestruct in the context of this contract + // + if (operationType == OPERATION_4_DELEGATECALL) { + if (value != 0) { + revert ERC725X_MsgValueDisallowedInDelegateCall(); + } + return _executeDelegateCall(target, data); + } + + revert ERC725X_UnknownOperationType(operationType); + } + + /** + * @dev check each `operationType` provided in the batch and perform the associated low-level opcode after checking for requirements (see {executeBatch}). + */ + function _executeBatch( + uint256[] memory operationsType, + address[] memory targets, + uint256[] memory values, + bytes[] memory datas + ) internal virtual returns (bytes[] memory) { + if ( + operationsType.length != targets.length || + (targets.length != values.length || values.length != datas.length) + ) { + revert ERC725X_ExecuteParametersLengthMismatch(); + } + + if (operationsType.length == 0) { + revert ERC725X_ExecuteParametersEmptyArray(); + } + + bytes[] memory result = new bytes[](operationsType.length); + + for (uint256 i = 0; i < operationsType.length; ) { + result[i] = _execute( + operationsType[i], + targets[i], + values[i], + datas[i] + ); + + // Increment the iterator in unchecked block to save gas + unchecked { + ++i; + } + } + + return result; + } + + /** + * @dev Perform low-level call (operation type = 0) + * @param target The address on which call is executed + * @param value The value to be sent with the call + * @param data The data to be sent with the call + * @return result The data from the call + */ + function _executeCall( + address target, + uint256 value, + bytes memory data + ) internal virtual returns (bytes memory result) { + if (address(this).balance < value) { + revert ERC725X_InsufficientBalance(address(this).balance, value); + } + + emit Executed(OPERATION_0_CALL, target, value, bytes4(data)); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returnData) = target.call{value: value}( + data + ); + return + Address.verifyCallResult( + success, + returnData, + "ERC725X: Unknown Error" + ); + } + + /** + * @dev Perform low-level staticcall (operation type = 3) + * @param target The address on which staticcall is executed + * @param data The data to be sent with the staticcall + * @return result The data returned from the staticcall + */ + function _executeStaticCall( + address target, + bytes memory data + ) internal virtual returns (bytes memory result) { + emit Executed(OPERATION_3_STATICCALL, target, 0, bytes4(data)); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returnData) = target.staticcall(data); + return + Address.verifyCallResult( + success, + returnData, + "ERC725X: Unknown Error" + ); + } + + /** + * @dev Perform low-level delegatecall (operation type = 4) + * @param target The address on which delegatecall is executed + * @param data The data to be sent with the delegatecall + * @return result The data returned from the delegatecall + * + * @custom:warning The `msg.value` should not be trusted for any method called with `operationType`: `DELEGATECALL` (4). + */ + function _executeDelegateCall( + address target, + bytes memory data + ) internal virtual returns (bytes memory result) { + emit Executed(OPERATION_4_DELEGATECALL, target, 0, bytes4(data)); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returnData) = target.delegatecall(data); + return + Address.verifyCallResult( + success, + returnData, + "ERC725X: Unknown Error" + ); + } + + /** + * @dev Deploy a contract using the `CREATE` opcode (operation type = 1) + * @param value The value to be sent to the contract created + * @param creationCode The contract creation bytecode to deploy appended with the constructor argument(s) + * @return newContract The address of the contract created as bytes + */ + function _deployCreate( + uint256 value, + bytes memory creationCode + ) internal virtual returns (bytes memory newContract) { + if (address(this).balance < value) { + revert ERC725X_InsufficientBalance(address(this).balance, value); + } + + if (creationCode.length == 0) { + revert ERC725X_NoContractBytecodeProvided(); + } + + address contractAddress; + // solhint-disable-next-line no-inline-assembly + assembly { + contractAddress := create( + value, + add(creationCode, 0x20), + mload(creationCode) + ) + } + + if (contractAddress == address(0)) { + revert ERC725X_ContractDeploymentFailed(); + } + + emit ContractCreated( + OPERATION_1_CREATE, + contractAddress, + value, + bytes32(0) + ); + return abi.encodePacked(contractAddress); + } + + /** + * @dev Deploy a contract using the `CREATE2` opcode (operation type = 2) + * @param value The value to be sent to the contract created + * @param creationCode The contract creation bytecode to deploy appended with the constructor argument(s) and a bytes32 salt + * @return newContract The address of the contract created as bytes + */ + function _deployCreate2( + uint256 value, + bytes memory creationCode + ) internal virtual returns (bytes memory newContract) { + if (creationCode.length == 0) { + revert ERC725X_NoContractBytecodeProvided(); + } + + bytes32 salt = BytesLib.toBytes32( + creationCode, + creationCode.length - 32 + ); + bytes memory bytecode = BytesLib.slice( + creationCode, + 0, + creationCode.length - 32 + ); + address contractAddress = Create2.deploy(value, salt, bytecode); + + emit ContractCreated(OPERATION_2_CREATE2, contractAddress, value, salt); + return abi.encodePacked(contractAddress); } } diff --git a/implementations/contracts/ERC725XCore.sol b/implementations/contracts/ERC725XCore.sol deleted file mode 100644 index 5012b7ea..00000000 --- a/implementations/contracts/ERC725XCore.sol +++ /dev/null @@ -1,346 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.5; - -// interfaces -import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -import {IERC725X} from "./interfaces/IERC725X.sol"; - -// libraries -import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; -import {Address} from "@openzeppelin/contracts/utils/Address.sol"; -import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol"; - -// modules -import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import {OwnableUnset} from "./custom/OwnableUnset.sol"; - -// constants -import { - _INTERFACEID_ERC725X, - OPERATION_0_CALL, - OPERATION_1_CREATE, - OPERATION_2_CREATE2, - OPERATION_3_STATICCALL, - OPERATION_4_DELEGATECALL -} from "./constants.sol"; - -import { - ERC725X_InsufficientBalance, - ERC725X_UnknownOperationType, - ERC725X_MsgValueDisallowedInStaticCall, - ERC725X_MsgValueDisallowedInDelegateCall, - ERC725X_CreateOperationsRequireEmptyRecipientAddress, - ERC725X_ContractDeploymentFailed, - ERC725X_NoContractBytecodeProvided, - ERC725X_ExecuteParametersLengthMismatch, - ERC725X_ExecuteParametersEmptyArray -} from "./errors.sol"; - -/** - * @title Core implementation of ERC725X sub-standard, a generic executor. - * @author Fabian Vogelsteller - * It allows to use different type of message calls to interact with addresses such as `call`, `staticcall` and `delegatecall`. - * It also allows to deploy and create new contracts via both the `create` and `create2` opcodes. - * This is the basis for a smart contract based account system, but could also be used as a proxy account system. - */ -abstract contract ERC725XCore is OwnableUnset, ERC165, IERC725X { - /** - * @inheritdoc IERC725X - * @custom:requirements - * - SHOULD only be callable by the {owner} of the contract. - * - if a `value` is provided, the contract MUST have at least this amount to transfer to `target` from its balance and execute successfully. - * - if the operation type is `STATICCALL` (`3`) or `DELEGATECALL` (`4`), `value` transfer is disallowed and SHOULD be 0. - * - `target` SHOULD be `address(0)` when deploying a new contract via `operationType` `CREATE` (`1`), or `CREATE2` (`2`). - * - * @custom:events - * - {Executed} event when a call is made with `operationType` 0 (CALL), 3 (STATICCALL) or 4 (DELEGATECALL). - * - {ContractCreated} event when deploying a new contract with `operationType` 1 (CREATE) or 2 (CREATE2). - */ - function execute( - uint256 operationType, - address target, - uint256 value, - bytes memory data - ) public payable virtual override onlyOwner returns (bytes memory) { - return _execute(operationType, target, value, data); - } - - /** - * @inheritdoc IERC725X - * @custom:requirements - * - All the array parameters provided MUST be equal and have the same length. - * - SHOULD only be callable by the {owner} of the contract. - * - The contract MUST have in its balance **at least the sum of all the `values`** to transfer and execute successfully each calldata payloads. - * - * @custom:warning - * - The `msg.value` should not be trusted for any method called with `operationType`: `DELEGATECALL` (4). - * - * @custom:events - * - {Executed} event, when a call is made with `operationType` 0 (CALL), 3 (STATICCALL) or 4 (DELEGATECALL) - * - {ContractCreated} event, when deploying a contract with `operationType` 1 (CREATE) or 2 (CREATE2) - */ - function executeBatch( - uint256[] memory operationsType, - address[] memory targets, - uint256[] memory values, - bytes[] memory datas - ) public payable virtual override onlyOwner returns (bytes[] memory) { - return _executeBatch(operationsType, targets, values, datas); - } - - /** - * @inheritdoc ERC165 - */ - function supportsInterface( - bytes4 interfaceId - ) public view virtual override(IERC165, ERC165) returns (bool) { - return - interfaceId == _INTERFACEID_ERC725X || - super.supportsInterface(interfaceId); - } - - /** - * @dev check the `operationType` provided and perform the associated low-level opcode after checking for requirements (see {execute}). - */ - function _execute( - uint256 operationType, - address target, - uint256 value, - bytes memory data - ) internal virtual returns (bytes memory) { - // CALL - if (operationType == OPERATION_0_CALL) { - return _executeCall(target, value, data); - } - - // Deploy with CREATE - if (operationType == OPERATION_1_CREATE) { - if (target != address(0)) { - revert ERC725X_CreateOperationsRequireEmptyRecipientAddress(); - } - return _deployCreate(value, data); - } - - // Deploy with CREATE2 - if (operationType == OPERATION_2_CREATE2) { - if (target != address(0)) { - revert ERC725X_CreateOperationsRequireEmptyRecipientAddress(); - } - return _deployCreate2(value, data); - } - - // STATICCALL - if (operationType == OPERATION_3_STATICCALL) { - if (value != 0) { - revert ERC725X_MsgValueDisallowedInStaticCall(); - } - return _executeStaticCall(target, data); - } - - // DELEGATECALL - // - // WARNING! delegatecall is a dangerous operation type! use with EXTRA CAUTION - // - // delegate allows to call another deployed contract and use its functions - // to update the state of the current calling contract. - // - // this can lead to unexpected behaviour on the contract storage, such as: - // - updating any state variables (even if these are protected) - // - update the contract owner - // - run selfdestruct in the context of this contract - // - if (operationType == OPERATION_4_DELEGATECALL) { - if (value != 0) { - revert ERC725X_MsgValueDisallowedInDelegateCall(); - } - return _executeDelegateCall(target, data); - } - - revert ERC725X_UnknownOperationType(operationType); - } - - /** - * @dev check each `operationType` provided in the batch and perform the associated low-level opcode after checking for requirements (see {executeBatch}). - */ - function _executeBatch( - uint256[] memory operationsType, - address[] memory targets, - uint256[] memory values, - bytes[] memory datas - ) internal virtual returns (bytes[] memory) { - if ( - operationsType.length != targets.length || - (targets.length != values.length || values.length != datas.length) - ) { - revert ERC725X_ExecuteParametersLengthMismatch(); - } - - if (operationsType.length == 0) { - revert ERC725X_ExecuteParametersEmptyArray(); - } - - bytes[] memory result = new bytes[](operationsType.length); - - for (uint256 i = 0; i < operationsType.length; ) { - result[i] = _execute( - operationsType[i], - targets[i], - values[i], - datas[i] - ); - - // Increment the iterator in unchecked block to save gas - unchecked { - ++i; - } - } - - return result; - } - - /** - * @dev Perform low-level call (operation type = 0) - * @param target The address on which call is executed - * @param value The value to be sent with the call - * @param data The data to be sent with the call - * @return result The data from the call - */ - function _executeCall( - address target, - uint256 value, - bytes memory data - ) internal virtual returns (bytes memory result) { - if (address(this).balance < value) { - revert ERC725X_InsufficientBalance(address(this).balance, value); - } - - emit Executed(OPERATION_0_CALL, target, value, bytes4(data)); - - // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory returnData) = target.call{value: value}( - data - ); - return - Address.verifyCallResult( - success, - returnData, - "ERC725X: Unknown Error" - ); - } - - /** - * @dev Perform low-level staticcall (operation type = 3) - * @param target The address on which staticcall is executed - * @param data The data to be sent with the staticcall - * @return result The data returned from the staticcall - */ - function _executeStaticCall( - address target, - bytes memory data - ) internal virtual returns (bytes memory result) { - emit Executed(OPERATION_3_STATICCALL, target, 0, bytes4(data)); - - // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory returnData) = target.staticcall(data); - return - Address.verifyCallResult( - success, - returnData, - "ERC725X: Unknown Error" - ); - } - - /** - * @dev Perform low-level delegatecall (operation type = 4) - * @param target The address on which delegatecall is executed - * @param data The data to be sent with the delegatecall - * @return result The data returned from the delegatecall - * - * @custom:warning The `msg.value` should not be trusted for any method called with `operationType`: `DELEGATECALL` (4). - */ - function _executeDelegateCall( - address target, - bytes memory data - ) internal virtual returns (bytes memory result) { - emit Executed(OPERATION_4_DELEGATECALL, target, 0, bytes4(data)); - - // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory returnData) = target.delegatecall(data); - return - Address.verifyCallResult( - success, - returnData, - "ERC725X: Unknown Error" - ); - } - - /** - * @dev Deploy a contract using the `CREATE` opcode (operation type = 1) - * @param value The value to be sent to the contract created - * @param creationCode The contract creation bytecode to deploy appended with the constructor argument(s) - * @return newContract The address of the contract created as bytes - */ - function _deployCreate( - uint256 value, - bytes memory creationCode - ) internal virtual returns (bytes memory newContract) { - if (address(this).balance < value) { - revert ERC725X_InsufficientBalance(address(this).balance, value); - } - - if (creationCode.length == 0) { - revert ERC725X_NoContractBytecodeProvided(); - } - - address contractAddress; - // solhint-disable-next-line no-inline-assembly - assembly { - contractAddress := create( - value, - add(creationCode, 0x20), - mload(creationCode) - ) - } - - if (contractAddress == address(0)) { - revert ERC725X_ContractDeploymentFailed(); - } - - emit ContractCreated( - OPERATION_1_CREATE, - contractAddress, - value, - bytes32(0) - ); - return abi.encodePacked(contractAddress); - } - - /** - * @dev Deploy a contract using the `CREATE2` opcode (operation type = 2) - * @param value The value to be sent to the contract created - * @param creationCode The contract creation bytecode to deploy appended with the constructor argument(s) and a bytes32 salt - * @return newContract The address of the contract created as bytes - */ - function _deployCreate2( - uint256 value, - bytes memory creationCode - ) internal virtual returns (bytes memory newContract) { - if (creationCode.length == 0) { - revert ERC725X_NoContractBytecodeProvided(); - } - - bytes32 salt = BytesLib.toBytes32( - creationCode, - creationCode.length - 32 - ); - bytes memory bytecode = BytesLib.slice( - creationCode, - 0, - creationCode.length - 32 - ); - address contractAddress = Create2.deploy(value, salt, bytecode); - - emit ContractCreated(OPERATION_2_CREATE2, contractAddress, value, salt); - return abi.encodePacked(contractAddress); - } -} diff --git a/implementations/contracts/ERC725XInitAbstract.sol b/implementations/contracts/ERC725XInitAbstract.sol index 7a54213b..a109ee68 100644 --- a/implementations/contracts/ERC725XInitAbstract.sol +++ b/implementations/contracts/ERC725XInitAbstract.sol @@ -1,25 +1,59 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.5; +// interfaces +import {IERC725X} from "./interfaces/IERC725X.sol"; + +// libraries +import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; +import {Address} from "@openzeppelin/contracts/utils/Address.sol"; +import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol"; + // modules import { - Initializable -} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import {OwnableUnset} from "./custom/OwnableUnset.sol"; -import {ERC725XCore} from "./ERC725XCore.sol"; + ERC165Upgradeable +} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; +import { + OwnableUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +// constants +import { + _INTERFACEID_ERC725X, + OPERATION_0_CALL, + OPERATION_1_CREATE, + OPERATION_2_CREATE2, + OPERATION_3_STATICCALL, + OPERATION_4_DELEGATECALL +} from "./constants.sol"; // errors -import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol"; +import { + ERC725X_InsufficientBalance, + ERC725X_UnknownOperationType, + ERC725X_MsgValueDisallowedInStaticCall, + ERC725X_MsgValueDisallowedInDelegateCall, + ERC725X_CreateOperationsRequireEmptyRecipientAddress, + ERC725X_ContractDeploymentFailed, + ERC725X_NoContractBytecodeProvided, + ERC725X_ExecuteParametersLengthMismatch, + ERC725X_ExecuteParametersEmptyArray, + OwnableCannotSetZeroAddressAsOwner +} from "./errors.sol"; /** - * @title Inheritable Proxy Implementation of ERC725X, a generic executor. - * @author Fabian Vogelsteller + * @title Inheritable Proxy Implementation of ERC725X sub-standard, a generic executor. + * @author Fabian Vogelsteller and , , , * @dev ERC725X provides the ability to call arbitrary functions on any other smart contract (including itself). * It allows to use different type of message calls to interact with addresses such as `call`, `staticcall` and `delegatecall`. * It also allows to deploy and create new contracts via both the `create` and `create2` opcodes. * This is the basis for a smart contract based account system, but could also be used as a proxy account system. */ -abstract contract ERC725XInitAbstract is Initializable, ERC725XCore { +abstract contract ERC725XInitAbstract is + OwnableUpgradeable, + ERC165Upgradeable, + IERC725X +{ /** * @dev Internal function to initialize the contract with the provided `initialOwner` as the contract {owner}. * @param initialOwner the owner of the contract. @@ -33,6 +67,306 @@ abstract contract ERC725XInitAbstract is Initializable, ERC725XCore { if (initialOwner == address(0)) { revert OwnableCannotSetZeroAddressAsOwner(); } - OwnableUnset._setOwner(initialOwner); + OwnableUpgradeable._transferOwnership(initialOwner); + } + + /** + * @inheritdoc ERC165Upgradeable + */ + function supportsInterface( + bytes4 interfaceId + ) public view virtual override returns (bool) { + return + interfaceId == _INTERFACEID_ERC725X || + super.supportsInterface(interfaceId); + } + + /** + * @inheritdoc IERC725X + * @custom:requirements + * - SHOULD only be callable by the {owner} of the contract. + * - if a `value` is provided, the contract MUST have at least this amount to transfer to `target` from its balance and execute successfully. + * - if the operation type is `STATICCALL` (`3`) or `DELEGATECALL` (`4`), `value` transfer is disallowed and SHOULD be 0. + * - `target` SHOULD be `address(0)` when deploying a new contract via `operationType` `CREATE` (`1`), or `CREATE2` (`2`). + * + * @custom:events + * - {Executed} event when a call is made with `operationType` 0 (CALL), 3 (STATICCALL) or 4 (DELEGATECALL). + * - {ContractCreated} event when deploying a new contract with `operationType` 1 (CREATE) or 2 (CREATE2). + */ + function execute( + uint256 operationType, + address target, + uint256 value, + bytes memory data + ) public payable virtual override onlyOwner returns (bytes memory) { + return _execute(operationType, target, value, data); + } + + /** + * @inheritdoc IERC725X + * @custom:requirements + * - All the array parameters provided MUST be equal and have the same length. + * - SHOULD only be callable by the {owner} of the contract. + * - The contract MUST have in its balance **at least the sum of all the `values`** to transfer and execute successfully each calldata payloads. + * + * @custom:warning + * - The `msg.value` should not be trusted for any method called with `operationType`: `DELEGATECALL` (4). + * + * @custom:events + * - {Executed} event, when a call is made with `operationType` 0 (CALL), 3 (STATICCALL) or 4 (DELEGATECALL) + * - {ContractCreated} event, when deploying a contract with `operationType` 1 (CREATE) or 2 (CREATE2) + */ + function executeBatch( + uint256[] memory operationsType, + address[] memory targets, + uint256[] memory values, + bytes[] memory datas + ) public payable virtual override onlyOwner returns (bytes[] memory) { + return _executeBatch(operationsType, targets, values, datas); + } + + /** + * @dev check the `operationType` provided and perform the associated low-level opcode after checking for requirements (see {execute}). + */ + function _execute( + uint256 operationType, + address target, + uint256 value, + bytes memory data + ) internal virtual returns (bytes memory) { + // CALL + if (operationType == OPERATION_0_CALL) { + return _executeCall(target, value, data); + } + + // Deploy with CREATE + if (operationType == OPERATION_1_CREATE) { + if (target != address(0)) { + revert ERC725X_CreateOperationsRequireEmptyRecipientAddress(); + } + return _deployCreate(value, data); + } + + // Deploy with CREATE2 + if (operationType == OPERATION_2_CREATE2) { + if (target != address(0)) { + revert ERC725X_CreateOperationsRequireEmptyRecipientAddress(); + } + return _deployCreate2(value, data); + } + + // STATICCALL + if (operationType == OPERATION_3_STATICCALL) { + if (value != 0) { + revert ERC725X_MsgValueDisallowedInStaticCall(); + } + return _executeStaticCall(target, data); + } + + // DELEGATECALL + // + // WARNING! delegatecall is a dangerous operation type! use with EXTRA CAUTION + // + // delegate allows to call another deployed contract and use its functions + // to update the state of the current calling contract. + // + // this can lead to unexpected behaviour on the contract storage, such as: + // - updating any state variables (even if these are protected) + // - update the contract owner + // - run selfdestruct in the context of this contract + // + if (operationType == OPERATION_4_DELEGATECALL) { + if (value != 0) { + revert ERC725X_MsgValueDisallowedInDelegateCall(); + } + return _executeDelegateCall(target, data); + } + + revert ERC725X_UnknownOperationType(operationType); + } + + /** + * @dev check each `operationType` provided in the batch and perform the associated low-level opcode after checking for requirements (see {executeBatch}). + */ + function _executeBatch( + uint256[] memory operationsType, + address[] memory targets, + uint256[] memory values, + bytes[] memory datas + ) internal virtual returns (bytes[] memory) { + if ( + operationsType.length != targets.length || + (targets.length != values.length || values.length != datas.length) + ) { + revert ERC725X_ExecuteParametersLengthMismatch(); + } + + if (operationsType.length == 0) { + revert ERC725X_ExecuteParametersEmptyArray(); + } + + bytes[] memory result = new bytes[](operationsType.length); + + for (uint256 i = 0; i < operationsType.length; ) { + result[i] = _execute( + operationsType[i], + targets[i], + values[i], + datas[i] + ); + + // Increment the iterator in unchecked block to save gas + unchecked { + ++i; + } + } + + return result; + } + + /** + * @dev Perform low-level call (operation type = 0) + * @param target The address on which call is executed + * @param value The value to be sent with the call + * @param data The data to be sent with the call + * @return result The data from the call + */ + function _executeCall( + address target, + uint256 value, + bytes memory data + ) internal virtual returns (bytes memory result) { + if (address(this).balance < value) { + revert ERC725X_InsufficientBalance(address(this).balance, value); + } + + emit Executed(OPERATION_0_CALL, target, value, bytes4(data)); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returnData) = target.call{value: value}( + data + ); + return + Address.verifyCallResult( + success, + returnData, + "ERC725X: Unknown Error" + ); + } + + /** + * @dev Perform low-level staticcall (operation type = 3) + * @param target The address on which staticcall is executed + * @param data The data to be sent with the staticcall + * @return result The data returned from the staticcall + */ + function _executeStaticCall( + address target, + bytes memory data + ) internal virtual returns (bytes memory result) { + emit Executed(OPERATION_3_STATICCALL, target, 0, bytes4(data)); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returnData) = target.staticcall(data); + return + Address.verifyCallResult( + success, + returnData, + "ERC725X: Unknown Error" + ); + } + + /** + * @dev Perform low-level delegatecall (operation type = 4) + * @param target The address on which delegatecall is executed + * @param data The data to be sent with the delegatecall + * @return result The data returned from the delegatecall + * + * @custom:warning The `msg.value` should not be trusted for any method called with `operationType`: `DELEGATECALL` (4). + */ + function _executeDelegateCall( + address target, + bytes memory data + ) internal virtual returns (bytes memory result) { + emit Executed(OPERATION_4_DELEGATECALL, target, 0, bytes4(data)); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returnData) = target.delegatecall(data); + return + Address.verifyCallResult( + success, + returnData, + "ERC725X: Unknown Error" + ); + } + + /** + * @dev Deploy a contract using the `CREATE` opcode (operation type = 1) + * @param value The value to be sent to the contract created + * @param creationCode The contract creation bytecode to deploy appended with the constructor argument(s) + * @return newContract The address of the contract created as bytes + */ + function _deployCreate( + uint256 value, + bytes memory creationCode + ) internal virtual returns (bytes memory newContract) { + if (address(this).balance < value) { + revert ERC725X_InsufficientBalance(address(this).balance, value); + } + + if (creationCode.length == 0) { + revert ERC725X_NoContractBytecodeProvided(); + } + + address contractAddress; + // solhint-disable-next-line no-inline-assembly + assembly { + contractAddress := create( + value, + add(creationCode, 0x20), + mload(creationCode) + ) + } + + if (contractAddress == address(0)) { + revert ERC725X_ContractDeploymentFailed(); + } + + emit ContractCreated( + OPERATION_1_CREATE, + contractAddress, + value, + bytes32(0) + ); + return abi.encodePacked(contractAddress); + } + + /** + * @dev Deploy a contract using the `CREATE2` opcode (operation type = 2) + * @param value The value to be sent to the contract created + * @param creationCode The contract creation bytecode to deploy appended with the constructor argument(s) and a bytes32 salt + * @return newContract The address of the contract created as bytes + */ + function _deployCreate2( + uint256 value, + bytes memory creationCode + ) internal virtual returns (bytes memory newContract) { + if (creationCode.length == 0) { + revert ERC725X_NoContractBytecodeProvided(); + } + + bytes32 salt = BytesLib.toBytes32( + creationCode, + creationCode.length - 32 + ); + bytes memory bytecode = BytesLib.slice( + creationCode, + 0, + creationCode.length - 32 + ); + address contractAddress = Create2.deploy(value, salt, bytecode); + + emit ContractCreated(OPERATION_2_CREATE2, contractAddress, value, salt); + return abi.encodePacked(contractAddress); } } diff --git a/implementations/contracts/ERC725Y.sol b/implementations/contracts/ERC725Y.sol index ca4e7877..eefdb36c 100644 --- a/implementations/contracts/ERC725Y.sol +++ b/implementations/contracts/ERC725Y.sol @@ -1,20 +1,36 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.4; +// interfaces +import {IERC725Y} from "./interfaces/IERC725Y.sol"; + // modules -import {OwnableUnset} from "./custom/OwnableUnset.sol"; -import {ERC725YCore} from "./ERC725YCore.sol"; +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; + +// constants +import {_INTERFACEID_ERC725Y} from "./constants.sol"; // errors -import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol"; +import { + ERC725Y_MsgValueDisallowed, + ERC725Y_DataKeysValuesLengthMismatch, + ERC725Y_DataKeysValuesEmptyArray, + OwnableCannotSetZeroAddressAsOwner +} from "./errors.sol"; /** - * @title Deployable implementation with `constructor` of ERC725Y, a generic data key/value store. - * @author Fabian Vogelsteller + * @title Deployable implementation with `constructor` of ERC725Y sub-standard, a generic data key/value store. + * @author Fabian Vogelsteller and , , , * @dev ERC725Y provides the ability to set arbitrary data key/value pairs that can be changed over time. * It is intended to standardise certain data key/value pairs to allow automated read and writes from/to the contract storage. */ -contract ERC725Y is ERC725YCore { +contract ERC725Y is Ownable, ERC165, IERC725Y { + /** + * @dev Map `bytes32` data keys to their `bytes` data values. + */ + mapping(bytes32 => bytes) internal _store; + /** * @notice Deploying an ERC725Y smart contract and setting address `initialOwner` as the contract owner. * @dev Deploy a new ERC725Y contract with the provided `initialOwner` as the contract {owner}. @@ -27,6 +43,160 @@ contract ERC725Y is ERC725YCore { if (initialOwner == address(0)) { revert OwnableCannotSetZeroAddressAsOwner(); } - OwnableUnset._setOwner(initialOwner); + Ownable._transferOwnership(initialOwner); + } + + /** + * @inheritdoc IERC725Y + */ + function getData( + bytes32 dataKey + ) public view virtual override returns (bytes memory dataValue) { + return _getData(dataKey); + } + + /** + * @inheritdoc IERC725Y + */ + function getDataBatch( + bytes32[] memory dataKeys + ) public view virtual override returns (bytes[] memory dataValues) { + dataValues = new bytes[](dataKeys.length); + + for (uint256 i = 0; i < dataKeys.length; ) { + dataValues[i] = _getData(dataKeys[i]); + + // Increment the iterator in unchecked block to save gas + unchecked { + ++i; + } + } + + return dataValues; + } + + /** + * @inheritdoc IERC725Y + * @custom:requirements + * - SHOULD only be callable by the {owner}. + * + * @custom:warning + * **Note for developers:** despite the fact that this function is set as `payable`, the function is not intended to receive value + * (= native tokens). **An additional check has been implemented to ensure that `msg.value` sent was equal to 0**. + * If you want to allow this function to receive value in your inheriting contract, this function can be overriden to remove this check. + * + * @custom:events {DataChanged} event. + */ + function setData( + bytes32 dataKey, + bytes memory dataValue + ) public payable virtual override onlyOwner { + if (msg.value != 0) revert ERC725Y_MsgValueDisallowed(); + _setData(dataKey, dataValue); + } + + /** + * @inheritdoc IERC725Y + * @custom:requirements + * - SHOULD only be callable by the {owner} of the contract. + * + * @custom:warning + * **Note for developers:** despite the fact that this function is set as `payable`, the function is not intended to receive value + * (= native tokens). **An additional check has been implemented to ensure that `msg.value` sent was equal to 0**. + * If you want to allow this function to receive value in your inheriting contract, this function can be overriden to remove this check. + * + * @custom:events {DataChanged} event **for each data key/value pair set**. + */ + function setDataBatch( + bytes32[] memory dataKeys, + bytes[] memory dataValues + ) public payable virtual override onlyOwner { + /// @dev do not allow to send value by default when setting data in ERC725Y + if (msg.value != 0) revert ERC725Y_MsgValueDisallowed(); + _setDataBatch(dataKeys, dataValues); + } + + /** + * @dev Read the value stored under a specific `dataKey` inside the underlying ERC725Y storage, + * represented as a mapping of `bytes32` data keys mapped to their `bytes` data values. + * + * ```solidity + * mapping(bytes32 => bytes) _store + * ``` + * + * @param dataKey A bytes32 data key to read the associated `bytes` value from the store. + * @return dataValue The `bytes` value associated with the given `dataKey` in the ERC725Y storage. + */ + function _getData( + bytes32 dataKey + ) internal view virtual returns (bytes memory dataValue) { + return _store[dataKey]; + } + + /** + * @dev Write a `dataValue` to the underlying ERC725Y storage, represented as a mapping of + * `bytes32` data keys mapped to their `bytes` data values. + * + * ```solidity + * mapping(bytes32 => bytes) _store + * ``` + * + * @param dataKey A bytes32 data key to write the associated `bytes` value to the store. + * @param dataValue The `bytes` value to associate with the given `dataKey` in the ERC725Y storage. + * + * @custom:events {DataChanged} event emitted after a successful `setData` call. + */ + function _setData( + bytes32 dataKey, + bytes memory dataValue + ) internal virtual { + _store[dataKey] = dataValue; + emit DataChanged(dataKey, dataValue); + } + + /** + * @dev Write a set of `dataValues` to the underlying ERC725Y storage for each associated `dataKeys`. The ERC725Y storage is + * represented as a mapping of `bytes32` data keys mapped to their `bytes` data values. + * + * ```solidity + * mapping(bytes32 => bytes) _store + * ``` + * + * @param dataKeys A bytes32 array of data keys to write the associated `bytes` value to the store. + * @param dataValues The `bytes` values to associate with each given `dataKeys` in the ERC725Y storage. + * + * @custom:events {DataChanged} event emitted for each successful data key-value pairs set. + */ + function _setDataBatch( + bytes32[] memory dataKeys, + bytes[] memory dataValues + ) internal virtual { + if (dataKeys.length != dataValues.length) { + revert ERC725Y_DataKeysValuesLengthMismatch(); + } + + if (dataKeys.length == 0) { + revert ERC725Y_DataKeysValuesEmptyArray(); + } + + for (uint256 i = 0; i < dataKeys.length; ) { + _setData(dataKeys[i], dataValues[i]); + + // Increment the iterator in unchecked block to save gas + unchecked { + ++i; + } + } + } + + /** + * @inheritdoc ERC165 + */ + function supportsInterface( + bytes4 interfaceId + ) public view virtual override returns (bool) { + return + interfaceId == _INTERFACEID_ERC725Y || + super.supportsInterface(interfaceId); } } diff --git a/implementations/contracts/ERC725YCore.sol b/implementations/contracts/ERC725YCore.sol deleted file mode 100644 index d2909a74..00000000 --- a/implementations/contracts/ERC725YCore.sol +++ /dev/null @@ -1,186 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.8.4; - -// interfaces -import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -import {IERC725Y} from "./interfaces/IERC725Y.sol"; - -// modules -import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import {OwnableUnset} from "./custom/OwnableUnset.sol"; - -// constants -import {_INTERFACEID_ERC725Y} from "./constants.sol"; - -import { - ERC725Y_MsgValueDisallowed, - ERC725Y_DataKeysValuesLengthMismatch, - ERC725Y_DataKeysValuesEmptyArray -} from "./errors.sol"; - -/** - * @title Core implementation of ERC725Y sub-standard, a general data key/value store. - * @author Fabian Vogelsteller - * @dev ERC725Y provides the ability to set arbitrary data key/value pairs that can be changed over time. - * It is intended to standardise certain data key/value pairs to allow automated read and writes from/to the contract storage. - */ -abstract contract ERC725YCore is OwnableUnset, ERC165, IERC725Y { - /** - * @dev Map `bytes32` data keys to their `bytes` data values. - */ - mapping(bytes32 => bytes) internal _store; - - /** - * @inheritdoc IERC725Y - */ - function getData( - bytes32 dataKey - ) public view virtual override returns (bytes memory dataValue) { - return _getData(dataKey); - } - - /** - * @inheritdoc IERC725Y - */ - function getDataBatch( - bytes32[] memory dataKeys - ) public view virtual override returns (bytes[] memory dataValues) { - dataValues = new bytes[](dataKeys.length); - - for (uint256 i = 0; i < dataKeys.length; ) { - dataValues[i] = _getData(dataKeys[i]); - - // Increment the iterator in unchecked block to save gas - unchecked { - ++i; - } - } - - return dataValues; - } - - /** - * @inheritdoc IERC725Y - * @custom:requirements - * - SHOULD only be callable by the {owner}. - * - * @custom:warning - * **Note for developers:** despite the fact that this function is set as `payable`, the function is not intended to receive value - * (= native tokens). **An additional check has been implemented to ensure that `msg.value` sent was equal to 0**. - * If you want to allow this function to receive value in your inheriting contract, this function can be overriden to remove this check. - * - * @custom:events {DataChanged} event. - */ - function setData( - bytes32 dataKey, - bytes memory dataValue - ) public payable virtual override onlyOwner { - if (msg.value != 0) revert ERC725Y_MsgValueDisallowed(); - _setData(dataKey, dataValue); - } - - /** - * @inheritdoc IERC725Y - * @custom:requirements - * - SHOULD only be callable by the {owner} of the contract. - * - * @custom:warning - * **Note for developers:** despite the fact that this function is set as `payable`, the function is not intended to receive value - * (= native tokens). **An additional check has been implemented to ensure that `msg.value` sent was equal to 0**. - * If you want to allow this function to receive value in your inheriting contract, this function can be overriden to remove this check. - * - * @custom:events {DataChanged} event **for each data key/value pair set**. - */ - function setDataBatch( - bytes32[] memory dataKeys, - bytes[] memory dataValues - ) public payable virtual override onlyOwner { - /// @dev do not allow to send value by default when setting data in ERC725Y - if (msg.value != 0) revert ERC725Y_MsgValueDisallowed(); - _setDataBatch(dataKeys, dataValues); - } - - /** - * @dev Read the value stored under a specific `dataKey` inside the underlying ERC725Y storage, - * represented as a mapping of `bytes32` data keys mapped to their `bytes` data values. - * - * ```solidity - * mapping(bytes32 => bytes) _store - * ``` - * - * @param dataKey A bytes32 data key to read the associated `bytes` value from the store. - * @return dataValue The `bytes` value associated with the given `dataKey` in the ERC725Y storage. - */ - function _getData( - bytes32 dataKey - ) internal view virtual returns (bytes memory dataValue) { - return _store[dataKey]; - } - - /** - * @dev Write a `dataValue` to the underlying ERC725Y storage, represented as a mapping of - * `bytes32` data keys mapped to their `bytes` data values. - * - * ```solidity - * mapping(bytes32 => bytes) _store - * ``` - * - * @param dataKey A bytes32 data key to write the associated `bytes` value to the store. - * @param dataValue The `bytes` value to associate with the given `dataKey` in the ERC725Y storage. - * - * @custom:events {DataChanged} event emitted after a successful `setData` call. - */ - function _setData( - bytes32 dataKey, - bytes memory dataValue - ) internal virtual { - _store[dataKey] = dataValue; - emit DataChanged(dataKey, dataValue); - } - - /** - * @dev Write a set of `dataValues` to the underlying ERC725Y storage for each associated `dataKeys`. The ERC725Y storage is - * represented as a mapping of `bytes32` data keys mapped to their `bytes` data values. - * - * ```solidity - * mapping(bytes32 => bytes) _store - * ``` - * - * @param dataKeys A bytes32 array of data keys to write the associated `bytes` value to the store. - * @param dataValues The `bytes` values to associate with each given `dataKeys` in the ERC725Y storage. - * - * @custom:events {DataChanged} event emitted for each successful data key-value pairs set. - */ - function _setDataBatch( - bytes32[] memory dataKeys, - bytes[] memory dataValues - ) internal virtual { - if (dataKeys.length != dataValues.length) { - revert ERC725Y_DataKeysValuesLengthMismatch(); - } - - if (dataKeys.length == 0) { - revert ERC725Y_DataKeysValuesEmptyArray(); - } - - for (uint256 i = 0; i < dataKeys.length; ) { - _setData(dataKeys[i], dataValues[i]); - - // Increment the iterator in unchecked block to save gas - unchecked { - ++i; - } - } - } - - /** - * @inheritdoc ERC165 - */ - function supportsInterface( - bytes4 interfaceId - ) public view virtual override(IERC165, ERC165) returns (bool) { - return - interfaceId == _INTERFACEID_ERC725Y || - super.supportsInterface(interfaceId); - } -} diff --git a/implementations/contracts/ERC725YInit.sol b/implementations/contracts/ERC725YInit.sol index 34f5075f..b0d02f75 100644 --- a/implementations/contracts/ERC725YInit.sol +++ b/implementations/contracts/ERC725YInit.sol @@ -6,7 +6,7 @@ import {ERC725YInitAbstract} from "./ERC725YInitAbstract.sol"; /** * @title Deployable Proxy Implementation of ERC725Y, a generic data key/value store. - * @author Fabian Vogelsteller + * @author Fabian Vogelsteller and , , , * @dev ERC725Y provides the ability to set arbitrary data key/value pairs that can be changed over time. * It is intended to standardise certain data key/value pairs to allow automated read and writes from/to the contract storage. */ diff --git a/implementations/contracts/ERC725YInitAbstract.sol b/implementations/contracts/ERC725YInitAbstract.sol index ff21652b..5cf30959 100644 --- a/implementations/contracts/ERC725YInitAbstract.sol +++ b/implementations/contracts/ERC725YInitAbstract.sol @@ -1,23 +1,44 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.4; +// interfaces +import {IERC725Y} from "./interfaces/IERC725Y.sol"; + // modules import { - Initializable -} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import {OwnableUnset} from "./custom/OwnableUnset.sol"; -import {ERC725YCore} from "./ERC725YCore.sol"; + ERC165Upgradeable +} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; +import { + OwnableUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +// constants +import {_INTERFACEID_ERC725Y} from "./constants.sol"; // errors -import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol"; +import { + ERC725Y_MsgValueDisallowed, + ERC725Y_DataKeysValuesLengthMismatch, + ERC725Y_DataKeysValuesEmptyArray, + OwnableCannotSetZeroAddressAsOwner +} from "./errors.sol"; /** - * @title Inheritable Proxy Implementation of ERC725Y, a generic data key/value store - * @author Fabian Vogelsteller + * @title Inheritable Proxy Implementation of ERC725Y sub-standard, a generic data key/value store + * @author Fabian Vogelsteller and , , , * @dev ERC725Y provides the ability to set arbitrary data key/value pairs that can be changed over time. * It is intended to standardise certain data key/value pairs to allow automated read and writes from/to the contract storage. */ -abstract contract ERC725YInitAbstract is Initializable, ERC725YCore { +abstract contract ERC725YInitAbstract is + OwnableUpgradeable, + ERC165Upgradeable, + IERC725Y +{ + /** + * @dev Map `bytes32` data keys to their `bytes` data values. + */ + mapping(bytes32 => bytes) internal _store; + /** * @dev Internal function to initialize the contract with the provided `initialOwner` as the contract {owner}. * @param initialOwner the owner of the contract. @@ -31,6 +52,160 @@ abstract contract ERC725YInitAbstract is Initializable, ERC725YCore { if (initialOwner == address(0)) { revert OwnableCannotSetZeroAddressAsOwner(); } - OwnableUnset._setOwner(initialOwner); + OwnableUpgradeable._transferOwnership(initialOwner); + } + + /** + * @inheritdoc IERC725Y + */ + function getData( + bytes32 dataKey + ) public view virtual override returns (bytes memory dataValue) { + return _getData(dataKey); + } + + /** + * @inheritdoc IERC725Y + */ + function getDataBatch( + bytes32[] memory dataKeys + ) public view virtual override returns (bytes[] memory dataValues) { + dataValues = new bytes[](dataKeys.length); + + for (uint256 i = 0; i < dataKeys.length; ) { + dataValues[i] = _getData(dataKeys[i]); + + // Increment the iterator in unchecked block to save gas + unchecked { + ++i; + } + } + + return dataValues; + } + + /** + * @inheritdoc IERC725Y + * @custom:requirements + * - SHOULD only be callable by the {owner}. + * + * @custom:warning + * **Note for developers:** despite the fact that this function is set as `payable`, the function is not intended to receive value + * (= native tokens). **An additional check has been implemented to ensure that `msg.value` sent was equal to 0**. + * If you want to allow this function to receive value in your inheriting contract, this function can be overriden to remove this check. + * + * @custom:events {DataChanged} event. + */ + function setData( + bytes32 dataKey, + bytes memory dataValue + ) public payable virtual override onlyOwner { + if (msg.value != 0) revert ERC725Y_MsgValueDisallowed(); + _setData(dataKey, dataValue); + } + + /** + * @inheritdoc IERC725Y + * @custom:requirements + * - SHOULD only be callable by the {owner} of the contract. + * + * @custom:warning + * **Note for developers:** despite the fact that this function is set as `payable`, the function is not intended to receive value + * (= native tokens). **An additional check has been implemented to ensure that `msg.value` sent was equal to 0**. + * If you want to allow this function to receive value in your inheriting contract, this function can be overriden to remove this check. + * + * @custom:events {DataChanged} event **for each data key/value pair set**. + */ + function setDataBatch( + bytes32[] memory dataKeys, + bytes[] memory dataValues + ) public payable virtual override onlyOwner { + /// @dev do not allow to send value by default when setting data in ERC725Y + if (msg.value != 0) revert ERC725Y_MsgValueDisallowed(); + _setDataBatch(dataKeys, dataValues); + } + + /** + * @dev Read the value stored under a specific `dataKey` inside the underlying ERC725Y storage, + * represented as a mapping of `bytes32` data keys mapped to their `bytes` data values. + * + * ```solidity + * mapping(bytes32 => bytes) _store + * ``` + * + * @param dataKey A bytes32 data key to read the associated `bytes` value from the store. + * @return dataValue The `bytes` value associated with the given `dataKey` in the ERC725Y storage. + */ + function _getData( + bytes32 dataKey + ) internal view virtual returns (bytes memory dataValue) { + return _store[dataKey]; + } + + /** + * @dev Write a `dataValue` to the underlying ERC725Y storage, represented as a mapping of + * `bytes32` data keys mapped to their `bytes` data values. + * + * ```solidity + * mapping(bytes32 => bytes) _store + * ``` + * + * @param dataKey A bytes32 data key to write the associated `bytes` value to the store. + * @param dataValue The `bytes` value to associate with the given `dataKey` in the ERC725Y storage. + * + * @custom:events {DataChanged} event emitted after a successful `setData` call. + */ + function _setData( + bytes32 dataKey, + bytes memory dataValue + ) internal virtual { + _store[dataKey] = dataValue; + emit DataChanged(dataKey, dataValue); + } + + /** + * @dev Write a set of `dataValues` to the underlying ERC725Y storage for each associated `dataKeys`. The ERC725Y storage is + * represented as a mapping of `bytes32` data keys mapped to their `bytes` data values. + * + * ```solidity + * mapping(bytes32 => bytes) _store + * ``` + * + * @param dataKeys A bytes32 array of data keys to write the associated `bytes` value to the store. + * @param dataValues The `bytes` values to associate with each given `dataKeys` in the ERC725Y storage. + * + * @custom:events {DataChanged} event emitted for each successful data key-value pairs set. + */ + function _setDataBatch( + bytes32[] memory dataKeys, + bytes[] memory dataValues + ) internal virtual { + if (dataKeys.length != dataValues.length) { + revert ERC725Y_DataKeysValuesLengthMismatch(); + } + + if (dataKeys.length == 0) { + revert ERC725Y_DataKeysValuesEmptyArray(); + } + + for (uint256 i = 0; i < dataKeys.length; ) { + _setData(dataKeys[i], dataValues[i]); + + // Increment the iterator in unchecked block to save gas + unchecked { + ++i; + } + } + } + + /** + * @inheritdoc ERC165Upgradeable + */ + function supportsInterface( + bytes4 interfaceId + ) public view virtual override returns (bool) { + return + interfaceId == _INTERFACEID_ERC725Y || + super.supportsInterface(interfaceId); } } diff --git a/implementations/contracts/custom/OwnableUnset.sol b/implementations/contracts/custom/OwnableUnset.sol deleted file mode 100644 index 4c8ee3f3..00000000 --- a/implementations/contracts/custom/OwnableUnset.sol +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -// errors -import { - OwnableCannotSetZeroAddressAsOwner, - OwnableCallerNotTheOwner -} from "../errors.sol"; - -/** - * @title OwnableUnset - * @dev modified version of OpenZeppelin implementation, where: - * - _setOwner(address) function is internal, so this function can be used in constructor - * of contracts implementation (instead of using transferOwnership(address) - * - the contract does not inherit from Context contract - */ -abstract contract OwnableUnset { - address private _owner; - - event OwnershipTransferred( - address indexed previousOwner, - address indexed newOwner - ); - - /** - * @dev Returns the address of the current owner. - */ - function owner() public view virtual returns (address) { - return _owner; - } - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - _checkOwner(); - _; - } - - /** - * @dev Leaves the contract without owner. It will not be possible to call - * `onlyOwner` functions anymore. Can only be called by the current owner. - * - * NOTE: Renouncing ownership will leave the contract without an owner, - * thereby removing any functionality that is only available to the owner. - */ - function renounceOwnership() public virtual onlyOwner { - _setOwner(address(0)); - } - - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`). - * Can only be called by the current owner. - */ - function transferOwnership(address newOwner) public virtual onlyOwner { - if (newOwner == address(0)) { - revert OwnableCannotSetZeroAddressAsOwner(); - } - _setOwner(newOwner); - } - - /** - * @dev Throws if the sender is not the owner. - */ - function _checkOwner() internal view virtual { - if (owner() != msg.sender) { - revert OwnableCallerNotTheOwner(msg.sender); - } - } - - /** - * @dev Changes the owner if `newOwner` and oldOwner are different - * This pattern is useful in inheritance. - */ - function _setOwner(address newOwner) internal virtual { - if (newOwner != owner()) { - emit OwnershipTransferred(_owner, newOwner); - _owner = newOwner; - } - } -} diff --git a/implementations/contracts/errors.sol b/implementations/contracts/errors.sol index f641525e..275be4a4 100644 --- a/implementations/contracts/errors.sol +++ b/implementations/contracts/errors.sol @@ -1,18 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.4; -/** - * @dev Reverts when trying to set `address(0)` as the contract owner when deploying the contract, - * initializing it or transferring ownership of the contract. - */ -error OwnableCannotSetZeroAddressAsOwner(); - -/** - * @dev Reverts when only the owner is allowed to call the function. - * @param callerAddress The address that tried to make the call. - */ -error OwnableCallerNotTheOwner(address callerAddress); - /** * @dev Reverts when trying to send more native tokens `value` than available in current `balance`. * @param balance The balance of native tokens of the ERC725X smart contract. @@ -83,3 +71,8 @@ error ERC725Y_DataKeysValuesEmptyArray(); * @dev Reverts when sending value to the {setData} or {setDataBatch} function. */ error ERC725Y_MsgValueDisallowed(); + +/** + * @dev Reverts when trying to set `address(0)` as the contract owner when deploying the contract or initializing it. + */ +error OwnableCannotSetZeroAddressAsOwner(); diff --git a/implementations/contracts/helpers/ConstantsChecker.sol b/implementations/contracts/helpers/ConstantsChecker.sol index e38769bc..9c9e9652 100644 --- a/implementations/contracts/helpers/ConstantsChecker.sol +++ b/implementations/contracts/helpers/ConstantsChecker.sol @@ -13,7 +13,7 @@ import {_INTERFACEID_ERC725X, _INTERFACEID_ERC725Y} from "../constants.sol"; */ contract ConstantsChecker { function getERC725XInterfaceID() public pure returns (bytes4) { - // solhint-disable-next-line custom-errors + // solhint-disable-next-line gas-custom-errors require( _INTERFACEID_ERC725X == type(IERC725X).interfaceId, "hardcoded _INTERFACEID_ERC725X in `constants.sol` does not match `type(IERC725X).interfaceId`" @@ -22,7 +22,7 @@ contract ConstantsChecker { } function getERC725YInterfaceID() public pure returns (bytes4) { - // solhint-disable-next-line custom-errors + // solhint-disable-next-line gas-custom-errors require( _INTERFACEID_ERC725Y == type(IERC725Y).interfaceId, "hardcoded _INTERFACEID_ERC725Y in `constants.sol` does not match `type(IERC725Y).interfaceId`" diff --git a/implementations/contracts/helpers/CustomRevertTest.sol b/implementations/contracts/helpers/CustomRevertTest.sol index 01f46afd..dc8c4e02 100644 --- a/implementations/contracts/helpers/CustomRevertTest.sol +++ b/implementations/contracts/helpers/CustomRevertTest.sol @@ -13,12 +13,12 @@ contract RevertTester { } function revertMeWithStringView() public pure { - // solhint-disable-next-line custom-errors + // solhint-disable-next-line gas-custom-errors revert("I reverted"); } function revertMeWithStringErrorNotView() public pure { - // solhint-disable-next-line custom-errors + // solhint-disable-next-line gas-custom-errors revert("I reverted"); } diff --git a/implementations/contracts/interfaces/IERC725X.sol b/implementations/contracts/interfaces/IERC725X.sol index e21b27c8..4197710d 100644 --- a/implementations/contracts/interfaces/IERC725X.sol +++ b/implementations/contracts/interfaces/IERC725X.sol @@ -1,9 +1,6 @@ // SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; -// interfaces -import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; - /** * @title The interface for the ERC725X sub-standard, a generic executor. * @dev ERC725X provides the ability to call arbitrary functions on any other smart contract (including itself). @@ -11,7 +8,7 @@ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; * It also allows to deploy and create new contracts via both the `create` and `create2` opcodes. * This is the basis for a smart contract based account system, but could also be used as a proxy account system. */ -interface IERC725X is IERC165 { +interface IERC725X { /** * @notice Deployed new contract at address `contractAddress` and funded with `value` wei (deployed using opcode: `operationType`). * @dev Emitted when a new contract was created and deployed. diff --git a/implementations/contracts/interfaces/IERC725Y.sol b/implementations/contracts/interfaces/IERC725Y.sol index 53815fae..6ebbc25d 100644 --- a/implementations/contracts/interfaces/IERC725Y.sol +++ b/implementations/contracts/interfaces/IERC725Y.sol @@ -1,15 +1,12 @@ // SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; -// interfaces -import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; - /** * @title The interface for ERC725Y sub-standard, a generic data key/value store. * @dev ERC725Y provides the ability to set arbitrary data key/value pairs that can be changed over time. * It is intended to standardise certain data key/value pairs to allow automated read and writes from/to the contract storage. */ -interface IERC725Y is IERC165 { +interface IERC725Y { /** * @notice The following data key/value pair has been changed in the ERC725Y storage: Data key: `dataKey`, data value: `dataValue`. * @dev Emitted when data at a specific `dataKey` was changed to a new value `dataValue`. diff --git a/implementations/package-lock.json b/implementations/package-lock.json index 79bce021..d0a57c15 100644 --- a/implementations/package-lock.json +++ b/implementations/package-lock.json @@ -9,8 +9,8 @@ "version": "7.0.0", "license": "Apache-2.0", "dependencies": { - "@openzeppelin/contracts": "^4.9.3", - "@openzeppelin/contracts-upgradeable": "^4.9.3", + "@openzeppelin/contracts": "^4.9.6", + "@openzeppelin/contracts-upgradeable": "^4.9.6", "solidity-bytes-utils": "0.8.0" }, "devDependencies": { @@ -19,15 +19,15 @@ "@typescript-eslint/eslint-plugin": "^5.59.11", "chai": "^4.2.0", "coveralls": "^3.1.1", - "eslint-config-prettier": "^8.8.0", - "eslint-plugin-prettier": "^4.2.1", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", "eth-create2-calculator": "^1.1.5", "hardhat": "^2.13.1", "hardhat-packager": "^1.4.2", "npm-run-all": "^4.1.5", - "prettier": "^2.8.8", - "prettier-plugin-solidity": "^1.1.3", - "solhint": "^3.6.2", + "prettier": "^3.3.3", + "prettier-plugin-solidity": "^1.4.1", + "solhint": "^5.0.3", "standard-version": "^9.3.1", "ts-node": "^10.9.1" } @@ -2179,14 +2179,61 @@ } }, "node_modules/@openzeppelin/contracts": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.3.tgz", - "integrity": "sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg==" + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.6.tgz", + "integrity": "sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA==" }, "node_modules/@openzeppelin/contracts-upgradeable": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.3.tgz", - "integrity": "sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A==" + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.6.tgz", + "integrity": "sha512-m4iHazOsOCv1DgM7eD7GupTJ+NFVujRZt1wzddDPSVGpWdKq1SKkla5htKG7+IS4d2XOCtzkUNwRZ7Vq5aEUMA==" + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "dev": true, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dev": true, + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "dev": true, + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } }, "node_modules/@scure/base": { "version": "1.1.1", @@ -2332,6 +2379,18 @@ "node": ">=6" } }, + "node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@solidity-parser/parser": { "version": "0.14.3", "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.3.tgz", @@ -2342,6 +2401,18 @@ "antlr4ts": "^0.5.0-alpha.4" } }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, "node_modules/@truffle/hdwallet-provider": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/@truffle/hdwallet-provider/-/hdwallet-provider-2.0.13.tgz", @@ -2509,6 +2580,12 @@ "@types/node": "*" } }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", @@ -3119,7 +3196,8 @@ "version": "0.5.0-alpha.4", "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true + "dev": true, + "peer": true }, "node_modules/anymatch": { "version": "3.1.2", @@ -3638,6 +3716,33 @@ "node": ">= 0.8" } }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "dev": true, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -4088,6 +4193,16 @@ "typedarray": "^0.0.6" } }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "node_modules/conventional-changelog": { "version": "3.1.25", "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", @@ -4649,6 +4764,33 @@ "node": ">=0.10.0" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/deep-eql": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.0.tgz", @@ -4678,6 +4820,15 @@ "dev": true, "peer": true }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/define-properties": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", @@ -5212,9 +5363,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", - "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -5224,21 +5375,30 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", "dev": true, "dependencies": { - "prettier-linter-helpers": "^1.0.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" }, "engines": { - "node": ">=12.0.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" }, "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" }, "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, "eslint-config-prettier": { "optional": true } @@ -7173,6 +7333,15 @@ "node": ">= 0.12" } }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "dev": true, + "engines": { + "node": ">= 14.17" + } + }, "node_modules/fp-ts": { "version": "1.19.3", "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", @@ -7367,6 +7536,18 @@ "node": ">=4" } }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -7569,6 +7750,31 @@ "node": ">=8" } }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -8073,6 +8279,12 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -8120,6 +8332,31 @@ "npm": ">=1.3.7" } }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/http2-wrapper/node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -8682,6 +8919,12 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -8841,6 +9084,15 @@ "node": ">=10.0.0" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -8859,6 +9111,21 @@ "graceful-fs": "^4.1.9" } }, + "node_modules/latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "dev": true, + "dependencies": { + "package-json": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lcov-parse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", @@ -9103,6 +9370,18 @@ "get-func-name": "^2.0.0" } }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lru_map": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", @@ -9442,6 +9721,18 @@ "node": ">= 0.6" } }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", @@ -9918,6 +10209,18 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-url": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/npm-run-all": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", @@ -10050,6 +10353,15 @@ "node": ">=0.10.0" } }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "dev": true, + "engines": { + "node": ">=12.20" + } + }, "node_modules/p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", @@ -10098,6 +10410,36 @@ "node": ">=4" } }, + "node_modules/package-json": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "dev": true, + "dependencies": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -10281,15 +10623,15 @@ } }, "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" @@ -10308,51 +10650,32 @@ } }, "node_modules/prettier-plugin-solidity": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz", - "integrity": "sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.4.1.tgz", + "integrity": "sha512-Mq8EtfacVZ/0+uDKTtHZGW3Aa7vEbX/BNx63hmVg6YTiTXSiuKP0amj0G6pGwjmLaOfymWh3QgXEZkjQbU8QRg==", "dev": true, "dependencies": { - "@solidity-parser/parser": "^0.16.0", - "semver": "^7.3.8", - "solidity-comments-extractor": "^0.0.7" + "@solidity-parser/parser": "^0.18.0", + "semver": "^7.5.4" }, "engines": { - "node": ">=12" + "node": ">=16" }, "peerDependencies": { - "prettier": ">=2.3.0 || >=3.0.0-alpha.0" + "prettier": ">=2.3.0" } }, "node_modules/prettier-plugin-solidity/node_modules/@solidity-parser/parser": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.0.tgz", - "integrity": "sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q==", - "dev": true, - "dependencies": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", + "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", + "dev": true }, "node_modules/prettier-plugin-solidity/node_modules/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -10360,12 +10683,6 @@ "node": ">=10" } }, - "node_modules/prettier-plugin-solidity/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -10401,6 +10718,12 @@ "node": ">=0.10.0" } }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -10503,6 +10826,30 @@ "node": ">= 0.8" } }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -10673,6 +11020,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "dev": true, + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "dev": true, + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/req-cwd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", @@ -10767,6 +11141,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, "node_modules/resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", @@ -10774,7 +11154,22 @@ "dev": true, "peer": true, "engines": { - "node": ">=4" + "node": ">=4" + } + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dev": true, + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/reusify": { @@ -11214,14 +11609,14 @@ } }, "node_modules/solhint": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.6.2.tgz", - "integrity": "sha512-85EeLbmkcPwD+3JR7aEMKsVC9YrRSxd4qkXuMzrlf7+z2Eqdfm1wHWq1ffTuo5aDhoZxp2I9yF3QkxZOxOL7aQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/solhint/-/solhint-5.0.3.tgz", + "integrity": "sha512-OLCH6qm/mZTCpplTXzXTJGId1zrtNuDYP5c2e6snIv/hdRVxPfBBz/bAlL91bY/Accavkayp2Zp2BaDSrLVXTQ==", "dev": true, "dependencies": { - "@solidity-parser/parser": "^0.16.0", + "@solidity-parser/parser": "^0.18.0", "ajv": "^6.12.6", - "antlr4": "^4.11.0", + "antlr4": "^4.13.1-patch-1", "ast-parents": "^0.0.1", "chalk": "^4.1.2", "commander": "^10.0.0", @@ -11230,6 +11625,7 @@ "glob": "^8.0.3", "ignore": "^5.2.4", "js-yaml": "^4.1.0", + "latest-version": "^7.0.0", "lodash": "^4.17.21", "pluralize": "^8.0.0", "semver": "^7.5.2", @@ -11245,13 +11641,10 @@ } }, "node_modules/solhint/node_modules/@solidity-parser/parser": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.1.tgz", - "integrity": "sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==", - "dev": true, - "dependencies": { - "antlr4ts": "^0.5.0-alpha.4" - } + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", + "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", + "dev": true }, "node_modules/solhint/node_modules/ansi-regex": { "version": "5.0.1", @@ -11390,6 +11783,22 @@ "node": ">=10" } }, + "node_modules/solhint/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "optional": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/solhint/node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -11443,12 +11852,6 @@ "@truffle/hdwallet-provider": "latest" } }, - "node_modules/solidity-comments-extractor": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", - "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", - "dev": true - }, "node_modules/solidity-coverage": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.5.tgz", @@ -12015,6 +12418,28 @@ "get-port": "^3.1.0" } }, + "node_modules/synckit": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/synckit/node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "dev": true + }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", @@ -12651,6 +13076,21 @@ "node": ">=10" } }, + "node_modules/typechain/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -14894,14 +15334,46 @@ } }, "@openzeppelin/contracts": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.3.tgz", - "integrity": "sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg==" + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.6.tgz", + "integrity": "sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA==" }, "@openzeppelin/contracts-upgradeable": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.3.tgz", - "integrity": "sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A==" + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.6.tgz", + "integrity": "sha512-m4iHazOsOCv1DgM7eD7GupTJ+NFVujRZt1wzddDPSVGpWdKq1SKkla5htKG7+IS4d2XOCtzkUNwRZ7Vq5aEUMA==" + }, + "@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true + }, + "@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "dev": true + }, + "@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dev": true, + "requires": { + "graceful-fs": "4.2.10" + } + }, + "@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "dev": true, + "requires": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + } }, "@scure/base": { "version": "1.1.1", @@ -15008,6 +15480,12 @@ "tslib": "^1.9.3" } }, + "@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "dev": true + }, "@solidity-parser/parser": { "version": "0.14.3", "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.3.tgz", @@ -15018,6 +15496,15 @@ "antlr4ts": "^0.5.0-alpha.4" } }, + "@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dev": true, + "requires": { + "defer-to-connect": "^2.0.1" + } + }, "@truffle/hdwallet-provider": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/@truffle/hdwallet-provider/-/hdwallet-provider-2.0.13.tgz", @@ -15163,6 +15650,12 @@ "@types/node": "*" } }, + "@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true + }, "@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", @@ -15605,7 +16098,8 @@ "version": "0.5.0-alpha.4", "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true + "dev": true, + "peer": true }, "anymatch": { "version": "3.1.2", @@ -16018,6 +16512,27 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true }, + "cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "dev": true + }, + "cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "dev": true, + "requires": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + } + }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -16363,6 +16878,16 @@ "typedarray": "^0.0.6" } }, + "config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "conventional-changelog": { "version": "3.1.25", "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", @@ -16794,6 +17319,23 @@ } } }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "requires": { + "mimic-response": "^3.1.0" + }, + "dependencies": { + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + } + } + }, "deep-eql": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.0.tgz", @@ -16817,6 +17359,12 @@ "dev": true, "peer": true }, + "defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true + }, "define-properties": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", @@ -17504,19 +18052,20 @@ } }, "eslint-config-prettier": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", - "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, "requires": {} }, "eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", "dev": true, "requires": { - "prettier-linter-helpers": "^1.0.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" } }, "eslint-scope": { @@ -18946,6 +19495,12 @@ "mime-types": "^2.1.12" } }, + "form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "dev": true + }, "fp-ts": { "version": "1.19.3", "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", @@ -19102,6 +19657,12 @@ "dev": true, "peer": true }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, "get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -19258,6 +19819,25 @@ "slash": "^3.0.0" } }, + "got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "dev": true, + "requires": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -19664,6 +20244,12 @@ } } }, + "http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -19706,6 +20292,24 @@ "sshpk": "^1.7.0" } }, + "http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dev": true, + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "dependencies": { + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + } + } + }, "https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -20093,6 +20697,12 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "peer": true }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -20223,6 +20833,15 @@ "readable-stream": "^3.6.0" } }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -20238,6 +20857,15 @@ "graceful-fs": "^4.1.9" } }, + "latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "dev": true, + "requires": { + "package-json": "^8.1.0" + } + }, "lcov-parse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", @@ -20428,6 +21056,12 @@ "get-func-name": "^2.0.0" } }, + "lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "dev": true + }, "lru_map": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", @@ -20686,6 +21320,12 @@ "mime-db": "1.52.0" } }, + "mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "dev": true + }, "min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", @@ -21043,6 +21683,12 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "normalize-url": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "dev": true + }, "npm-run-all": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", @@ -21147,6 +21793,12 @@ "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true }, + "p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "dev": true + }, "p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", @@ -21180,6 +21832,26 @@ "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "dev": true }, + "package-json": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "dev": true, + "requires": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + }, + "dependencies": { + "semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true + } + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -21314,9 +21986,9 @@ "peer": true }, "prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true }, "prettier-linter-helpers": { @@ -21329,47 +22001,25 @@ } }, "prettier-plugin-solidity": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz", - "integrity": "sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.4.1.tgz", + "integrity": "sha512-Mq8EtfacVZ/0+uDKTtHZGW3Aa7vEbX/BNx63hmVg6YTiTXSiuKP0amj0G6pGwjmLaOfymWh3QgXEZkjQbU8QRg==", "dev": true, "requires": { - "@solidity-parser/parser": "^0.16.0", - "semver": "^7.3.8", - "solidity-comments-extractor": "^0.0.7" + "@solidity-parser/parser": "^0.18.0", + "semver": "^7.5.4" }, "dependencies": { "@solidity-parser/parser": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.0.tgz", - "integrity": "sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q==", - "dev": true, - "requires": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", + "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", + "dev": true }, "semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true } } @@ -21403,6 +22053,12 @@ "set-immediate-shim": "^1.0.1" } }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -21472,6 +22128,26 @@ "unpipe": "1.0.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true + } + } + }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -21605,6 +22281,24 @@ "functions-have-names": "^1.2.2" } }, + "registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "dev": true, + "requires": { + "@pnpm/npm-conf": "^2.1.0" + } + }, + "registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "dev": true, + "requires": { + "rc": "1.2.8" + } + }, "req-cwd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", @@ -21678,6 +22372,12 @@ "path-parse": "^1.0.6" } }, + "resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", @@ -21685,6 +22385,15 @@ "dev": true, "peer": true }, + "responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dev": true, + "requires": { + "lowercase-keys": "^3.0.0" + } + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -21999,14 +22708,14 @@ } }, "solhint": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.6.2.tgz", - "integrity": "sha512-85EeLbmkcPwD+3JR7aEMKsVC9YrRSxd4qkXuMzrlf7+z2Eqdfm1wHWq1ffTuo5aDhoZxp2I9yF3QkxZOxOL7aQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/solhint/-/solhint-5.0.3.tgz", + "integrity": "sha512-OLCH6qm/mZTCpplTXzXTJGId1zrtNuDYP5c2e6snIv/hdRVxPfBBz/bAlL91bY/Accavkayp2Zp2BaDSrLVXTQ==", "dev": true, "requires": { - "@solidity-parser/parser": "^0.16.0", + "@solidity-parser/parser": "^0.18.0", "ajv": "^6.12.6", - "antlr4": "^4.11.0", + "antlr4": "^4.13.1-patch-1", "ast-parents": "^0.0.1", "chalk": "^4.1.2", "commander": "^10.0.0", @@ -22015,6 +22724,7 @@ "glob": "^8.0.3", "ignore": "^5.2.4", "js-yaml": "^4.1.0", + "latest-version": "^7.0.0", "lodash": "^4.17.21", "pluralize": "^8.0.0", "prettier": "^2.8.3", @@ -22025,13 +22735,10 @@ }, "dependencies": { "@solidity-parser/parser": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.1.tgz", - "integrity": "sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==", - "dev": true, - "requires": { - "antlr4ts": "^0.5.0-alpha.4" - } + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", + "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", + "dev": true }, "ansi-regex": { "version": "5.0.1", @@ -22134,6 +22841,13 @@ "brace-expansion": "^2.0.1" } }, + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "optional": true + }, "semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -22177,12 +22891,6 @@ "@truffle/hdwallet-provider": "latest" } }, - "solidity-comments-extractor": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", - "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", - "dev": true - }, "solidity-coverage": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.5.tgz", @@ -22627,6 +23335,24 @@ "get-port": "^3.1.0" } }, + "synckit": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", + "dev": true, + "requires": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "dev": true + } + } + }, "table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", @@ -23105,6 +23831,12 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true + }, + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true } } }, diff --git a/implementations/package.json b/implementations/package.json index 5f58a3f2..0aa05c48 100644 --- a/implementations/package.json +++ b/implementations/package.json @@ -34,8 +34,8 @@ "author": "Fabian Vogelsteller ", "license": "Apache-2.0", "dependencies": { - "@openzeppelin/contracts": "^4.9.3", - "@openzeppelin/contracts-upgradeable": "^4.9.3", + "@openzeppelin/contracts": "^4.9.6", + "@openzeppelin/contracts-upgradeable": "^4.9.6", "solidity-bytes-utils": "0.8.0" }, "devDependencies": { @@ -44,15 +44,15 @@ "@typescript-eslint/eslint-plugin": "^5.59.11", "chai": "^4.2.0", "coveralls": "^3.1.1", - "eslint-config-prettier": "^8.8.0", - "eslint-plugin-prettier": "^4.2.1", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", "eth-create2-calculator": "^1.1.5", "hardhat": "^2.13.1", "hardhat-packager": "^1.4.2", "npm-run-all": "^4.1.5", - "prettier": "^2.8.8", - "prettier-plugin-solidity": "^1.1.3", - "solhint": "^3.6.2", + "prettier": "^3.3.3", + "prettier-plugin-solidity": "^1.4.1", + "solhint": "^5.0.3", "standard-version": "^9.3.1", "ts-node": "^10.9.1" } diff --git a/implementations/test/ERC725.test.ts b/implementations/test/ERC725.test.ts index 70a12f66..6e92537a 100644 --- a/implementations/test/ERC725.test.ts +++ b/implementations/test/ERC725.test.ts @@ -64,6 +64,22 @@ describe('ERC725', () => { expect(await ethers.provider.getBalance(contract.address)).to.equal(deployParams.funding); }); + + it('should have registered the ERC725X & ERC725Y interfaces', async () => { + const accounts = await ethers.getSigners(); + + const deployParams = { + newOwner: accounts[0].address, + funding: ethers.utils.parseEther('10'), + }; + + const contract = await new ERC725__factory(accounts[0]).deploy(deployParams.newOwner, { + value: deployParams.funding, + }); + + expect(await contract.supportsInterface(INTERFACE_ID.ERC725X)).to.be.true; + expect(await contract.supportsInterface(INTERFACE_ID.ERC725X)).to.be.true; + }); }); }); @@ -105,7 +121,11 @@ describe('ERC725', () => { }); it('should have registered the ERC725X interface', async () => { - expect(await context.erc725.supportsInterface(INTERFACE_ID.ERC725X)); + expect(await context.erc725.supportsInterface(INTERFACE_ID.ERC725X)).to.be.true; + }); + + it('should have registered the ERC725Y interface', async () => { + expect(await context.erc725.supportsInterface(INTERFACE_ID.ERC725Y)).to.be.true; }); it('should revert when initializing with address(0) as owner', async () => { diff --git a/implementations/test/ERC725X.behaviour.ts b/implementations/test/ERC725X.behaviour.ts index cc25c947..a217b24b 100644 --- a/implementations/test/ERC725X.behaviour.ts +++ b/implementations/test/ERC725X.behaviour.ts @@ -124,7 +124,7 @@ export const shouldBehaveLikeERC725X = (buildContext: () => Promise Promise Promise { await expect( context.erc725X.connect(context.accounts.anyone).renounceOwnership(), - ).to.be.revertedWithCustomError(context.erc725X, 'OwnableCallerNotTheOwner'); + ).to.be.revertedWith('Ownable: caller is not the owner'); }); }); }); @@ -204,7 +204,7 @@ export const shouldBehaveLikeERC725X = (buildContext: () => Promise Promise { - expect(await context.erc725X.supportsInterface(INTERFACE_ID.ERC725X)); + expect(await context.erc725X.supportsInterface(INTERFACE_ID.ERC725X)).to.be.true; }); it('should have set the correct owner', async () => { diff --git a/implementations/test/ERC725Y.behaviour.ts b/implementations/test/ERC725Y.behaviour.ts index c2cd0495..c97abe34 100644 --- a/implementations/test/ERC725Y.behaviour.ts +++ b/implementations/test/ERC725Y.behaviour.ts @@ -7,9 +7,12 @@ import { AddressZero } from '@ethersproject/constants'; import type { TransactionResponse } from '@ethersproject/abstract-provider'; // types -import { ERC725Y, ERC725YWriter__factory, ERC725YReader__factory } from '../types'; - -import { bytecode as ERC725Bytecode } from '../artifacts/contracts/ERC725.sol/ERC725.json'; +import { + ERC725Y, + ERC725Y__factory, + ERC725YWriter__factory, + ERC725YReader__factory, +} from '../types'; // constants import { INTERFACE_ID } from '../constants'; @@ -70,7 +73,7 @@ export const shouldBehaveLikeERC725Y = (buildContext: () => Promise Promise Promise { await expect( context.erc725Y.connect(context.accounts.anyone).renounceOwnership(), - ).to.be.revertedWithCustomError(context.erc725Y, 'OwnableCallerNotTheOwner'); + ).to.be.revertedWith('Ownable: caller is not the owner'); }); }); }); @@ -173,7 +176,7 @@ export const shouldBehaveLikeERC725Y = (buildContext: () => Promise Promise { const txParams = { dataKey: ethers.utils.solidityKeccak256(['string'], ['BytecodeOfMyFavoriteContract']), - dataValue: ERC725Bytecode, + dataValue: ERC725Y__factory.bytecode, }; await expect( @@ -385,7 +388,7 @@ export const shouldBehaveLikeERC725Y = (buildContext: () => Promise Promise { const txParams = { dataKey: ethers.utils.solidityKeccak256(['string'], ['BytecodeOfMyFavoriteContract']), - dataValue: ERC725Bytecode, + dataValue: ERC725Y__factory.bytecode, }; await expect( @@ -651,7 +654,7 @@ export const shouldBehaveLikeERC725Y = (buildContext: () => Promise { txParams = { dataKey: ethers.utils.solidityKeccak256(['string'], ['FirstDataKey']), - dataValue: ERC725Bytecode, + dataValue: ERC725Y__factory.bytecode, }; await context.erc725Y @@ -759,7 +762,7 @@ export const shouldBehaveLikeERC725Y = (buildContext: () => Promise { txParams = { dataKey: ethers.utils.solidityKeccak256(['string'], ['FirstDataKey']), - dataValue: ERC725Bytecode, + dataValue: ERC725Y__factory.bytecode, }; await context.erc725Y @@ -837,7 +840,7 @@ export const shouldInitializeLikeERC725Y = ( }); it('should have registered the ERC725Y interface', async () => { - expect(await context.erc725Y.supportsInterface(INTERFACE_ID.ERC725Y)); + expect(await context.erc725Y.supportsInterface(INTERFACE_ID.ERC725Y)).to.be.true; }); }); };