From dd7a0dc07871ca3812f9f6a0d9cc40e8ec05dba0 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 17 Apr 2023 11:24:48 +0200 Subject: [PATCH 001/112] feat: protect the DAO executor against reentrancy --- packages/contracts/CHANGELOG.md | 1 + packages/contracts/src/core/dao/DAO.sol | 5 +++- packages/contracts/test/core/dao/dao.ts | 34 +++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/packages/contracts/CHANGELOG.md b/packages/contracts/CHANGELOG.md index c8bad728e..571407b04 100644 --- a/packages/contracts/CHANGELOG.md +++ b/packages/contracts/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added `allowFailureMap` to `IDAO.Executed` event. +- Added OZ's `nonReentrant` modifier to the `execute` function in the `DAO` contract. ## v1.2.0 diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index a22784de6..7cb4c4568 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -12,6 +12,7 @@ import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.so import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts/interfaces/IERC1271.sol"; +import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import {PermissionManager} from "../permission/PermissionManager.sol"; import {CallbackHandler} from "../utils/CallbackHandler.sol"; @@ -31,7 +32,8 @@ contract DAO is IDAO, UUPSUpgradeable, PermissionManager, - CallbackHandler + CallbackHandler, + ReentrancyGuardUpgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; using AddressUpgradeable for address; @@ -175,6 +177,7 @@ contract DAO is ) external override + nonReentrant auth(EXECUTE_PERMISSION_ID) returns (bytes[] memory execResults, uint256 failureMap) { diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index bf3c87485..08e581786 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -289,6 +289,34 @@ describe('DAO', function () { .withArgs(0); }); + it('reverts on re-entrant actions', async () => { + // Grant DAO execute permission on itself. + await dao.grant( + dao.address, + dao.address, + PERMISSION_IDS.EXECUTE_PERMISSION_ID + ); + + // Create a reentrant action calling `dao.execute` again. + const reentrantAction = { + to: dao.address, + data: dao.interface.encodeFunctionData('execute', [ + ZERO_BYTES32, + [data.succeedAction], + 0, + ]), + value: 0, + }; + + // Create an action array with an normal action and an reentrant action. + const actions = [data.succeedAction, reentrantAction]; + + // Expect the second, reentrant action to fail. + await expect(dao.execute(ZERO_BYTES32, actions, 0)) + .to.be.revertedWithCustomError(dao, 'ActionFailed') + .withArgs(1); + }); + it('succeeds if action is failable but allowFailureMap allows it', async () => { let num = ethers.BigNumber.from(0); num = flipBit(0, num); @@ -393,12 +421,14 @@ describe('DAO', function () { ZERO_BYTES32, [gasConsumingAction], allowFailureMap - ); // exact gas required: 495453 + ); // expectedGas = 520720 gas + + console.log(expectedGas.toNumber()); // Providing less gas causes the `to.call` of the `gasConsumingAction` to fail, but is still enough for the overall `dao.execute` call to finish successfully. await expect( dao.execute(ZERO_BYTES32, [gasConsumingAction], allowFailureMap, { - gasLimit: expectedGas.sub(800), + gasLimit: expectedGas.sub(2800), // 2796 gas is the limit value for which the call cannot finish successfully anymore (520720 gas - 2796 gas = 517924 gas) }) ).to.be.revertedWithCustomError(dao, 'InsufficientGas'); From ad2fd40d2679dacdecd1bc05a767ca835f3a06c6 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 17 Apr 2023 12:01:43 +0200 Subject: [PATCH 002/112] fix: remove console.log --- packages/contracts/test/core/dao/dao.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 08e581786..428e93d8f 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -423,8 +423,6 @@ describe('DAO', function () { allowFailureMap ); // expectedGas = 520720 gas - console.log(expectedGas.toNumber()); - // Providing less gas causes the `to.call` of the `gasConsumingAction` to fail, but is still enough for the overall `dao.execute` call to finish successfully. await expect( dao.execute(ZERO_BYTES32, [gasConsumingAction], allowFailureMap, { From 616b8bfdad51180c8dbf44b91667c603ed9f9c50 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 17 Apr 2023 22:22:16 +0200 Subject: [PATCH 003/112] fix: prevent storage corruption --- packages/contracts/src/core/dao/DAO.sol | 29 ++++++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 7cb4c4568..686c72cf0 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -12,7 +12,6 @@ import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.so import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts/interfaces/IERC1271.sol"; -import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import {PermissionManager} from "../permission/PermissionManager.sol"; import {CallbackHandler} from "../utils/CallbackHandler.sol"; @@ -32,8 +31,7 @@ contract DAO is IDAO, UUPSUpgradeable, PermissionManager, - CallbackHandler, - ReentrancyGuardUpgradeable + CallbackHandler { using SafeERC20Upgradeable for IERC20Upgradeable; using AddressUpgradeable for address; @@ -62,15 +60,24 @@ contract DAO is /// @notice The internal constant storing the maximal action array length. uint256 internal constant MAX_ACTIONS = 256; + uint256 private constant _NOT_ENTERED = 1; + uint256 private constant _ENTERED = 2; + /// @notice The [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. IERC1271 public signatureValidator; /// @notice The address of the trusted forwarder verifying meta transactions. address private trustedForwarder; - /// @notice The [EIP-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO uri. + /// @notice The [EIP-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO URI. string private _daoURI; + /// @notice The state variable for the reentrancy guard of the `execute` function. + uint256 private _reentrancyStatus; + + /// @notice Thrown if a call is re-entrant. + error ReentrantCall(); + /// @notice Thrown if the action array length is larger than `MAX_ACTIONS`. error TooManyActions(); @@ -112,6 +119,8 @@ contract DAO is address _trustedForwarder, string calldata daoURI_ ) external initializer { + _reentrancyStatus = _NOT_ENTERED; + _registerInterface(type(IDAO).interfaceId); _registerInterface(type(IERC1271).interfaceId); _registerInterface(type(IEIP4824).interfaceId); @@ -177,10 +186,16 @@ contract DAO is ) external override - nonReentrant auth(EXECUTE_PERMISSION_ID) returns (bytes[] memory execResults, uint256 failureMap) { + // Protect against reentrancy. + if (_reentrancyStatus == _ENTERED) { + revert ReentrantCall(); + } + _reentrancyStatus = _ENTERED; + + // Check action array length. if (_actions.length > MAX_ACTIONS) { revert TooManyActions(); } @@ -234,6 +249,8 @@ contract DAO is failureMap: failureMap, execResults: execResults }); + + _reentrancyStatus = _NOT_ENTERED; } /// @inheritdoc IDAO @@ -358,5 +375,5 @@ contract DAO is } /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). - uint256[47] private __gap; + uint256[46] private __gap; } From e45854c4d1acf2209437443e991e23278c25f8b3 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Tue, 18 Apr 2023 17:37:34 +0200 Subject: [PATCH 004/112] feat: refactored reentrancy guard into a modifier --- packages/contracts/CHANGELOG.md | 2 +- packages/contracts/src/core/dao/DAO.sol | 27 ++++++++++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/packages/contracts/CHANGELOG.md b/packages/contracts/CHANGELOG.md index 571407b04..23613aa8e 100644 --- a/packages/contracts/CHANGELOG.md +++ b/packages/contracts/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added `allowFailureMap` to `IDAO.Executed` event. -- Added OZ's `nonReentrant` modifier to the `execute` function in the `DAO` contract. +- Added a `nonReentrant` modifier to the `execute` function in the `DAO` contract. ## v1.2.0 diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 686c72cf0..98beb9150 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -75,7 +75,7 @@ contract DAO is /// @notice The state variable for the reentrancy guard of the `execute` function. uint256 private _reentrancyStatus; - /// @notice Thrown if a call is re-entrant. + /// @notice Thrown if a call is reentrant. error ReentrantCall(); /// @notice Thrown if the action array length is larger than `MAX_ACTIONS`. @@ -100,6 +100,19 @@ contract DAO is /// @param daoURI The new uri. event NewURI(string daoURI); + /// @notice A modifier to protect the `execute()` function against reentrancy. + /// @dev If this is used multiple times, private `_beforeNonReentrant()` and `_afterNonReentrant()` functions should be created to prevent code duplication. + modifier nonReentrant() { + if (_reentrancyStatus == _ENTERED) { + revert ReentrantCall(); + } + _reentrancyStatus = _ENTERED; + + _; + + _reentrancyStatus = _NOT_ENTERED; + } + /// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized. constructor() { _disableInitializers(); @@ -186,16 +199,11 @@ contract DAO is ) external override + nonReentrant auth(EXECUTE_PERMISSION_ID) returns (bytes[] memory execResults, uint256 failureMap) { - // Protect against reentrancy. - if (_reentrancyStatus == _ENTERED) { - revert ReentrantCall(); - } - _reentrancyStatus = _ENTERED; - - // Check action array length. + // Check that the action array length is within bounds. if (_actions.length > MAX_ACTIONS) { revert TooManyActions(); } @@ -205,6 +213,7 @@ contract DAO is uint256 gasBefore; uint256 gasAfter; + // for (uint256 i = 0; i < _actions.length; ) { gasBefore = gasleft(); @@ -249,8 +258,6 @@ contract DAO is failureMap: failureMap, execResults: execResults }); - - _reentrancyStatus = _NOT_ENTERED; } /// @inheritdoc IDAO From 2ac2262a70217a061ba2e87a0412310353a0a979 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Tue, 18 Apr 2023 17:36:54 +0200 Subject: [PATCH 005/112] feat: added tests and preliminary versioning --- packages/contracts/src/core/dao/DAO.sol | 2 +- packages/contracts/src/core/dao/IDAO.sol | 2 +- .../core/dao/previous_versions/DAO_v1_0_0.sol | 340 ++++++++++++++++++ .../dao/previous_versions/IDAO_v1_0_0.sol | 136 +++++++ packages/contracts/test/core/dao/dao.ts | 57 ++- .../core/permission/permission-manager.ts | 2 +- .../contracts/test/deploy/managing-dao.ts | 41 +-- .../utils/ens/ens-subdomain-registry.ts | 2 +- .../test/plugins/governance/admin/admin.ts | 2 +- .../addresslist/addresslist-voting.ts | 2 +- .../majority-voting/majority-voting.ts | 2 +- .../majority-voting/token/token-voting.ts | 2 +- .../plugins/governance/multisig/multisig.ts | 2 +- .../test-utils/{error.ts => oz-constants.ts} | 3 + .../test/test-utils/uups-upgradeable.ts | 12 + .../test/token/erc20/governance-erc20.ts | 2 +- .../token/erc20/governance-wrapped-erc20.ts | 2 +- packages/contracts/test/upgrade/dao.ts | 77 ++++ packages/contracts/utils/event.ts | 15 + packages/contracts/utils/storage.ts | 26 ++ 20 files changed, 682 insertions(+), 47 deletions(-) create mode 100644 packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol create mode 100644 packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol rename packages/contracts/test/test-utils/{error.ts => oz-constants.ts} (60%) create mode 100644 packages/contracts/test/upgrade/dao.ts create mode 100644 packages/contracts/utils/storage.ts diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 98beb9150..ea5b98b84 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -19,7 +19,7 @@ import {hasBit, flipBit} from "../utils/BitMap.sol"; import {IEIP4824} from "./IEIP4824.sol"; import {IDAO} from "./IDAO.sol"; -/// @title DAO +/// @title DAO v1.1.0 /// @author Aragon Association - 2021-2023 /// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. /// @dev Public API of the Aragon DAO framework. diff --git a/packages/contracts/src/core/dao/IDAO.sol b/packages/contracts/src/core/dao/IDAO.sol index 099d7a1e8..89aed6799 100644 --- a/packages/contracts/src/core/dao/IDAO.sol +++ b/packages/contracts/src/core/dao/IDAO.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.17; -/// @title IDAO +/// @title IDAO v1.1.0 /// @author Aragon Association - 2022-2023 /// @notice The interface required for DAOs within the Aragon App DAO framework. interface IDAO { diff --git a/packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol b/packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol new file mode 100644 index 000000000..77c55af71 --- /dev/null +++ b/packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.17; + +import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165StorageUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; +import "@openzeppelin/contracts/interfaces/IERC1271.sol"; + +import {PermissionManager} from "../../permission/PermissionManager.sol"; +import {CallbackHandler} from "../../utils/CallbackHandler.sol"; +import {hasBit, flipBit} from "../../utils/BitMap.sol"; +import {IEIP4824} from "../IEIP4824.sol"; +import {IDAO_v1_0_0} from "./IDAO_v1_0_0.sol"; + +/// @title DAO v1.0.0 +/// @author Aragon Association - 2021-2023 +/// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. +/// @dev Public API of the Aragon DAO framework. +contract DAO_v1_0_0 is + IEIP4824, + Initializable, + IERC1271, + ERC165StorageUpgradeable, + IDAO_v1_0_0, + UUPSUpgradeable, + PermissionManager, + CallbackHandler +{ + using SafeERC20Upgradeable for IERC20Upgradeable; + using AddressUpgradeable for address; + + /// @notice The ID of the permission required to call the `execute` function. + bytes32 public constant EXECUTE_PERMISSION_ID = keccak256("EXECUTE_PERMISSION"); + + /// @notice The ID of the permission required to call the `_authorizeUpgrade` function. + bytes32 public constant UPGRADE_DAO_PERMISSION_ID = keccak256("UPGRADE_DAO_PERMISSION"); + + /// @notice The ID of the permission required to call the `setMetadata` function. + bytes32 public constant SET_METADATA_PERMISSION_ID = keccak256("SET_METADATA_PERMISSION"); + + /// @notice The ID of the permission required to call the `setTrustedForwarder` function. + bytes32 public constant SET_TRUSTED_FORWARDER_PERMISSION_ID = + keccak256("SET_TRUSTED_FORWARDER_PERMISSION"); + + /// @notice The ID of the permission required to call the `setSignatureValidator` function. + bytes32 public constant SET_SIGNATURE_VALIDATOR_PERMISSION_ID = + keccak256("SET_SIGNATURE_VALIDATOR_PERMISSION"); + + /// @notice The ID of the permission required to call the `registerStandardCallback` function. + bytes32 public constant REGISTER_STANDARD_CALLBACK_PERMISSION_ID = + keccak256("REGISTER_STANDARD_CALLBACK_PERMISSION"); + + /// @notice The internal constant storing the maximal action array length. + uint256 internal constant MAX_ACTIONS = 256; + + /// @notice The [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. + IERC1271 public signatureValidator; + + /// @notice The address of the trusted forwarder verifying meta transactions. + address private trustedForwarder; + + /// @notice The [EIP-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO uri. + string private _daoURI; + + /// @notice Thrown if the action array length is larger than `MAX_ACTIONS`. + error TooManyActions(); + + /// @notice Thrown if action execution has failed. + /// @param index The index of the action in the action array that failed. + error ActionFailed(uint256 index); + + /// @notice Thrown if the deposit amount is zero. + error ZeroAmount(); + + /// @notice Thrown if there is a mismatch between the expected and actually deposited amount of native tokens. + /// @param expected The expected native token amount. + /// @param actual The actual native token amount deposited. + error NativeTokenDepositAmountMismatch(uint256 expected, uint256 actual); + + /// @notice Emitted when a new DAO uri is set. + /// @param daoURI The new uri. + event NewURI(string daoURI); + + /// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized. + constructor() { + _disableInitializers(); + } + + /// @notice Initializes the DAO by + /// - registering the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID + /// - setting the trusted forwarder for meta transactions + /// - giving the `ROOT_PERMISSION_ID` permission to the initial owner (that should be revoked and transferred to the DAO after setup). + /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). + /// @param _metadata IPFS hash that points to all the metadata (logo, description, tags, etc.) of a DAO. + /// @param _initialOwner The initial owner of the DAO having the `ROOT_PERMISSION_ID` permission. + /// @param _trustedForwarder The trusted forwarder responsible for verifying meta transactions. + function initialize( + bytes calldata _metadata, + address _initialOwner, + address _trustedForwarder, + string calldata daoURI_ + ) external initializer { + _registerInterface(type(IDAO_v1_0_0).interfaceId); + _registerInterface(type(IERC1271).interfaceId); + _registerInterface(type(IEIP4824).interfaceId); + _registerTokenInterfaces(); + + _setMetadata(_metadata); + _setTrustedForwarder(_trustedForwarder); + _setDaoURI(daoURI_); + __PermissionManager_init(_initialOwner); + } + + /// @inheritdoc PermissionManager + function isPermissionRestrictedForAnyAddr( + bytes32 _permissionId + ) internal pure override returns (bool) { + return + _permissionId == EXECUTE_PERMISSION_ID || + _permissionId == UPGRADE_DAO_PERMISSION_ID || + _permissionId == SET_METADATA_PERMISSION_ID || + _permissionId == SET_TRUSTED_FORWARDER_PERMISSION_ID || + _permissionId == SET_SIGNATURE_VALIDATOR_PERMISSION_ID || + _permissionId == REGISTER_STANDARD_CALLBACK_PERMISSION_ID; + } + + /// @notice Internal method authorizing the upgrade of the contract via the [upgradeabilty mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). + /// @dev The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. + function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {} + + /// @inheritdoc IDAO_v1_0_0 + function setTrustedForwarder( + address _newTrustedForwarder + ) external override auth(SET_TRUSTED_FORWARDER_PERMISSION_ID) { + _setTrustedForwarder(_newTrustedForwarder); + } + + /// @inheritdoc IDAO_v1_0_0 + function getTrustedForwarder() external view virtual override returns (address) { + return trustedForwarder; + } + + /// @inheritdoc IDAO_v1_0_0 + function hasPermission( + address _where, + address _who, + bytes32 _permissionId, + bytes memory _data + ) external view override returns (bool) { + return isGranted(_where, _who, _permissionId, _data); + } + + /// @inheritdoc IDAO_v1_0_0 + function setMetadata( + bytes calldata _metadata + ) external override auth(SET_METADATA_PERMISSION_ID) { + _setMetadata(_metadata); + } + + /// @inheritdoc IDAO_v1_0_0 + function execute( + bytes32 _callId, + Action[] calldata _actions, + uint256 _allowFailureMap + ) + external + override + auth(EXECUTE_PERMISSION_ID) + returns (bytes[] memory execResults, uint256 failureMap) + { + if (_actions.length > MAX_ACTIONS) { + revert TooManyActions(); + } + + execResults = new bytes[](_actions.length); + + for (uint256 i = 0; i < _actions.length; ) { + address to = _actions[i].to; + (bool success, bytes memory response) = to.call{value: _actions[i].value}( + _actions[i].data + ); + + if (!success) { + // If the call failed and wasn't allowed in allowFailureMap, revert. + if (!hasBit(_allowFailureMap, uint8(i))) { + revert ActionFailed(i); + } + + // If the call failed, but was allowed in allowFailureMap, store that + // this specific action has actually failed. + failureMap = flipBit(failureMap, uint8(i)); + } + + execResults[i] = response; + + unchecked { + ++i; + } + } + + emit Executed({ + actor: msg.sender, + callId: _callId, + actions: _actions, + failureMap: failureMap, + execResults: execResults + }); + } + + /// @inheritdoc IDAO_v1_0_0 + function deposit( + address _token, + uint256 _amount, + string calldata _reference + ) external payable override { + if (_amount == 0) revert ZeroAmount(); + + if (_token == address(0)) { + if (msg.value != _amount) + revert NativeTokenDepositAmountMismatch({expected: _amount, actual: msg.value}); + } else { + if (msg.value != 0) + revert NativeTokenDepositAmountMismatch({expected: 0, actual: msg.value}); + + IERC20Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _amount); + } + + emit Deposited(msg.sender, _token, _amount, _reference); + } + + /// @inheritdoc IDAO_v1_0_0 + function setSignatureValidator( + address _signatureValidator + ) external override auth(SET_SIGNATURE_VALIDATOR_PERMISSION_ID) { + signatureValidator = IERC1271(_signatureValidator); + + emit SignatureValidatorSet({signatureValidator: _signatureValidator}); + } + + /// @inheritdoc IDAO_v1_0_0 + function isValidSignature( + bytes32 _hash, + bytes memory _signature + ) external view override(IDAO_v1_0_0, IERC1271) returns (bytes4) { + if (address(signatureValidator) == address(0)) { + // Return the invalid magic number + return bytes4(0); + } + // Forward the call to the set signature validator contract + return signatureValidator.isValidSignature(_hash, _signature); + } + + /// @notice Emits the `NativeTokenDeposited` event to track native token deposits that weren't made via the deposit method. + /// @dev This call is bound by the gas limitations for `send`/`transfer` calls introduced by EIP-2929. + /// Gas cost increases in future hard forks might break this function. As an alternative, EIP-2930-type transactions using access lists can be employed. + receive() external payable { + emit NativeTokenDeposited(msg.sender, msg.value); + } + + /// @notice Fallback to handle future versions of the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) standard. + /// @param _input An alias being equivalent to `msg.data`. This feature of the fallback function was introduced with the [solidity compiler version 0.7.6](https://github.com/ethereum/solidity/releases/tag/v0.7.6) + /// @return The magic number registered for the function selector triggering the fallback. + fallback(bytes calldata _input) external returns (bytes memory) { + bytes4 magicNumber = _handleCallback(msg.sig, _input); + return abi.encode(magicNumber); + } + + /// @notice Emits the MetadataSet event if new metadata is set. + /// @param _metadata Hash of the IPFS metadata object. + function _setMetadata(bytes calldata _metadata) internal { + emit MetadataSet(_metadata); + } + + /// @notice Sets the trusted forwarder on the DAO and emits the associated event. + /// @param _trustedForwarder The trusted forwarder address. + function _setTrustedForwarder(address _trustedForwarder) internal { + trustedForwarder = _trustedForwarder; + + emit TrustedForwarderSet(_trustedForwarder); + } + + /// @notice Registers the ERC721/ERC1155 interfaces and callbacks. + function _registerTokenInterfaces() private { + _registerInterface(type(IERC721ReceiverUpgradeable).interfaceId); + _registerInterface(type(IERC1155ReceiverUpgradeable).interfaceId); + + _registerCallback( + IERC721ReceiverUpgradeable.onERC721Received.selector, + IERC721ReceiverUpgradeable.onERC721Received.selector + ); + _registerCallback( + IERC1155ReceiverUpgradeable.onERC1155Received.selector, + IERC1155ReceiverUpgradeable.onERC1155Received.selector + ); + _registerCallback( + IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector, + IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector + ); + } + + /// @inheritdoc IDAO_v1_0_0 + function registerStandardCallback( + bytes4 _interfaceId, + bytes4 _callbackSelector, + bytes4 _magicNumber + ) external override auth(REGISTER_STANDARD_CALLBACK_PERMISSION_ID) { + _registerInterface(_interfaceId); + _registerCallback(_callbackSelector, _magicNumber); + emit StandardCallbackRegistered(_interfaceId, _callbackSelector, _magicNumber); + } + + /// @inheritdoc IEIP4824 + function daoURI() external view returns (string memory) { + return _daoURI; + } + + /// @notice Updates the set DAO uri to a new value. + /// @param newDaoURI The new DAO uri to be set. + function setDaoURI(string calldata newDaoURI) external auth(SET_METADATA_PERMISSION_ID) { + _setDaoURI(newDaoURI); + } + + /// @notice Sets the new DAO uri and emits the associated event. + /// @param daoURI_ The new DAO uri. + function _setDaoURI(string calldata daoURI_) internal { + _daoURI = daoURI_; + + emit NewURI(daoURI_); + } + + /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). + uint256[47] private __gap; +} diff --git a/packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol b/packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol new file mode 100644 index 000000000..f7318726b --- /dev/null +++ b/packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.17; + +/// @title IDAO v1.0.0 +/// @author Aragon Association - 2022-2023 +/// @notice The interface required for DAOs within the Aragon App DAO framework. +interface IDAO_v1_0_0 { + /// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call. + /// @param to The address to call. + /// @param value The native token value to be sent with the call. + /// @param data The bytes-encoded function selector and calldata for the call. + struct Action { + address to; + uint256 value; + bytes data; + } + + /// @notice Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process. + /// @param _where The address of the contract. + /// @param _who The address of a EOA or contract to give the permissions. + /// @param _permissionId The permission identifier. + /// @param _data The optional data passed to the `PermissionCondition` registered. + /// @return Returns true if the address has permission, false if not. + function hasPermission( + address _where, + address _who, + bytes32 _permissionId, + bytes memory _data + ) external view returns (bool); + + /// @notice Updates the DAO metadata (e.g., an IPFS hash). + /// @param _metadata The IPFS hash of the new metadata object. + function setMetadata(bytes calldata _metadata) external; + + /// @notice Emitted when the DAO metadata is updated. + /// @param metadata The IPFS hash of the new metadata object. + event MetadataSet(bytes metadata); + + /// @notice Executes a list of actions. If no failure map is provided, one failing action results in the entire excution to be reverted. If a non-zero failure map is provided, allowed actions can fail without the remaining actions being reverted. + /// @param _callId The ID of the call. The definition of the value of `callId` is up to the calling contract and can be used, e.g., as a nonce. + /// @param _actions The array of actions. + /// @param _allowFailureMap A bitmap allowing execution to succeed, even if individual actions might revert. If the bit at index `i` is 1, the execution succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. + /// @return The array of results obtained from the executed actions in `bytes`. + /// @return The constructed failureMap which contains which actions have actually failed. + function execute( + bytes32 _callId, + Action[] memory _actions, + uint256 _allowFailureMap + ) external returns (bytes[] memory, uint256); + + /// @notice Emitted when a proposal is executed. + /// @param actor The address of the caller. + /// @param callId The ID of the call. + /// @param actions The array of actions executed. + /// @param failureMap The failure map encoding which actions have failed. + /// @param execResults The array with the results of the executed actions. + /// @dev The value of `callId` is defined by the component/contract calling the execute function. A `Plugin` implementation can use it, for example, as a nonce. + event Executed( + address indexed actor, + bytes32 callId, + Action[] actions, + uint256 failureMap, + bytes[] execResults + ); + + /// @notice Emitted when a standard callback is registered. + /// @param interfaceId The ID of the interface. + /// @param callbackSelector The selector of the callback function. + /// @param magicNumber The magic number to be registered for the callback function selector. + event StandardCallbackRegistered( + bytes4 interfaceId, + bytes4 callbackSelector, + bytes4 magicNumber + ); + + /// @notice Deposits (native) tokens to the DAO contract with a reference string. + /// @param _token The address of the token or address(0) in case of the native token. + /// @param _amount The amount of tokens to deposit. + /// @param _reference The reference describing the deposit reason. + function deposit(address _token, uint256 _amount, string calldata _reference) external payable; + + /// @notice Emitted when a token deposit has been made to the DAO. + /// @param sender The address of the sender. + /// @param token The address of the deposited token. + /// @param amount The amount of tokens deposited. + /// @param _reference The reference describing the deposit reason. + event Deposited( + address indexed sender, + address indexed token, + uint256 amount, + string _reference + ); + + /// @notice Emitted when a native token deposit has been made to the DAO. + /// @dev This event is intended to be emitted in the `receive` function and is therefore bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929). + /// @param sender The address of the sender. + /// @param amount The amount of native tokens deposited. + event NativeTokenDeposited(address sender, uint256 amount); + + /// @notice Setter for the trusted forwarder verifying the meta transaction. + /// @param _trustedForwarder The trusted forwarder address. + function setTrustedForwarder(address _trustedForwarder) external; + + /// @notice Getter for the trusted forwarder verifying the meta transaction. + /// @return The trusted forwarder address. + function getTrustedForwarder() external view returns (address); + + /// @notice Emitted when a new TrustedForwarder is set on the DAO. + /// @param forwarder the new forwarder address. + event TrustedForwarderSet(address forwarder); + + /// @notice Setter for the [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. + /// @param _signatureValidator The address of the signature validator. + function setSignatureValidator(address _signatureValidator) external; + + /// @notice Emitted when the signature validator address is updated. + /// @param signatureValidator The address of the signature validator. + event SignatureValidatorSet(address signatureValidator); + + /// @notice Checks whether a signature is valid for the provided hash by forwarding the call to the set [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. + /// @param _hash The hash of the data to be signed. + /// @param _signature The signature byte array associated with `_hash`. + /// @return Returns the `bytes4` magic value `0x1626ba7e` if the signature is valid. + function isValidSignature(bytes32 _hash, bytes memory _signature) external returns (bytes4); + + /// @notice Registers an ERC standard having a callback by registering its [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID and callback function signature. + /// @param _interfaceId The ID of the interface. + /// @param _callbackSelector The selector of the callback function. + /// @param _magicNumber The magic number to be registered for the function signature. + function registerStandardCallback( + bytes4 _interfaceId, + bytes4 _callbackSelector, + bytes4 _magicNumber + ) external; +} diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 428e93d8f..8fa2d10f2 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -9,6 +9,12 @@ import { TestERC721, IERC1271__factory, GasConsumer__factory, + DAOFactory__factory, + PluginRepo__factory, + DAORegistry__factory, + DAO__factory, + Admin__factory, + PluginSetupProcessor__factory, } from '../../../typechain'; import {findEvent, DAO_EVENTS} from '../../../utils/event'; import {flipBit} from '../../test-utils/bitmap'; @@ -22,7 +28,7 @@ import { } from '../../test-utils/dao'; import {getInterfaceID} from '../../test-utils/interfaces'; -import {OZ_ERRORS} from '../../test-utils/error'; +import {OZ_ERRORS} from '../../test-utils/oz-constants'; import {smock} from '@defi-wonderland/smock'; import {deployWithProxy} from '../../test-utils/proxy'; import {UNREGISTERED_INTERFACE_RETURN} from './callback-handler'; @@ -30,6 +36,8 @@ import {shouldUpgradeCorrectly} from '../../test-utils/uups-upgradeable'; import {UPGRADE_PERMISSIONS} from '../../test-utils/permissions'; import {ZERO_BYTES32, daoExampleURI} from '../../test-utils/dao'; import {ExecutedEvent} from '../../../typechain/DAO'; +import {getActiveContractsJSON} from '../../../deploy/helpers'; +import {BigNumber} from 'ethers'; chai.use(smock.matchers); @@ -55,7 +63,7 @@ const EVENTS = { CallbackReceived: 'CallbackReceived', }; -const PERMISSION_IDS = { +export const PERMISSION_IDS = { UPGRADE_DAO_PERMISSION_ID: UPGRADE_PERMISSIONS.UPGRADE_DAO_PERMISSION_ID, SET_METADATA_PERMISSION_ID: ethers.utils.id('SET_METADATA_PERMISSION'), EXECUTE_PERMISSION_ID: ethers.utils.id('EXECUTE_PERMISSION'), @@ -404,10 +412,11 @@ describe('DAO', function () { expect(event.args.allowFailureMap).to.equal(0); }); - it('reverts if failure is allowed but not enough gas is provided', async () => { + it('reverts if failure is allowed but not enough gas is provided (many actions)', async () => { const GasConsumer = new GasConsumer__factory(signers[0]); let gasConsumer = await GasConsumer.deploy(); + // Prepare an action array calling `consumeGas` twenty times. const gasConsumingAction = { to: gasConsumer.address, data: GasConsumer.interface.encodeFunctionData('consumeGas', [20]), @@ -421,15 +430,51 @@ describe('DAO', function () { ZERO_BYTES32, [gasConsumingAction], allowFailureMap - ); // expectedGas = 520720 gas + ); + + // Provide too little gas so that the last `to.call` fails, but the remaining gas is enough to finish the subsequent operations. + await expect( + dao.execute(ZERO_BYTES32, [gasConsumingAction], allowFailureMap, { + gasLimit: expectedGas.sub(3000), + }) + ).to.be.revertedWithCustomError(dao, 'InsufficientGas'); + + // Provide enough gas so that the entire call passes. + await expect( + dao.execute(ZERO_BYTES32, [gasConsumingAction], allowFailureMap, { + gasLimit: expectedGas, + }) + ).to.not.be.reverted; + }); + + it('reverts if failure is allowed but not enough gas is provided (one action)', async () => { + const GasConsumer = new GasConsumer__factory(signers[0]); + let gasConsumer = await GasConsumer.deploy(); + + // Prepare an action array calling `consumeGas` one times. + const gasConsumingAction = { + to: gasConsumer.address, + data: GasConsumer.interface.encodeFunctionData('consumeGas', [1]), + value: 0, + }; + + let allowFailureMap = ethers.BigNumber.from(0); + allowFailureMap = flipBit(0, allowFailureMap); // allow the action to fail + + const expectedGas = await dao.estimateGas.execute( + ZERO_BYTES32, + [gasConsumingAction], + allowFailureMap + ); - // Providing less gas causes the `to.call` of the `gasConsumingAction` to fail, but is still enough for the overall `dao.execute` call to finish successfully. + // Provide too little gas so that the last `to.call` fails, but the remaining gas is enough to finish the subsequent operations. await expect( dao.execute(ZERO_BYTES32, [gasConsumingAction], allowFailureMap, { - gasLimit: expectedGas.sub(2800), // 2796 gas is the limit value for which the call cannot finish successfully anymore (520720 gas - 2796 gas = 517924 gas) + gasLimit: expectedGas.sub(10000), }) ).to.be.revertedWithCustomError(dao, 'InsufficientGas'); + // Provide enough gas so that the entire call passes. await expect( dao.execute(ZERO_BYTES32, [gasConsumingAction], allowFailureMap, { gasLimit: expectedGas, diff --git a/packages/contracts/test/core/permission/permission-manager.ts b/packages/contracts/test/core/permission/permission-manager.ts index 6e6fd1b4f..c4456b189 100644 --- a/packages/contracts/test/core/permission/permission-manager.ts +++ b/packages/contracts/test/core/permission/permission-manager.ts @@ -7,7 +7,7 @@ import { PermissionConditionMock, } from '../../../typechain'; import {DeployTestPermissionCondition} from '../../test-utils/conditions'; -import {OZ_ERRORS} from '../../test-utils/error'; +import {OZ_ERRORS} from '../../test-utils/oz-constants'; import {Operation} from '../../../utils/types'; const ROOT_PERMISSION_ID = ethers.utils.id('ROOT_PERMISSION'); diff --git a/packages/contracts/test/deploy/managing-dao.ts b/packages/contracts/test/deploy/managing-dao.ts index 142d54e63..323ff42e5 100644 --- a/packages/contracts/test/deploy/managing-dao.ts +++ b/packages/contracts/test/deploy/managing-dao.ts @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {defaultAbiCoder} from 'ethers/lib/utils'; +import {readImplementationValuesFromSlot} from '../../utils/storage'; import hre, {ethers, deployments, getNamedAccounts} from 'hardhat'; import {Deployment} from 'hardhat-deploy/dist/types'; @@ -16,9 +16,6 @@ async function deployAll() { await deployments.fixture(); } -const IMPLEMENTATION_SLOT = - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc'; - describe('Managing DAO', function () { let ownerAddress: string; let managingDaoDeployment: Deployment; @@ -31,22 +28,6 @@ describe('Managing DAO', function () { let ensSubdomainRegistrarDeployments: Deployment[]; let ensSubdomainRegistrars: ENSSubdomainRegistrar[]; - async function readImplementationValueFromSlot( - contractAddresses: string[] - ): Promise { - const implementationValues: string[] = await Promise.all( - contractAddresses.map(async contractAddress => { - const encoded = await ethers.provider.getStorageAt( - contractAddress, - IMPLEMENTATION_SLOT - ); - return defaultAbiCoder.decode(['address'], encoded)[0]; - }) - ); - - return implementationValues; - } - async function createUpgradeProposal( contractAddress: string[], newImplementationAddress: string @@ -144,7 +125,7 @@ describe('Managing DAO', function () { // check new implementation is deferent from the one on the ManagingDao. // read from slot let implementationAddress = ( - await readImplementationValueFromSlot([managingDao.address]) + await readImplementationValuesFromSlot([managingDao.address]) )[0]; expect(managingDaoV2Deployment.address).not.equal(implementationAddress); @@ -157,7 +138,7 @@ describe('Managing DAO', function () { // re-read from slot implementationAddress = ( - await readImplementationValueFromSlot([managingDao.address]) + await readImplementationValuesFromSlot([managingDao.address]) )[0]; expect(managingDaoV2Deployment.address).to.be.equal(implementationAddress); @@ -182,7 +163,7 @@ describe('Managing DAO', function () { // check new implementation is deferent from the one on the `DaoRegistry`. // read from slot let implementationAddress = ( - await readImplementationValueFromSlot([daoRegistry.address]) + await readImplementationValuesFromSlot([daoRegistry.address]) )[0]; expect(daoRegistryV2Deployment.address).not.equal(implementationAddress); @@ -195,7 +176,7 @@ describe('Managing DAO', function () { // re-read from slot implementationAddress = ( - await readImplementationValueFromSlot([daoRegistry.address]) + await readImplementationValuesFromSlot([daoRegistry.address]) )[0]; expect(daoRegistryV2Deployment.address).to.be.equal(implementationAddress); @@ -222,7 +203,7 @@ describe('Managing DAO', function () { // check new implementation is deferent from the one on the `DaoRegistry`. // read from slot let implementationAddress = ( - await readImplementationValueFromSlot([pluginRepoRegistry.address]) + await readImplementationValuesFromSlot([pluginRepoRegistry.address]) )[0]; expect(pluginRepoRegistryV2Deployment.address).not.equal( @@ -237,7 +218,7 @@ describe('Managing DAO', function () { // re-read from slot implementationAddress = ( - await readImplementationValueFromSlot([pluginRepoRegistry.address]) + await readImplementationValuesFromSlot([pluginRepoRegistry.address]) )[0]; expect(pluginRepoRegistryV2Deployment.address).to.be.equal( @@ -265,7 +246,7 @@ describe('Managing DAO', function () { // check new implementation is deferent from the one on the `DaoRegistry`. // read from slot - let implementationValues = await readImplementationValueFromSlot([ + let implementationValues = await readImplementationValuesFromSlot([ ensSubdomainRegistrars[0].address, ensSubdomainRegistrars[1].address, ]); @@ -284,7 +265,7 @@ describe('Managing DAO', function () { ); // re-read from slot - implementationValues = await readImplementationValueFromSlot([ + implementationValues = await readImplementationValuesFromSlot([ ensSubdomainRegistrars[0].address, ensSubdomainRegistrars[1].address, ]); @@ -315,7 +296,7 @@ describe('Managing DAO', function () { // check new implementation is deferent from the one on the `DaoRegistry`. // read from slot - let implementationValues = await readImplementationValueFromSlot([ + let implementationValues = await readImplementationValuesFromSlot([ hre.aragonPluginRepos['token-voting'], hre.aragonPluginRepos['address-list-voting'], hre.aragonPluginRepos['admin'], @@ -336,7 +317,7 @@ describe('Managing DAO', function () { ); // re-read from slot - implementationValues = await readImplementationValueFromSlot([ + implementationValues = await readImplementationValuesFromSlot([ hre.aragonPluginRepos['token-voting'], hre.aragonPluginRepos['address-list-voting'], hre.aragonPluginRepos['admin'], diff --git a/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts b/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts index c70974a18..2ef1abb72 100644 --- a/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts +++ b/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts @@ -11,7 +11,7 @@ import { } from '../../../../typechain'; import {deployNewDAO} from '../../../test-utils/dao'; import {ensDomainHash, ensLabelHash} from '../../../../utils/ens'; -import {OZ_ERRORS} from '../../../test-utils/error'; +import {OZ_ERRORS} from '../../../test-utils/oz-constants'; import {setupResolver} from '../../../test-utils/ens'; import {shouldUpgradeCorrectly} from '../../../test-utils/uups-upgradeable'; import {UPGRADE_PERMISSIONS} from '../../../test-utils/permissions'; diff --git a/packages/contracts/test/plugins/governance/admin/admin.ts b/packages/contracts/test/plugins/governance/admin/admin.ts index 9865712d7..a57ce570e 100644 --- a/packages/contracts/test/plugins/governance/admin/admin.ts +++ b/packages/contracts/test/plugins/governance/admin/admin.ts @@ -11,7 +11,7 @@ import { } from '../../../../utils/event'; import {deployNewDAO} from '../../../test-utils/dao'; import {getInterfaceID} from '../../../test-utils/interfaces'; -import {OZ_ERRORS} from '../../../test-utils/error'; +import {OZ_ERRORS} from '../../../test-utils/oz-constants'; import {toBytes32} from '../../../test-utils/voting'; import { AdminCloneFactory, diff --git a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts index f29f26f55..faa18d170 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts @@ -34,7 +34,7 @@ import { toBytes32, } from '../../../../test-utils/voting'; import {deployNewDAO} from '../../../../test-utils/dao'; -import {OZ_ERRORS} from '../../../../test-utils/error'; +import {OZ_ERRORS} from '../../../../test-utils/oz-constants'; import {shouldUpgradeCorrectly} from '../../../../test-utils/uups-upgradeable'; import {UPGRADE_PERMISSIONS} from '../../../../test-utils/permissions'; import {deployWithProxy} from '../../../../test-utils/proxy'; diff --git a/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts index 90a869dfc..2e1dfc88c 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts @@ -19,7 +19,7 @@ import { ONE_YEAR, } from '../../../test-utils/voting'; import {deployWithProxy} from '../../../test-utils/proxy'; -import {OZ_ERRORS} from '../../../test-utils/error'; +import {OZ_ERRORS} from '../../../test-utils/oz-constants'; import {daoExampleURI} from '../../../test-utils/dao'; import {getInterfaceID} from '../../../test-utils/interfaces'; diff --git a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts index 378e619a6..e7c707d66 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts @@ -37,7 +37,7 @@ import { toBytes32, } from '../../../../test-utils/voting'; import {deployNewDAO} from '../../../../test-utils/dao'; -import {OZ_ERRORS} from '../../../../test-utils/error'; +import {OZ_ERRORS} from '../../../../test-utils/oz-constants'; import {shouldUpgradeCorrectly} from '../../../../test-utils/uups-upgradeable'; import {UPGRADE_PERMISSIONS} from '../../../../test-utils/permissions'; import {deployWithProxy} from '../../../../test-utils/proxy'; diff --git a/packages/contracts/test/plugins/governance/multisig/multisig.ts b/packages/contracts/test/plugins/governance/multisig/multisig.ts index 8389becd0..54d52e752 100644 --- a/packages/contracts/test/plugins/governance/multisig/multisig.ts +++ b/packages/contracts/test/plugins/governance/multisig/multisig.ts @@ -22,7 +22,7 @@ import { } from '../../../../utils/event'; import {getMergedABI} from '../../../../utils/abi'; import {deployNewDAO} from '../../../test-utils/dao'; -import {OZ_ERRORS} from '../../../test-utils/error'; +import {OZ_ERRORS} from '../../../test-utils/oz-constants'; import { advanceTime, getTime, diff --git a/packages/contracts/test/test-utils/error.ts b/packages/contracts/test/test-utils/oz-constants.ts similarity index 60% rename from packages/contracts/test/test-utils/error.ts rename to packages/contracts/test/test-utils/oz-constants.ts index 05416f89a..7686b95de 100644 --- a/packages/contracts/test/test-utils/error.ts +++ b/packages/contracts/test/test-utils/oz-constants.ts @@ -2,3 +2,6 @@ export const OZ_ERRORS = { ALREADY_INITIALIZED: 'Initializable: contract is already initialized', ERC20_INSUFFICIENT_ALLOWANCE: 'ERC20: insufficient allowance', }; + +export const IMPLEMENTATION_SLOT = + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc'; diff --git a/packages/contracts/test/test-utils/uups-upgradeable.ts b/packages/contracts/test/test-utils/uups-upgradeable.ts index 1a28de61f..6ae9ab4bf 100644 --- a/packages/contracts/test/test-utils/uups-upgradeable.ts +++ b/packages/contracts/test/test-utils/uups-upgradeable.ts @@ -1,7 +1,9 @@ import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; import {Contract} from 'ethers'; +import {defaultAbiCoder} from 'ethers/lib/utils'; import {ethers} from 'hardhat'; +import {IMPLEMENTATION_SLOT} from './oz-constants'; /// Used as a common test suite to test upgradeability of the contracts. /// Presumes that `upgrade` object is set on `this` inside the actual test file. @@ -73,9 +75,19 @@ export function shouldUpgradeCorrectly( const {user, contract, dao} = this.upgrade; await dao.grant(contract.address, user.address, upgradePermissionId); const connect = contract.connect(user); + + // Check the event. await expect(connect.upgradeTo(uupsCompatibleBase)) .to.emit(contract, 'Upgraded') .withArgs(uupsCompatibleBase); + + // Check the storage slot. + const encoded = await ethers.provider.getStorageAt( + contract.address, + IMPLEMENTATION_SLOT + ); + const implementation = defaultAbiCoder.decode(['address'], encoded)[0]; + expect(implementation).to.equal(uupsCompatibleBase); }); }); } diff --git a/packages/contracts/test/token/erc20/governance-erc20.ts b/packages/contracts/test/token/erc20/governance-erc20.ts index dac310695..9be65b2ad 100644 --- a/packages/contracts/test/token/erc20/governance-erc20.ts +++ b/packages/contracts/test/token/erc20/governance-erc20.ts @@ -9,7 +9,7 @@ import { IERC165Upgradeable__factory, } from '../../../typechain'; import {deployNewDAO} from '../../test-utils/dao'; -import {OZ_ERRORS} from '../../test-utils/error'; +import {OZ_ERRORS} from '../../test-utils/oz-constants'; import {getInterfaceID} from '../../test-utils/interfaces'; export type MintSettings = { diff --git a/packages/contracts/test/token/erc20/governance-wrapped-erc20.ts b/packages/contracts/test/token/erc20/governance-wrapped-erc20.ts index dc8f94ed1..d661fe7ac 100644 --- a/packages/contracts/test/token/erc20/governance-wrapped-erc20.ts +++ b/packages/contracts/test/token/erc20/governance-wrapped-erc20.ts @@ -9,7 +9,7 @@ import { GovernanceWrappedERC20__factory, IERC165Upgradeable__factory, } from '../../../typechain'; -import {OZ_ERRORS} from '../../test-utils/error'; +import {OZ_ERRORS} from '../../test-utils/oz-constants'; import {getInterfaceID} from '../../test-utils/interfaces'; export type AccountBalance = {account: string; amount: number}; diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts new file mode 100644 index 000000000..ff00511c9 --- /dev/null +++ b/packages/contracts/test/upgrade/dao.ts @@ -0,0 +1,77 @@ +import {expect} from 'chai'; +import {ethers} from 'hardhat'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; + +import { + DAOFactory__factory, + PluginRepo__factory, + DAORegistry__factory, + DAO__factory, + DAOV100, + DAOV100__factory, +} from '../../typechain'; + +import {daoExampleURI} from '../test-utils/dao'; + +import {deployWithProxy} from '../test-utils/proxy'; +import {UPGRADE_PERMISSIONS} from '../test-utils/permissions'; +import {findEventTopicLog} from '../../utils/event'; +import {readImplementationValueFromSlot} from '../../utils/storage'; + +let signers: SignerWithAddress[]; +let DaoV100: DAOV100__factory; +let DaoV110: DAO__factory; + +const DUMMY_METADATA = ethers.utils.hexlify( + ethers.utils.toUtf8Bytes('0x123456789') +); + +describe('DAO Upgrade', function () { + before(async function () { + signers = await ethers.getSigners(); + DaoV100 = new DAOV100__factory(signers[0]); + DaoV110 = new DAO__factory(signers[0]); + }); + + it('upgrades v1.0.0 to v1.1.0', async () => { + const daoV100 = await deployWithProxy(DaoV100); + await daoV100.initialize( + DUMMY_METADATA, + signers[0].address, + ethers.constants.AddressZero, + daoExampleURI + ); + + const oldImplementation = await readImplementationValueFromSlot( + daoV100.address + ); + + daoV100.grant( + daoV100.address, + signers[0].address, + UPGRADE_PERMISSIONS.UPGRADE_DAO_PERMISSION_ID + ); + + // Deploy the new implementation + const daoV110 = await DaoV110.deploy(); + + // Upgrade to the new implementation + const upgradeTx = await daoV100.upgradeTo(daoV110.address); + + // Check the stored implementation. + const newImplementation = await readImplementationValueFromSlot( + daoV100.address + ); + expect(newImplementation).to.equal(daoV110.address); + expect(newImplementation).to.not.equal(oldImplementation); + + // Check the emitted implementation. + const emittedImplementation = ( + await findEventTopicLog(upgradeTx, DaoV100.interface, 'Upgraded') + ).args.implementation; + expect(emittedImplementation).to.equal(daoV110.address); + + // Check that storage is not corrupted. + expect(await daoV100.callStatic.daoURI()).to.equal(daoExampleURI); + }); +}); diff --git a/packages/contracts/utils/event.ts b/packages/contracts/utils/event.ts index 06a76bf98..2cf48b0ab 100644 --- a/packages/contracts/utils/event.ts +++ b/packages/contracts/utils/event.ts @@ -1,4 +1,5 @@ import {ContractTransaction} from 'ethers'; +import {Interface, LogDescription} from 'ethers/lib/utils'; export async function findEvent(tx: ContractTransaction, eventName: string) { const receipt = await tx.wait(); @@ -11,6 +12,20 @@ export async function findEvent(tx: ContractTransaction, eventName: string) { return event as T; } +export async function findEventTopicLog( + tx: ContractTransaction, + iface: Interface, + eventName: string +): Promise { + const receipt = await tx.wait(); + const topic = iface.getEventTopic(eventName); + const log = receipt.logs.find(x => x.topics.indexOf(topic) >= 0); + if (!log) { + throw new Error(`No logs found for this event ${eventName} topic.`); + } + return iface.parseLog(log); +} + export async function filterEvents(tx: any, eventName: string) { const {events} = await tx.wait(); const event = events.filter(({event}: {event: any}) => event === eventName); diff --git a/packages/contracts/utils/storage.ts b/packages/contracts/utils/storage.ts new file mode 100644 index 000000000..b56ff2842 --- /dev/null +++ b/packages/contracts/utils/storage.ts @@ -0,0 +1,26 @@ +import {ethers} from 'hardhat'; +import {IMPLEMENTATION_SLOT} from '../test/test-utils/oz-constants'; + +import {defaultAbiCoder} from 'ethers/lib/utils'; + +export async function readImplementationValuesFromSlot( + contractAddresses: string[] +): Promise { + const implementationValues: string[] = await Promise.all( + contractAddresses.map(async contractAddress => { + return readImplementationValueFromSlot(contractAddress); + }) + ); + + return implementationValues; +} + +export async function readImplementationValueFromSlot( + contractAddress: string +): Promise { + const encoded = await ethers.provider.getStorageAt( + contractAddress, + IMPLEMENTATION_SLOT + ); + return defaultAbiCoder.decode(['address'], encoded)[0]; +} From 9fb0473e60ff280fa3b7ad8737574ce7287adba7 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 19 Apr 2023 10:00:00 +0200 Subject: [PATCH 006/112] chore: cleaning --- packages/contracts/test/core/dao/dao.ts | 8 ------- packages/contracts/test/upgrade/dao.ts | 31 ++++++++++++++----------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 8fa2d10f2..33c7710b5 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -9,12 +9,6 @@ import { TestERC721, IERC1271__factory, GasConsumer__factory, - DAOFactory__factory, - PluginRepo__factory, - DAORegistry__factory, - DAO__factory, - Admin__factory, - PluginSetupProcessor__factory, } from '../../../typechain'; import {findEvent, DAO_EVENTS} from '../../../utils/event'; import {flipBit} from '../../test-utils/bitmap'; @@ -36,8 +30,6 @@ import {shouldUpgradeCorrectly} from '../../test-utils/uups-upgradeable'; import {UPGRADE_PERMISSIONS} from '../../test-utils/permissions'; import {ZERO_BYTES32, daoExampleURI} from '../../test-utils/dao'; import {ExecutedEvent} from '../../../typechain/DAO'; -import {getActiveContractsJSON} from '../../../deploy/helpers'; -import {BigNumber} from 'ethers'; chai.use(smock.matchers); diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index ff00511c9..8e1334f20 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -34,44 +34,47 @@ describe('DAO Upgrade', function () { }); it('upgrades v1.0.0 to v1.1.0', async () => { - const daoV100 = await deployWithProxy(DaoV100); - await daoV100.initialize( + const proxy = await deployWithProxy(DaoV100); + await proxy.initialize( DUMMY_METADATA, signers[0].address, ethers.constants.AddressZero, daoExampleURI ); - const oldImplementation = await readImplementationValueFromSlot( - daoV100.address + // Store the current implementation + const implementationBeforeUpgrade = await readImplementationValueFromSlot( + proxy.address ); - daoV100.grant( - daoV100.address, + proxy.grant( + proxy.address, signers[0].address, UPGRADE_PERMISSIONS.UPGRADE_DAO_PERMISSION_ID ); // Deploy the new implementation - const daoV110 = await DaoV110.deploy(); + const newImplementation = await DaoV110.deploy(); // Upgrade to the new implementation - const upgradeTx = await daoV100.upgradeTo(daoV110.address); + const upgradeTx = await proxy.upgradeTo(newImplementation.address); // Check the stored implementation. - const newImplementation = await readImplementationValueFromSlot( - daoV100.address + const implementationAfterUpgrade = await readImplementationValueFromSlot( + proxy.address + ); + expect(implementationAfterUpgrade).to.equal(newImplementation.address); + expect(implementationAfterUpgrade).to.not.equal( + implementationBeforeUpgrade ); - expect(newImplementation).to.equal(daoV110.address); - expect(newImplementation).to.not.equal(oldImplementation); // Check the emitted implementation. const emittedImplementation = ( await findEventTopicLog(upgradeTx, DaoV100.interface, 'Upgraded') ).args.implementation; - expect(emittedImplementation).to.equal(daoV110.address); + expect(emittedImplementation).to.equal(newImplementation.address); // Check that storage is not corrupted. - expect(await daoV100.callStatic.daoURI()).to.equal(daoExampleURI); + expect(await proxy.callStatic.daoURI()).to.equal(daoExampleURI); }); }); From a02552325ab5bf692cdf14d239ae510f59717fbc Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 19 Apr 2023 14:33:03 +0200 Subject: [PATCH 007/112] fix: remove empty comment --- packages/contracts/src/core/dao/DAO.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index ea5b98b84..c924f4993 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -213,7 +213,6 @@ contract DAO is uint256 gasBefore; uint256 gasAfter; - // for (uint256 i = 0; i < _actions.length; ) { gasBefore = gasleft(); From 3fcc083562c7c4c39812ebafebfd631a50c1724c Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 19 Apr 2023 14:33:30 +0200 Subject: [PATCH 008/112] fix: refactor findEventTopicLog function --- packages/contracts/utils/event.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/utils/event.ts b/packages/contracts/utils/event.ts index 2cf48b0ab..b68b3785e 100644 --- a/packages/contracts/utils/event.ts +++ b/packages/contracts/utils/event.ts @@ -19,7 +19,7 @@ export async function findEventTopicLog( ): Promise { const receipt = await tx.wait(); const topic = iface.getEventTopic(eventName); - const log = receipt.logs.find(x => x.topics.indexOf(topic) >= 0); + const log = receipt.logs.find(x => x.topics[0] === topic); if (!log) { throw new Error(`No logs found for this event ${eventName} topic.`); } From 02711cc0834252722eace1e18e398c8bf75c691d Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 19 Apr 2023 14:40:48 +0200 Subject: [PATCH 009/112] fix: moved implementation slot and renamed file --- packages/contracts/test/core/dao/dao.ts | 2 +- packages/contracts/test/core/permission/permission-manager.ts | 2 +- .../test/framework/utils/ens/ens-subdomain-registry.ts | 2 +- packages/contracts/test/plugins/governance/admin/admin.ts | 2 +- .../majority-voting/addresslist/addresslist-voting.ts | 2 +- .../plugins/governance/majority-voting/majority-voting.ts | 2 +- .../plugins/governance/majority-voting/token/token-voting.ts | 2 +- .../contracts/test/plugins/governance/multisig/multisig.ts | 2 +- .../contracts/test/test-utils/{oz-constants.ts => error.ts} | 3 --- packages/contracts/test/test-utils/uups-upgradeable.ts | 4 +++- packages/contracts/test/token/erc20/governance-erc20.ts | 2 +- .../contracts/test/token/erc20/governance-wrapped-erc20.ts | 2 +- packages/contracts/utils/storage.ts | 4 ++-- 13 files changed, 15 insertions(+), 16 deletions(-) rename packages/contracts/test/test-utils/{oz-constants.ts => error.ts} (60%) diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 33c7710b5..dc75f7a68 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -22,7 +22,7 @@ import { } from '../../test-utils/dao'; import {getInterfaceID} from '../../test-utils/interfaces'; -import {OZ_ERRORS} from '../../test-utils/oz-constants'; +import {OZ_ERRORS} from '../../test-utils/error'; import {smock} from '@defi-wonderland/smock'; import {deployWithProxy} from '../../test-utils/proxy'; import {UNREGISTERED_INTERFACE_RETURN} from './callback-handler'; diff --git a/packages/contracts/test/core/permission/permission-manager.ts b/packages/contracts/test/core/permission/permission-manager.ts index c4456b189..6e6fd1b4f 100644 --- a/packages/contracts/test/core/permission/permission-manager.ts +++ b/packages/contracts/test/core/permission/permission-manager.ts @@ -7,7 +7,7 @@ import { PermissionConditionMock, } from '../../../typechain'; import {DeployTestPermissionCondition} from '../../test-utils/conditions'; -import {OZ_ERRORS} from '../../test-utils/oz-constants'; +import {OZ_ERRORS} from '../../test-utils/error'; import {Operation} from '../../../utils/types'; const ROOT_PERMISSION_ID = ethers.utils.id('ROOT_PERMISSION'); diff --git a/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts b/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts index 2ef1abb72..c70974a18 100644 --- a/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts +++ b/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts @@ -11,7 +11,7 @@ import { } from '../../../../typechain'; import {deployNewDAO} from '../../../test-utils/dao'; import {ensDomainHash, ensLabelHash} from '../../../../utils/ens'; -import {OZ_ERRORS} from '../../../test-utils/oz-constants'; +import {OZ_ERRORS} from '../../../test-utils/error'; import {setupResolver} from '../../../test-utils/ens'; import {shouldUpgradeCorrectly} from '../../../test-utils/uups-upgradeable'; import {UPGRADE_PERMISSIONS} from '../../../test-utils/permissions'; diff --git a/packages/contracts/test/plugins/governance/admin/admin.ts b/packages/contracts/test/plugins/governance/admin/admin.ts index a57ce570e..9865712d7 100644 --- a/packages/contracts/test/plugins/governance/admin/admin.ts +++ b/packages/contracts/test/plugins/governance/admin/admin.ts @@ -11,7 +11,7 @@ import { } from '../../../../utils/event'; import {deployNewDAO} from '../../../test-utils/dao'; import {getInterfaceID} from '../../../test-utils/interfaces'; -import {OZ_ERRORS} from '../../../test-utils/oz-constants'; +import {OZ_ERRORS} from '../../../test-utils/error'; import {toBytes32} from '../../../test-utils/voting'; import { AdminCloneFactory, diff --git a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts index faa18d170..f29f26f55 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts @@ -34,7 +34,7 @@ import { toBytes32, } from '../../../../test-utils/voting'; import {deployNewDAO} from '../../../../test-utils/dao'; -import {OZ_ERRORS} from '../../../../test-utils/oz-constants'; +import {OZ_ERRORS} from '../../../../test-utils/error'; import {shouldUpgradeCorrectly} from '../../../../test-utils/uups-upgradeable'; import {UPGRADE_PERMISSIONS} from '../../../../test-utils/permissions'; import {deployWithProxy} from '../../../../test-utils/proxy'; diff --git a/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts index 2e1dfc88c..90a869dfc 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts @@ -19,7 +19,7 @@ import { ONE_YEAR, } from '../../../test-utils/voting'; import {deployWithProxy} from '../../../test-utils/proxy'; -import {OZ_ERRORS} from '../../../test-utils/oz-constants'; +import {OZ_ERRORS} from '../../../test-utils/error'; import {daoExampleURI} from '../../../test-utils/dao'; import {getInterfaceID} from '../../../test-utils/interfaces'; diff --git a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts index e7c707d66..378e619a6 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts @@ -37,7 +37,7 @@ import { toBytes32, } from '../../../../test-utils/voting'; import {deployNewDAO} from '../../../../test-utils/dao'; -import {OZ_ERRORS} from '../../../../test-utils/oz-constants'; +import {OZ_ERRORS} from '../../../../test-utils/error'; import {shouldUpgradeCorrectly} from '../../../../test-utils/uups-upgradeable'; import {UPGRADE_PERMISSIONS} from '../../../../test-utils/permissions'; import {deployWithProxy} from '../../../../test-utils/proxy'; diff --git a/packages/contracts/test/plugins/governance/multisig/multisig.ts b/packages/contracts/test/plugins/governance/multisig/multisig.ts index 54d52e752..8389becd0 100644 --- a/packages/contracts/test/plugins/governance/multisig/multisig.ts +++ b/packages/contracts/test/plugins/governance/multisig/multisig.ts @@ -22,7 +22,7 @@ import { } from '../../../../utils/event'; import {getMergedABI} from '../../../../utils/abi'; import {deployNewDAO} from '../../../test-utils/dao'; -import {OZ_ERRORS} from '../../../test-utils/oz-constants'; +import {OZ_ERRORS} from '../../../test-utils/error'; import { advanceTime, getTime, diff --git a/packages/contracts/test/test-utils/oz-constants.ts b/packages/contracts/test/test-utils/error.ts similarity index 60% rename from packages/contracts/test/test-utils/oz-constants.ts rename to packages/contracts/test/test-utils/error.ts index 7686b95de..05416f89a 100644 --- a/packages/contracts/test/test-utils/oz-constants.ts +++ b/packages/contracts/test/test-utils/error.ts @@ -2,6 +2,3 @@ export const OZ_ERRORS = { ALREADY_INITIALIZED: 'Initializable: contract is already initialized', ERC20_INSUFFICIENT_ALLOWANCE: 'ERC20: insufficient allowance', }; - -export const IMPLEMENTATION_SLOT = - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc'; diff --git a/packages/contracts/test/test-utils/uups-upgradeable.ts b/packages/contracts/test/test-utils/uups-upgradeable.ts index 6ae9ab4bf..ca4ec843f 100644 --- a/packages/contracts/test/test-utils/uups-upgradeable.ts +++ b/packages/contracts/test/test-utils/uups-upgradeable.ts @@ -3,7 +3,9 @@ import {expect} from 'chai'; import {Contract} from 'ethers'; import {defaultAbiCoder} from 'ethers/lib/utils'; import {ethers} from 'hardhat'; -import {IMPLEMENTATION_SLOT} from './oz-constants'; + +export const IMPLEMENTATION_SLOT = + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc'; /// Used as a common test suite to test upgradeability of the contracts. /// Presumes that `upgrade` object is set on `this` inside the actual test file. diff --git a/packages/contracts/test/token/erc20/governance-erc20.ts b/packages/contracts/test/token/erc20/governance-erc20.ts index 9be65b2ad..dac310695 100644 --- a/packages/contracts/test/token/erc20/governance-erc20.ts +++ b/packages/contracts/test/token/erc20/governance-erc20.ts @@ -9,7 +9,7 @@ import { IERC165Upgradeable__factory, } from '../../../typechain'; import {deployNewDAO} from '../../test-utils/dao'; -import {OZ_ERRORS} from '../../test-utils/oz-constants'; +import {OZ_ERRORS} from '../../test-utils/error'; import {getInterfaceID} from '../../test-utils/interfaces'; export type MintSettings = { diff --git a/packages/contracts/test/token/erc20/governance-wrapped-erc20.ts b/packages/contracts/test/token/erc20/governance-wrapped-erc20.ts index d661fe7ac..dc8f94ed1 100644 --- a/packages/contracts/test/token/erc20/governance-wrapped-erc20.ts +++ b/packages/contracts/test/token/erc20/governance-wrapped-erc20.ts @@ -9,7 +9,7 @@ import { GovernanceWrappedERC20__factory, IERC165Upgradeable__factory, } from '../../../typechain'; -import {OZ_ERRORS} from '../../test-utils/oz-constants'; +import {OZ_ERRORS} from '../../test-utils/error'; import {getInterfaceID} from '../../test-utils/interfaces'; export type AccountBalance = {account: string; amount: number}; diff --git a/packages/contracts/utils/storage.ts b/packages/contracts/utils/storage.ts index b56ff2842..983342026 100644 --- a/packages/contracts/utils/storage.ts +++ b/packages/contracts/utils/storage.ts @@ -1,8 +1,8 @@ import {ethers} from 'hardhat'; -import {IMPLEMENTATION_SLOT} from '../test/test-utils/oz-constants'; - import {defaultAbiCoder} from 'ethers/lib/utils'; +import {IMPLEMENTATION_SLOT} from '../test/test-utils/uups-upgradeable'; + export async function readImplementationValuesFromSlot( contractAddresses: string[] ): Promise { From 360079c7691dc47092eef215e3e86892ccfc45ac Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 19 Apr 2023 14:50:08 +0200 Subject: [PATCH 010/112] fix: remove redundant includes --- packages/contracts/test/upgrade/dao.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 8e1334f20..a9fda8c6d 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -2,14 +2,7 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; -import { - DAOFactory__factory, - PluginRepo__factory, - DAORegistry__factory, - DAO__factory, - DAOV100, - DAOV100__factory, -} from '../../typechain'; +import {DAO__factory, DAOV100, DAOV100__factory} from '../../typechain'; import {daoExampleURI} from '../test-utils/dao'; From 1b14d420e47110856a45a642375ac4dc1dd7928d Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 25 Apr 2023 12:20:33 +0300 Subject: [PATCH 011/112] prepare package --- .../contracts-versions/commit_hashes.json | 8 ++ .../create-contract-versions.js | 61 ++++++++++ packages/contracts-versions/npm/index.ts | 0 packages/contracts-versions/package.json | 18 +++ packages/contracts-versions/rollup.config.js | 16 +++ packages/contracts-versions/tsconfig.json | 11 ++ yarn.lock | 111 +++++++++++++++++- 7 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 packages/contracts-versions/commit_hashes.json create mode 100644 packages/contracts-versions/create-contract-versions.js create mode 100644 packages/contracts-versions/npm/index.ts create mode 100644 packages/contracts-versions/package.json create mode 100644 packages/contracts-versions/rollup.config.js create mode 100644 packages/contracts-versions/tsconfig.json diff --git a/packages/contracts-versions/commit_hashes.json b/packages/contracts-versions/commit_hashes.json new file mode 100644 index 000000000..2ab5a1722 --- /dev/null +++ b/packages/contracts-versions/commit_hashes.json @@ -0,0 +1,8 @@ +{ + "versions": [ + { + "name": "v0.1", + "commit": "cb0621d" + } + ] +} diff --git a/packages/contracts-versions/create-contract-versions.js b/packages/contracts-versions/create-contract-versions.js new file mode 100644 index 000000000..7c11a591f --- /dev/null +++ b/packages/contracts-versions/create-contract-versions.js @@ -0,0 +1,61 @@ +const fs = require('fs-extra'); +const path = require('path'); +const util = require('util'); +const exec = util.promisify(require('child_process').exec); + +const contractsDir = path.join(__dirname, '../contracts'); +const contractVersionsDir = __dirname; +const commitHashes = require('./commit_hashes.json'); + +async function buildContracts(commit) { + try { + await exec(`git checkout ${commit}`, {cwd: contractsDir}); + await exec('yarn build', {cwd: contractsDir}); + } catch (error) { + console.error('Error building contracts:', error); + } +} + +async function copyContracts(commit, versionName) { + try { + const srcArtifacts = path.join(contractsDir, 'artifacts'); + const destArtifacts = path.join( + contractVersionsDir, + versionName, + 'artifacts' + ); + await fs.copy(srcArtifacts, destArtifacts); + + const srcContracts = path.join(contractsDir, 'contracts'); + const destContracts = path.join( + contractVersionsDir, + versionName, + 'contracts' + ); + await fs.copy(srcContracts, destContracts, { + filter: src => src.endsWith('.sol'), + }); + + const srcActiveContracts = path.join(contractsDir, 'active_contracts.json'); + const destActiveContracts = path.join( + contractVersionsDir, + versionName, + 'active_contracts.json' + ); + await fs.copy(srcActiveContracts, destActiveContracts); + } catch (error) { + console.error('Error copying contracts:', error); + } +} + +async function createVersions() { + for (const version of commitHashes.versions) { + await buildContracts(version.commit); + await copyContracts(version.commit, version.name); + } + + // Return to the original branch + await exec('git checkout HEAD', {cwd: contractsDir}); +} + +createVersions(); diff --git a/packages/contracts-versions/npm/index.ts b/packages/contracts-versions/npm/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/contracts-versions/package.json b/packages/contracts-versions/package.json new file mode 100644 index 000000000..c8c3b647c --- /dev/null +++ b/packages/contracts-versions/package.json @@ -0,0 +1,18 @@ +{ + "name": "contracts-versions", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "scripts": { + "build:contracts": "node create-contract-versions.js", + "build:npm": "rollup --config rollup.config.js", + "build": "yarn build:contracts && yarn build:npm" + }, + "devDependencies": { + "@types/node": "^18.16.0", + "fs-extra": "^11.1.1", + "rollup": "^3.21.0", + "rollup-plugin-typescript2": "^0.34.1", + "typescript": "^5.0.4" + } +} diff --git a/packages/contracts-versions/rollup.config.js b/packages/contracts-versions/rollup.config.js new file mode 100644 index 000000000..40c160051 --- /dev/null +++ b/packages/contracts-versions/rollup.config.js @@ -0,0 +1,16 @@ +import typescript from 'rollup-plugin-typescript2'; + +export default { + input: './npm/index.ts', + output: [ + { + file: './dist/index.js', + format: 'cjs', + }, + { + file: './dist/index.esm.js', + format: 'esm', + }, + ], + plugins: [typescript()], +}; diff --git a/packages/contracts-versions/tsconfig.json b/packages/contracts-versions/tsconfig.json new file mode 100644 index 000000000..77801b084 --- /dev/null +++ b/packages/contracts-versions/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "module": "ESNext", + "target": "ES2018", + "moduleResolution": "node", + "strict": true, + "esModuleInterop": true, + "outDir": "dist" + }, + "include": ["src/**/*.ts"] +} diff --git a/yarn.lock b/yarn.lock index 7ae65e7fe..8d719fa4f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1768,6 +1768,14 @@ estree-walker "^1.0.1" picomatch "^2.2.2" +"@rollup/pluginutils@^4.1.2": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" + integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== + dependencies: + estree-walker "^2.0.1" + picomatch "^2.2.2" + "@scure/base@~1.1.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" @@ -2152,6 +2160,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.37.tgz#abb38afa9d6e8a2f627a8cb52290b3c80fbe61ed" integrity sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA== +"@types/node@^18.16.0": + version "18.16.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.0.tgz#4668bc392bb6938637b47e98b1f2ed5426f33316" + integrity sha512-BsAaKhB+7X+H4GnSjGhJG9Qi8Tw+inU9nJDwmD5CgOmBLEI6ArdhikpLX7DjbjDRDTbqZzU2LSQNZg8WGPiSZQ== + "@types/node@^8.0.0": version "8.10.66" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" @@ -3681,6 +3694,11 @@ commander@^2.15.0, commander@^2.20.3: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + compare-versions@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-5.0.1.tgz#14c6008436d994c3787aba38d4087fabe858555e" @@ -4798,6 +4816,11 @@ estree-walker@^1.0.1: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== +estree-walker@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -5353,6 +5376,15 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" +find-cache-dir@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + find-replace@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-1.0.3.tgz#b88e7364d2d9c959559f388c66670d6130441fa0" @@ -5398,6 +5430,14 @@ find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + flat-cache@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" @@ -5551,6 +5591,15 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" + integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^4.0.2: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" @@ -7468,6 +7517,13 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -7674,6 +7730,13 @@ magic-string@^0.26.1: dependencies: sourcemap-codec "^1.4.8" +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" @@ -8597,7 +8660,7 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0: +p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== @@ -8625,6 +8688,13 @@ p-locate@^3.0.0: dependencies: p-limit "^2.0.0" +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + p-locate@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" @@ -8914,6 +8984,13 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + pkginfo@0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff" @@ -9561,6 +9638,17 @@ rollup-plugin-dts@^4.2.0: optionalDependencies: "@babel/code-frame" "^7.16.7" +rollup-plugin-typescript2@^0.34.1: + version "0.34.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.34.1.tgz#c457f155a71d133c142689213fce78694e30d0be" + integrity sha512-P4cHLtGikESmqi1CA+tdMDUv8WbQV48mzPYt77TSTOPJpERyZ9TXdDgjSDix8Fkqce6soYz3+fa4lrC93IEkcw== + dependencies: + "@rollup/pluginutils" "^4.1.2" + find-cache-dir "^3.3.2" + fs-extra "^10.0.0" + semver "^7.3.7" + tslib "^2.4.0" + rollup@^2.70.1: version "2.70.1" resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.70.1.tgz#824b1f1f879ea396db30b0fc3ae8d2fead93523e" @@ -9568,6 +9656,13 @@ rollup@^2.70.1: optionalDependencies: fsevents "~2.3.2" +rollup@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.21.0.tgz#0a71517db56e150222670f88e5e7acfa4fede7c8" + integrity sha512-ANPhVcyeHvYdQMUyCbczy33nbLzI7RzrBje4uvNiTDJGIMtlKoOStmympwr9OtS1LZxiDmE2wvxHyVhoLtf1KQ== + optionalDependencies: + fsevents "~2.3.2" + rsa-pem-to-jwk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/rsa-pem-to-jwk/-/rsa-pem-to-jwk-1.1.3.tgz#245e76bdb7e7234cfee7ca032d31b54c38fab98e" @@ -9701,11 +9796,18 @@ semver@7.3.5, semver@^7.0.0, semver@^7.2.1, semver@^7.3.4, semver@^7.3.5: dependencies: lru-cache "^6.0.0" -semver@^6.1.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.3.7: + version "7.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0" + integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== + dependencies: + lru-cache "^6.0.0" + semver@^7.3.8: version "7.3.8" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" @@ -10796,6 +10898,11 @@ typescript@^4.9.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + typical@^2.6.0, typical@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" From 9d73698c384de29436278bb439ee408f947d2709 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 25 Apr 2023 12:39:18 +0300 Subject: [PATCH 012/112] remember the branch --- .../contracts-versions/create-contract-versions.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/contracts-versions/create-contract-versions.js b/packages/contracts-versions/create-contract-versions.js index 7c11a591f..433aac39f 100644 --- a/packages/contracts-versions/create-contract-versions.js +++ b/packages/contracts-versions/create-contract-versions.js @@ -4,9 +4,14 @@ const util = require('util'); const exec = util.promisify(require('child_process').exec); const contractsDir = path.join(__dirname, '../contracts'); -const contractVersionsDir = __dirname; +const contractVersionsDir = path.join(__dirname, 'dist'); const commitHashes = require('./commit_hashes.json'); +async function getCurrentBranch() { + const {stdout} = await exec('git branch --show-current', {cwd: contractsDir}); + return stdout.trim(); +} + async function buildContracts(commit) { try { await exec(`git checkout ${commit}`, {cwd: contractsDir}); @@ -49,13 +54,15 @@ async function copyContracts(commit, versionName) { } async function createVersions() { + const currentBranch = await getCurrentBranch(); + for (const version of commitHashes.versions) { await buildContracts(version.commit); await copyContracts(version.commit, version.name); } // Return to the original branch - await exec('git checkout HEAD', {cwd: contractsDir}); + await exec(`git checkout ${currentBranch}`, {cwd: contractsDir}); } createVersions(); From fe9fe0fd008d4466fea20a382ca859ad50f4c033 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 25 Apr 2023 12:41:32 +0300 Subject: [PATCH 013/112] only artifact src --- packages/contracts-versions/create-contract-versions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-versions/create-contract-versions.js b/packages/contracts-versions/create-contract-versions.js index 433aac39f..1e849ebd8 100644 --- a/packages/contracts-versions/create-contract-versions.js +++ b/packages/contracts-versions/create-contract-versions.js @@ -23,7 +23,7 @@ async function buildContracts(commit) { async function copyContracts(commit, versionName) { try { - const srcArtifacts = path.join(contractsDir, 'artifacts'); + const srcArtifacts = path.join(contractsDir, 'artifacts/src'); const destArtifacts = path.join( contractVersionsDir, versionName, From c8f10de122150e04aebec1161e79a07cf218e880 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 25 Apr 2023 12:46:42 +0300 Subject: [PATCH 014/112] correct the paths --- packages/contracts-versions/create-contract-versions.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/contracts-versions/create-contract-versions.js b/packages/contracts-versions/create-contract-versions.js index 1e849ebd8..aa2f87a95 100644 --- a/packages/contracts-versions/create-contract-versions.js +++ b/packages/contracts-versions/create-contract-versions.js @@ -3,7 +3,8 @@ const path = require('path'); const util = require('util'); const exec = util.promisify(require('child_process').exec); -const contractsDir = path.join(__dirname, '../contracts'); +const monorepoRoot = path.join(__dirname, '..'); +const contractsDir = path.join(monorepoRoot, 'contracts'); const contractVersionsDir = path.join(__dirname, 'dist'); const commitHashes = require('./commit_hashes.json'); @@ -31,7 +32,7 @@ async function copyContracts(commit, versionName) { ); await fs.copy(srcArtifacts, destArtifacts); - const srcContracts = path.join(contractsDir, 'contracts'); + const srcContracts = path.join(contractsDir, 'src'); const destContracts = path.join( contractVersionsDir, versionName, @@ -41,7 +42,7 @@ async function copyContracts(commit, versionName) { filter: src => src.endsWith('.sol'), }); - const srcActiveContracts = path.join(contractsDir, 'active_contracts.json'); + const srcActiveContracts = path.join(monorepoRoot, 'active_contracts.json'); const destActiveContracts = path.join( contractVersionsDir, versionName, From c878bf451b418523caf406077159d9823d930c27 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 25 Apr 2023 12:55:16 +0300 Subject: [PATCH 015/112] correct root path --- packages/contracts-versions/create-contract-versions.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/contracts-versions/create-contract-versions.js b/packages/contracts-versions/create-contract-versions.js index aa2f87a95..b88d91cb1 100644 --- a/packages/contracts-versions/create-contract-versions.js +++ b/packages/contracts-versions/create-contract-versions.js @@ -3,8 +3,8 @@ const path = require('path'); const util = require('util'); const exec = util.promisify(require('child_process').exec); -const monorepoRoot = path.join(__dirname, '..'); -const contractsDir = path.join(monorepoRoot, 'contracts'); +const monorepoRoot = path.join(__dirname, '../..'); +const contractsDir = path.join(monorepoRoot, 'packages/contracts'); const contractVersionsDir = path.join(__dirname, 'dist'); const commitHashes = require('./commit_hashes.json'); @@ -33,14 +33,13 @@ async function copyContracts(commit, versionName) { await fs.copy(srcArtifacts, destArtifacts); const srcContracts = path.join(contractsDir, 'src'); + console.log('copy contracts = ', srcContracts); const destContracts = path.join( contractVersionsDir, versionName, 'contracts' ); - await fs.copy(srcContracts, destContracts, { - filter: src => src.endsWith('.sol'), - }); + await fs.copy(srcContracts, destContracts); const srcActiveContracts = path.join(monorepoRoot, 'active_contracts.json'); const destActiveContracts = path.join( From f319e0cf47b7c70b93fb7de96e69adfe3999db74 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 25 Apr 2023 13:02:39 +0300 Subject: [PATCH 016/112] update hashes --- packages/contracts-versions/commit_hashes.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/contracts-versions/commit_hashes.json b/packages/contracts-versions/commit_hashes.json index 2ab5a1722..f15e5bc78 100644 --- a/packages/contracts-versions/commit_hashes.json +++ b/packages/contracts-versions/commit_hashes.json @@ -1,8 +1,16 @@ { "versions": [ { - "name": "v0.1", - "commit": "cb0621d" + "name": "v0.7.0-alpha", + "commit": "9b912728c315f983af8c4bfd1f8d07021996563f" + }, + { + "name": "v1.0.0-mainnet-goerli", + "commit": "c2b9d23a96654e81f22fbf91e6f334ef26a370af" + }, + { + "name": "v1.0.0-mumbai", + "commit": "9485d97301611cfc78faa4bd00eb54abb6dd2d5e" } ] } From 35752585adbfa71e62e159b51fdd142903103d88 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 25 Apr 2023 13:11:04 +0300 Subject: [PATCH 017/112] add logs --- packages/contracts-versions/create-contract-versions.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/contracts-versions/create-contract-versions.js b/packages/contracts-versions/create-contract-versions.js index b88d91cb1..25f302d87 100644 --- a/packages/contracts-versions/create-contract-versions.js +++ b/packages/contracts-versions/create-contract-versions.js @@ -24,6 +24,7 @@ async function buildContracts(commit) { async function copyContracts(commit, versionName) { try { + console.log(`Copying artifacts`); const srcArtifacts = path.join(contractsDir, 'artifacts/src'); const destArtifacts = path.join( contractVersionsDir, @@ -32,8 +33,8 @@ async function copyContracts(commit, versionName) { ); await fs.copy(srcArtifacts, destArtifacts); + console.log(`Copying contracts`); const srcContracts = path.join(contractsDir, 'src'); - console.log('copy contracts = ', srcContracts); const destContracts = path.join( contractVersionsDir, versionName, @@ -41,6 +42,7 @@ async function copyContracts(commit, versionName) { ); await fs.copy(srcContracts, destContracts); + console.log(`Copying active_contracts.json`); const srcActiveContracts = path.join(monorepoRoot, 'active_contracts.json'); const destActiveContracts = path.join( contractVersionsDir, @@ -57,6 +59,9 @@ async function createVersions() { const currentBranch = await getCurrentBranch(); for (const version of commitHashes.versions) { + console.log( + `Building contracts for version: ${version.name}, with commit: ${version.commit}` + ); await buildContracts(version.commit); await copyContracts(version.commit, version.name); } From 1c6b6f87e924d10f45ff1895914d9379b0ef4392 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:11:45 +0300 Subject: [PATCH 018/112] only copy typechain --- packages/contracts-versions/.gitignore | 0 .../create-contract-versions.js | 17 ++++------------ packages/contracts-versions/npm/index.ts | 2 ++ packages/contracts-versions/rollup.config.js | 20 +++++++------------ 4 files changed, 13 insertions(+), 26 deletions(-) create mode 100644 packages/contracts-versions/.gitignore diff --git a/packages/contracts-versions/.gitignore b/packages/contracts-versions/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/packages/contracts-versions/create-contract-versions.js b/packages/contracts-versions/create-contract-versions.js index 25f302d87..26851055d 100644 --- a/packages/contracts-versions/create-contract-versions.js +++ b/packages/contracts-versions/create-contract-versions.js @@ -24,23 +24,14 @@ async function buildContracts(commit) { async function copyContracts(commit, versionName) { try { - console.log(`Copying artifacts`); - const srcArtifacts = path.join(contractsDir, 'artifacts/src'); - const destArtifacts = path.join( - contractVersionsDir, - versionName, - 'artifacts' - ); - await fs.copy(srcArtifacts, destArtifacts); - - console.log(`Copying contracts`); - const srcContracts = path.join(contractsDir, 'src'); - const destContracts = path.join( + console.log(`Copying typechain`); + const srcTypechain = path.join(contractsDir, 'typechain'); + const destTypechain = path.join( contractVersionsDir, versionName, 'contracts' ); - await fs.copy(srcContracts, destContracts); + await fs.copy(srcTypechain, destTypechain); console.log(`Copying active_contracts.json`); const srcActiveContracts = path.join(monorepoRoot, 'active_contracts.json'); diff --git a/packages/contracts-versions/npm/index.ts b/packages/contracts-versions/npm/index.ts index e69de29bb..866833951 100644 --- a/packages/contracts-versions/npm/index.ts +++ b/packages/contracts-versions/npm/index.ts @@ -0,0 +1,2 @@ +// Import and export the generated contract versions +export * from '../dist'; diff --git a/packages/contracts-versions/rollup.config.js b/packages/contracts-versions/rollup.config.js index 40c160051..476e2d85f 100644 --- a/packages/contracts-versions/rollup.config.js +++ b/packages/contracts-versions/rollup.config.js @@ -1,16 +1,10 @@ -import typescript from 'rollup-plugin-typescript2'; +import json from 'rollup-plugin-json'; export default { - input: './npm/index.ts', - output: [ - { - file: './dist/index.js', - format: 'cjs', - }, - { - file: './dist/index.esm.js', - format: 'esm', - }, - ], - plugins: [typescript()], + input: 'index.js', + output: { + dir: 'dist', + format: 'cjs', + }, + plugins: [json()], }; From 9f961ccd2f14c72d9773fec559817a1569c452c6 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:36:21 +0300 Subject: [PATCH 019/112] generate typechain --- .../create-contract-versions.js | 24 +++++++++++++------ packages/contracts-versions/npm/index.ts | 2 +- packages/contracts-versions/package.json | 2 ++ yarn.lock | 24 +++++++++++++++++++ 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/packages/contracts-versions/create-contract-versions.js b/packages/contracts-versions/create-contract-versions.js index 26851055d..bdaab0fb7 100644 --- a/packages/contracts-versions/create-contract-versions.js +++ b/packages/contracts-versions/create-contract-versions.js @@ -5,7 +5,7 @@ const exec = util.promisify(require('child_process').exec); const monorepoRoot = path.join(__dirname, '../..'); const contractsDir = path.join(monorepoRoot, 'packages/contracts'); -const contractVersionsDir = path.join(__dirname, 'dist'); +const contractVersionsDir = path.join(__dirname, 'build'); const commitHashes = require('./commit_hashes.json'); async function getCurrentBranch() { @@ -22,17 +22,26 @@ async function buildContracts(commit) { } } -async function copyContracts(commit, versionName) { +async function generateTypechain(commit, versionName) { try { - console.log(`Copying typechain`); - const srcTypechain = path.join(contractsDir, 'typechain'); + const srcArtifacts = path.join(contractsDir, 'artifacts/src'); const destTypechain = path.join( contractVersionsDir, versionName, 'contracts' ); - await fs.copy(srcTypechain, destTypechain); + await exec( + `find ${srcArtifacts} -name '*.json' -type f | grep -v '.dbg.json' | xargs typechain --target ethers-v5 --out-dir ${destTypechain}`, + {cwd: contractsDir} + ); + } catch (error) { + console.error('Error generating TypeChain output:', error); + } +} + +async function copyActiveContracts(versionName) { + try { console.log(`Copying active_contracts.json`); const srcActiveContracts = path.join(monorepoRoot, 'active_contracts.json'); const destActiveContracts = path.join( @@ -42,7 +51,7 @@ async function copyContracts(commit, versionName) { ); await fs.copy(srcActiveContracts, destActiveContracts); } catch (error) { - console.error('Error copying contracts:', error); + console.error('Error copying active_contracts.json:', error); } } @@ -54,7 +63,8 @@ async function createVersions() { `Building contracts for version: ${version.name}, with commit: ${version.commit}` ); await buildContracts(version.commit); - await copyContracts(version.commit, version.name); + await generateTypechain(version.commit, version.name); + await copyActiveContracts(version.name); } // Return to the original branch diff --git a/packages/contracts-versions/npm/index.ts b/packages/contracts-versions/npm/index.ts index 866833951..481e5bf1a 100644 --- a/packages/contracts-versions/npm/index.ts +++ b/packages/contracts-versions/npm/index.ts @@ -1,2 +1,2 @@ // Import and export the generated contract versions -export * from '../dist'; +export * from '../build'; diff --git a/packages/contracts-versions/package.json b/packages/contracts-versions/package.json index c8c3b647c..e80bb66e2 100644 --- a/packages/contracts-versions/package.json +++ b/packages/contracts-versions/package.json @@ -9,10 +9,12 @@ "build": "yarn build:contracts && yarn build:npm" }, "devDependencies": { + "@typechain/ethers-v5": "^10.2.0", "@types/node": "^18.16.0", "fs-extra": "^11.1.1", "rollup": "^3.21.0", "rollup-plugin-typescript2": "^0.34.1", + "typechain": "^8.1.1", "typescript": "^5.0.4" } } diff --git a/yarn.lock b/yarn.lock index 8d719fa4f..b94c66ed2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2001,6 +2001,14 @@ lodash "^4.17.15" ts-essentials "^7.0.1" +"@typechain/ethers-v5@^10.2.0": + version "10.2.0" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.2.0.tgz#68f5963efb5214cb2d881477228e4b5b315473e1" + integrity sha512-ikaq0N/w9fABM+G01OFmU3U3dNnyRwEahkdvi9mqy1a3XwKiPZaF/lu54OcNaEWnpvEYyhhS0N7buCtLQqC92w== + dependencies: + lodash "^4.17.15" + ts-essentials "^7.0.1" + "@typechain/ethers-v5@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-7.2.0.tgz#d559cffe0efe6bdbc20e644b817f6fa8add5e8f8" @@ -10876,6 +10884,22 @@ typechain@^8.0.0: ts-command-line-args "^2.2.0" ts-essentials "^7.0.1" +typechain@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.1.1.tgz#9c2e8012c2c4c586536fc18402dcd7034c4ff0bd" + integrity sha512-uF/sUvnXTOVF2FHKhQYnxHk4su4JjZR8vr4mA2mBaRwHTbwh0jIlqARz9XJr1tA0l7afJGvEa1dTSi4zt039LQ== + dependencies: + "@types/prettier" "^2.1.1" + debug "^4.3.1" + fs-extra "^7.0.0" + glob "7.1.7" + js-sha3 "^0.8.0" + lodash "^4.17.15" + mkdirp "^1.0.4" + prettier "^2.3.1" + ts-command-line-args "^2.2.0" + ts-essentials "^7.0.1" + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" From e8d659029faf811cee357b54413c3086a90c8f4f Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:47:34 +0300 Subject: [PATCH 020/112] setup rollup --- packages/contracts-versions/package.json | 4 +- packages/contracts-versions/rollup.config.js | 10 ----- packages/contracts-versions/rollup.config.ts | 30 +++++++++++++ packages/contracts-versions/tsconfig.json | 14 +++--- yarn.lock | 47 +++++++++++++++++++- 5 files changed, 87 insertions(+), 18 deletions(-) delete mode 100644 packages/contracts-versions/rollup.config.js create mode 100644 packages/contracts-versions/rollup.config.ts diff --git a/packages/contracts-versions/package.json b/packages/contracts-versions/package.json index e80bb66e2..d65127eec 100644 --- a/packages/contracts-versions/package.json +++ b/packages/contracts-versions/package.json @@ -5,15 +5,17 @@ "license": "MIT", "scripts": { "build:contracts": "node create-contract-versions.js", - "build:npm": "rollup --config rollup.config.js", + "build:npm": "rollup --config rollup.config.ts", "build": "yarn build:contracts && yarn build:npm" }, "devDependencies": { + "@rollup/plugin-typescript": "^11.1.0", "@typechain/ethers-v5": "^10.2.0", "@types/node": "^18.16.0", "fs-extra": "^11.1.1", "rollup": "^3.21.0", "rollup-plugin-typescript2": "^0.34.1", + "tslib": "^2.5.0", "typechain": "^8.1.1", "typescript": "^5.0.4" } diff --git a/packages/contracts-versions/rollup.config.js b/packages/contracts-versions/rollup.config.js deleted file mode 100644 index 476e2d85f..000000000 --- a/packages/contracts-versions/rollup.config.js +++ /dev/null @@ -1,10 +0,0 @@ -import json from 'rollup-plugin-json'; - -export default { - input: 'index.js', - output: { - dir: 'dist', - format: 'cjs', - }, - plugins: [json()], -}; diff --git a/packages/contracts-versions/rollup.config.ts b/packages/contracts-versions/rollup.config.ts new file mode 100644 index 000000000..6d3c76b70 --- /dev/null +++ b/packages/contracts-versions/rollup.config.ts @@ -0,0 +1,30 @@ +import typescript from '@rollup/plugin-typescript'; +import dts from 'rollup-plugin-dts'; +import json from '@rollup/plugin-json'; + +export default [ + { + input: 'npm/index.ts', + plugins: [typescript({project: './tsconfig.json'}), json()], + output: [ + { + file: 'dist/bundle-cjs.js', + format: 'cjs', + }, + { + file: 'dist/bundle-esm.js', + format: 'es', + }, + ], + }, + { + input: 'npm/index.ts', + plugins: [dts()], + output: [ + { + file: 'dist/bundle.d.ts', + format: 'es', + }, + ], + }, +]; diff --git a/packages/contracts-versions/tsconfig.json b/packages/contracts-versions/tsconfig.json index 77801b084..7c17bb795 100644 --- a/packages/contracts-versions/tsconfig.json +++ b/packages/contracts-versions/tsconfig.json @@ -1,11 +1,15 @@ { "compilerOptions": { - "module": "ESNext", - "target": "ES2018", - "moduleResolution": "node", + "target": "es2018", + "module": "esnext", "strict": true, "esModuleInterop": true, - "outDir": "dist" + "outDir": "dist", + "declaration": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "rootDir": "../../" }, - "include": ["src/**/*.ts"] + "include": ["./npm", "/types"], + "files": ["./npm/index.ts"] } diff --git a/yarn.lock b/yarn.lock index b94c66ed2..42d8edf09 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1751,6 +1751,14 @@ dependencies: "@rollup/pluginutils" "^3.0.8" +"@rollup/plugin-typescript@^11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-11.1.0.tgz#4dd2a98475a791200d3e4dd1b8234073ad96c535" + integrity sha512-86flrfE+bSHB69znnTV6kVjkncs2LBMhcTCyxWgRxLyfXfQrxg4UwlAqENnjrrxnSNS/XKCDJCl8EkdFJVHOxw== + dependencies: + "@rollup/pluginutils" "^5.0.1" + resolve "^1.22.1" + "@rollup/plugin-typescript@^8.3.1": version "8.3.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-8.3.1.tgz#b7dc75ed6b4876e260b9e80624fab23bc98e4ac1" @@ -1776,6 +1784,15 @@ estree-walker "^2.0.1" picomatch "^2.2.2" +"@rollup/pluginutils@^5.0.1": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33" + integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" + "@scure/base@~1.1.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" @@ -2079,6 +2096,11 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== +"@types/estree@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== + "@types/express-serve-static-core@^4.17.9": version "4.17.28" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" @@ -4824,7 +4846,7 @@ estree-walker@^1.0.1: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== -estree-walker@^2.0.1: +estree-walker@^2.0.1, estree-walker@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== @@ -6791,6 +6813,13 @@ is-circular@^1.0.2: resolved "https://registry.yarnpkg.com/is-circular/-/is-circular-1.0.2.tgz#2e0ab4e9835f4c6b0ea2b9855a84acd501b8366c" integrity sha512-YttjnrswnUYRVJvxCvu8z+PGMUSzC2JttP0OEXezlAEdp3EXzhf7IZ3j0gRAybJBQupedIZFhY61Tga6E0qASA== +is-core-module@^2.11.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" + integrity sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== + dependencies: + has "^1.0.3" + is-core-module@^2.2.0, is-core-module@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" @@ -8958,7 +8987,7 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== -picomatch@^2.2.2: +picomatch@^2.2.2, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -9558,6 +9587,15 @@ resolve@^1.17.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.22.1: + version "1.22.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + dependencies: + is-core-module "^2.11.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -10766,6 +10804,11 @@ tslib@^2.4.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +tslib@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" + integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== + tsort@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" From 930b4369d0ae5b0dbb507971f48aa348cb9253f9 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 25 Apr 2023 17:26:19 +0300 Subject: [PATCH 021/112] update npm packages --- .../create-contract-versions.js | 8 +- packages/contracts-versions/npm/index.ts | 9 +- packages/contracts-versions/package.json | 18 +- packages/contracts-versions/tsconfig.json | 2 +- yarn.lock | 180 +----------------- 5 files changed, 23 insertions(+), 194 deletions(-) diff --git a/packages/contracts-versions/create-contract-versions.js b/packages/contracts-versions/create-contract-versions.js index bdaab0fb7..e38524c06 100644 --- a/packages/contracts-versions/create-contract-versions.js +++ b/packages/contracts-versions/create-contract-versions.js @@ -25,14 +25,10 @@ async function buildContracts(commit) { async function generateTypechain(commit, versionName) { try { const srcArtifacts = path.join(contractsDir, 'artifacts/src'); - const destTypechain = path.join( - contractVersionsDir, - versionName, - 'contracts' - ); + const destTypechain = path.join(contractVersionsDir, versionName, 'types'); await exec( - `find ${srcArtifacts} -name '*.json' -type f | grep -v '.dbg.json' | xargs typechain --target ethers-v5 --out-dir ${destTypechain}`, + `find ${srcArtifacts} -name '*.json' -type f | grep -v '.dbg.json' | xargs typechain --target=ethers-v5 --out-dir ${destTypechain}`, {cwd: contractsDir} ); } catch (error) { diff --git a/packages/contracts-versions/npm/index.ts b/packages/contracts-versions/npm/index.ts index 481e5bf1a..219b810e3 100644 --- a/packages/contracts-versions/npm/index.ts +++ b/packages/contracts-versions/npm/index.ts @@ -1,2 +1,9 @@ // Import and export the generated contract versions -export * from '../build'; +const versions = { + v0_7_0_alpha: () => import('../build/v0.7.0-alpha/contracts'), + v1_0_0_mainnet_goerli: () => + import('../build/v1.0.0-mainnet-goerli/contracts'), + // Add more versions here if needed +}; + +export default versions; diff --git a/packages/contracts-versions/package.json b/packages/contracts-versions/package.json index d65127eec..43a1d477a 100644 --- a/packages/contracts-versions/package.json +++ b/packages/contracts-versions/package.json @@ -9,14 +9,14 @@ "build": "yarn build:contracts && yarn build:npm" }, "devDependencies": { - "@rollup/plugin-typescript": "^11.1.0", - "@typechain/ethers-v5": "^10.2.0", - "@types/node": "^18.16.0", - "fs-extra": "^11.1.1", - "rollup": "^3.21.0", - "rollup-plugin-typescript2": "^0.34.1", - "tslib": "^2.5.0", - "typechain": "^8.1.1", - "typescript": "^5.0.4" + "@rollup/plugin-typescript": "^8.3.1", + "@typechain/ethers-v5": "^10.0.0", + "rollup": "^2.70.1", + "rollup-plugin-dts": "^4.2.0", + "typechain": "^8.0.0", + "typescript": "^4.4.4" + }, + "dependencies": { + "ethers": "^5.6.2" } } diff --git a/packages/contracts-versions/tsconfig.json b/packages/contracts-versions/tsconfig.json index 7c17bb795..167010b1f 100644 --- a/packages/contracts-versions/tsconfig.json +++ b/packages/contracts-versions/tsconfig.json @@ -10,6 +10,6 @@ "resolveJsonModule": true, "rootDir": "../../" }, - "include": ["./npm", "/types"], + "include": ["./npm", "/build"], "files": ["./npm/index.ts"] } diff --git a/yarn.lock b/yarn.lock index 42d8edf09..7ae65e7fe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1751,14 +1751,6 @@ dependencies: "@rollup/pluginutils" "^3.0.8" -"@rollup/plugin-typescript@^11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-11.1.0.tgz#4dd2a98475a791200d3e4dd1b8234073ad96c535" - integrity sha512-86flrfE+bSHB69znnTV6kVjkncs2LBMhcTCyxWgRxLyfXfQrxg4UwlAqENnjrrxnSNS/XKCDJCl8EkdFJVHOxw== - dependencies: - "@rollup/pluginutils" "^5.0.1" - resolve "^1.22.1" - "@rollup/plugin-typescript@^8.3.1": version "8.3.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-8.3.1.tgz#b7dc75ed6b4876e260b9e80624fab23bc98e4ac1" @@ -1776,23 +1768,6 @@ estree-walker "^1.0.1" picomatch "^2.2.2" -"@rollup/pluginutils@^4.1.2": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" - integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== - dependencies: - estree-walker "^2.0.1" - picomatch "^2.2.2" - -"@rollup/pluginutils@^5.0.1": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33" - integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA== - dependencies: - "@types/estree" "^1.0.0" - estree-walker "^2.0.2" - picomatch "^2.3.1" - "@scure/base@~1.1.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" @@ -2018,14 +1993,6 @@ lodash "^4.17.15" ts-essentials "^7.0.1" -"@typechain/ethers-v5@^10.2.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.2.0.tgz#68f5963efb5214cb2d881477228e4b5b315473e1" - integrity sha512-ikaq0N/w9fABM+G01OFmU3U3dNnyRwEahkdvi9mqy1a3XwKiPZaF/lu54OcNaEWnpvEYyhhS0N7buCtLQqC92w== - dependencies: - lodash "^4.17.15" - ts-essentials "^7.0.1" - "@typechain/ethers-v5@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-7.2.0.tgz#d559cffe0efe6bdbc20e644b817f6fa8add5e8f8" @@ -2096,11 +2063,6 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/estree@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" - integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== - "@types/express-serve-static-core@^4.17.9": version "4.17.28" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" @@ -2190,11 +2152,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.37.tgz#abb38afa9d6e8a2f627a8cb52290b3c80fbe61ed" integrity sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA== -"@types/node@^18.16.0": - version "18.16.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.0.tgz#4668bc392bb6938637b47e98b1f2ed5426f33316" - integrity sha512-BsAaKhB+7X+H4GnSjGhJG9Qi8Tw+inU9nJDwmD5CgOmBLEI6ArdhikpLX7DjbjDRDTbqZzU2LSQNZg8WGPiSZQ== - "@types/node@^8.0.0": version "8.10.66" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" @@ -3724,11 +3681,6 @@ commander@^2.15.0, commander@^2.20.3: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - compare-versions@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-5.0.1.tgz#14c6008436d994c3787aba38d4087fabe858555e" @@ -4846,11 +4798,6 @@ estree-walker@^1.0.1: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== -estree-walker@^2.0.1, estree-walker@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" - integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== - esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -5406,15 +5353,6 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -find-cache-dir@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - find-replace@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-1.0.3.tgz#b88e7364d2d9c959559f388c66670d6130441fa0" @@ -5460,14 +5398,6 @@ find-up@^2.1.0: dependencies: locate-path "^2.0.0" -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - flat-cache@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" @@ -5621,15 +5551,6 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" - integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs-extra@^4.0.2: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" @@ -6813,13 +6734,6 @@ is-circular@^1.0.2: resolved "https://registry.yarnpkg.com/is-circular/-/is-circular-1.0.2.tgz#2e0ab4e9835f4c6b0ea2b9855a84acd501b8366c" integrity sha512-YttjnrswnUYRVJvxCvu8z+PGMUSzC2JttP0OEXezlAEdp3EXzhf7IZ3j0gRAybJBQupedIZFhY61Tga6E0qASA== -is-core-module@^2.11.0: - version "2.12.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" - integrity sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== - dependencies: - has "^1.0.3" - is-core-module@^2.2.0, is-core-module@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" @@ -7554,13 +7468,6 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -7767,13 +7674,6 @@ magic-string@^0.26.1: dependencies: sourcemap-codec "^1.4.8" -make-dir@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" @@ -8697,7 +8597,7 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0, p-limit@^2.2.0: +p-limit@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== @@ -8725,13 +8625,6 @@ p-locate@^3.0.0: dependencies: p-limit "^2.0.0" -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - p-locate@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" @@ -8987,7 +8880,7 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== -picomatch@^2.2.2, picomatch@^2.3.1: +picomatch@^2.2.2: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -9021,13 +8914,6 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" -pkg-dir@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - pkginfo@0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff" @@ -9587,15 +9473,6 @@ resolve@^1.17.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^1.22.1: - version "1.22.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" - integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== - dependencies: - is-core-module "^2.11.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -9684,17 +9561,6 @@ rollup-plugin-dts@^4.2.0: optionalDependencies: "@babel/code-frame" "^7.16.7" -rollup-plugin-typescript2@^0.34.1: - version "0.34.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.34.1.tgz#c457f155a71d133c142689213fce78694e30d0be" - integrity sha512-P4cHLtGikESmqi1CA+tdMDUv8WbQV48mzPYt77TSTOPJpERyZ9TXdDgjSDix8Fkqce6soYz3+fa4lrC93IEkcw== - dependencies: - "@rollup/pluginutils" "^4.1.2" - find-cache-dir "^3.3.2" - fs-extra "^10.0.0" - semver "^7.3.7" - tslib "^2.4.0" - rollup@^2.70.1: version "2.70.1" resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.70.1.tgz#824b1f1f879ea396db30b0fc3ae8d2fead93523e" @@ -9702,13 +9568,6 @@ rollup@^2.70.1: optionalDependencies: fsevents "~2.3.2" -rollup@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.21.0.tgz#0a71517db56e150222670f88e5e7acfa4fede7c8" - integrity sha512-ANPhVcyeHvYdQMUyCbczy33nbLzI7RzrBje4uvNiTDJGIMtlKoOStmympwr9OtS1LZxiDmE2wvxHyVhoLtf1KQ== - optionalDependencies: - fsevents "~2.3.2" - rsa-pem-to-jwk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/rsa-pem-to-jwk/-/rsa-pem-to-jwk-1.1.3.tgz#245e76bdb7e7234cfee7ca032d31b54c38fab98e" @@ -9842,18 +9701,11 @@ semver@7.3.5, semver@^7.0.0, semver@^7.2.1, semver@^7.3.4, semver@^7.3.5: dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: +semver@^6.1.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.7: - version "7.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0" - integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== - dependencies: - lru-cache "^6.0.0" - semver@^7.3.8: version "7.3.8" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" @@ -10804,11 +10656,6 @@ tslib@^2.4.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== -tslib@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== - tsort@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" @@ -10927,22 +10774,6 @@ typechain@^8.0.0: ts-command-line-args "^2.2.0" ts-essentials "^7.0.1" -typechain@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.1.1.tgz#9c2e8012c2c4c586536fc18402dcd7034c4ff0bd" - integrity sha512-uF/sUvnXTOVF2FHKhQYnxHk4su4JjZR8vr4mA2mBaRwHTbwh0jIlqARz9XJr1tA0l7afJGvEa1dTSi4zt039LQ== - dependencies: - "@types/prettier" "^2.1.1" - debug "^4.3.1" - fs-extra "^7.0.0" - glob "7.1.7" - js-sha3 "^0.8.0" - lodash "^4.17.15" - mkdirp "^1.0.4" - prettier "^2.3.1" - ts-command-line-args "^2.2.0" - ts-essentials "^7.0.1" - typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -10965,11 +10796,6 @@ typescript@^4.9.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== -typescript@^5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" - integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== - typical@^2.6.0, typical@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" From 5db940ff5cb7800a2a50991a8c7a1f541c97e7af Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Wed, 26 Apr 2023 13:16:56 +0300 Subject: [PATCH 022/112] update rollup index --- .../contracts-versions/commit_hashes.json | 6 +-- .../create-contract-versions.js | 44 +++++++++++-------- packages/contracts-versions/npm/index.ts | 18 ++++++-- packages/contracts-versions/rollup.config.ts | 28 +++++------- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/packages/contracts-versions/commit_hashes.json b/packages/contracts-versions/commit_hashes.json index f15e5bc78..f26d6fcfa 100644 --- a/packages/contracts-versions/commit_hashes.json +++ b/packages/contracts-versions/commit_hashes.json @@ -1,15 +1,15 @@ { "versions": [ { - "name": "v0.7.0-alpha", + "name": "v0.7.0_alpha", "commit": "9b912728c315f983af8c4bfd1f8d07021996563f" }, { - "name": "v1.0.0-mainnet-goerli", + "name": "v1.0.0_mainnet_goerli", "commit": "c2b9d23a96654e81f22fbf91e6f334ef26a370af" }, { - "name": "v1.0.0-mumbai", + "name": "v1.0.0_mumbai", "commit": "9485d97301611cfc78faa4bd00eb54abb6dd2d5e" } ] diff --git a/packages/contracts-versions/create-contract-versions.js b/packages/contracts-versions/create-contract-versions.js index e38524c06..9576b8b0c 100644 --- a/packages/contracts-versions/create-contract-versions.js +++ b/packages/contracts-versions/create-contract-versions.js @@ -22,21 +22,7 @@ async function buildContracts(commit) { } } -async function generateTypechain(commit, versionName) { - try { - const srcArtifacts = path.join(contractsDir, 'artifacts/src'); - const destTypechain = path.join(contractVersionsDir, versionName, 'types'); - - await exec( - `find ${srcArtifacts} -name '*.json' -type f | grep -v '.dbg.json' | xargs typechain --target=ethers-v5 --out-dir ${destTypechain}`, - {cwd: contractsDir} - ); - } catch (error) { - console.error('Error generating TypeChain output:', error); - } -} - -async function copyActiveContracts(versionName) { +async function copyActiveContracts(commit, versionName) { try { console.log(`Copying active_contracts.json`); const srcActiveContracts = path.join(monorepoRoot, 'active_contracts.json'); @@ -47,7 +33,26 @@ async function copyActiveContracts(versionName) { ); await fs.copy(srcActiveContracts, destActiveContracts); } catch (error) { - console.error('Error copying active_contracts.json:', error); + console.error('Error copying active contracts:', error); + } +} + +async function generateTypechain(src, dest) { + try { + // Find all the .json files, excluding the .dbg.json files, in all subdirectories + const {stdout} = await exec( + `find "${src}" -name '*.json' -type f -not -path '*.dbg.json'` + ); + const jsonFiles = stdout + .trim() + .split('\n') + .map(file => `"${file}"`) + .join(' '); + + // Run typechain for all .json files at once + await exec(`typechain --target ethers-v5 --out-dir "${dest}" ${jsonFiles}`); + } catch (error) { + console.error('Error generating TypeChain output:', error); } } @@ -59,8 +64,11 @@ async function createVersions() { `Building contracts for version: ${version.name}, with commit: ${version.commit}` ); await buildContracts(version.commit); - await generateTypechain(version.commit, version.name); - await copyActiveContracts(version.name); + await copyActiveContracts(version.commit, version.name); + + const srcArtifacts = path.join(contractsDir, 'artifacts/src'); + const destTypechain = path.join(contractVersionsDir, version.name, 'types'); + await generateTypechain(srcArtifacts, destTypechain); } // Return to the original branch diff --git a/packages/contracts-versions/npm/index.ts b/packages/contracts-versions/npm/index.ts index 219b810e3..4c4dc0e65 100644 --- a/packages/contracts-versions/npm/index.ts +++ b/packages/contracts-versions/npm/index.ts @@ -1,8 +1,20 @@ // Import and export the generated contract versions const versions = { - v0_7_0_alpha: () => import('../build/v0.7.0-alpha/contracts'), - v1_0_0_mainnet_goerli: () => - import('../build/v1.0.0-mainnet-goerli/contracts'), + v0_7_0_alpha: { + types: () => import('../build/v0.7.0_alpha/types'), + active_contracts: () => + import('../build/v0.7.0_alpha/active_contracts.json'), + }, + v1_0_0_mainnet_goerli: { + types: () => import('../build/v1.0.0_mainnet_goerli/types'), + active_contracts: () => + import('../build/v1.0.0_mainnet_goerli/active_contracts.json'), + }, + v1_0_0_mumbai: { + types: () => import('../build/v1.0.0_mumbai/types'), + active_contracts: () => + import('../build/v1.0.0_mumbai/active_contracts.json'), + }, // Add more versions here if needed }; diff --git a/packages/contracts-versions/rollup.config.ts b/packages/contracts-versions/rollup.config.ts index 6d3c76b70..4aa98adc3 100644 --- a/packages/contracts-versions/rollup.config.ts +++ b/packages/contracts-versions/rollup.config.ts @@ -6,25 +6,21 @@ export default [ { input: 'npm/index.ts', plugins: [typescript({project: './tsconfig.json'}), json()], - output: [ - { - file: 'dist/bundle-cjs.js', - format: 'cjs', - }, - { - file: 'dist/bundle-esm.js', - format: 'es', - }, - ], + output: { + dir: 'dist', + entryFileNames: '[name]-[format].js', + format: 'esm', + exports: 'named', + chunkFileNames: 'chunks/[name]-[hash].js', + }, }, { input: 'npm/index.ts', plugins: [dts()], - output: [ - { - file: 'dist/bundle.d.ts', - format: 'es', - }, - ], + output: { + dir: 'dist', + entryFileNames: 'bundle.d.ts', + format: 'es', + }, }, ]; From 4dc131e1fe5ba2dea07438628ebf3eb854ede19d Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Wed, 26 Apr 2023 17:17:12 +0300 Subject: [PATCH 023/112] add esm cjs --- packages/contracts-versions/package.json | 21 +++++++++++++++--- packages/contracts-versions/rollup.config.ts | 23 ++++++++++++++------ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/packages/contracts-versions/package.json b/packages/contracts-versions/package.json index 43a1d477a..85fc66784 100644 --- a/packages/contracts-versions/package.json +++ b/packages/contracts-versions/package.json @@ -1,13 +1,28 @@ { - "name": "contracts-versions", + "name": "@aragon/osx-versions", "version": "1.0.0", - "main": "index.js", - "license": "MIT", + "description": "The Aragon OSx contract versions", + "main": "dist/index-cjs.js", + "module": "dist/index-esm.js", + "types": "dist/bundle.d.ts", + "publishConfig": { + "access": "public" + }, "scripts": { "build:contracts": "node create-contract-versions.js", "build:npm": "rollup --config rollup.config.ts", "build": "yarn build:contracts && yarn build:npm" }, + "repository": { + "type": "git", + "url": "git+https://github.com/aragon/osx.git" + }, + "author": "", + "license": "AGPL-3.0-or-later", + "bugs": { + "url": "https://github.com/aragon/osx/issues" + }, + "homepage": "https://github.com/aragon/osx#readme", "devDependencies": { "@rollup/plugin-typescript": "^8.3.1", "@typechain/ethers-v5": "^10.0.0", diff --git a/packages/contracts-versions/rollup.config.ts b/packages/contracts-versions/rollup.config.ts index 4aa98adc3..86c7ccbc0 100644 --- a/packages/contracts-versions/rollup.config.ts +++ b/packages/contracts-versions/rollup.config.ts @@ -6,13 +6,22 @@ export default [ { input: 'npm/index.ts', plugins: [typescript({project: './tsconfig.json'}), json()], - output: { - dir: 'dist', - entryFileNames: '[name]-[format].js', - format: 'esm', - exports: 'named', - chunkFileNames: 'chunks/[name]-[hash].js', - }, + output: [ + { + dir: 'dist', + entryFileNames: 'index-esm.js', + format: 'esm', + exports: 'named', + chunkFileNames: 'chunks/[name]-[hash].js', + }, + { + dir: 'dist', + entryFileNames: 'index-cjs.js', + format: 'cjs', + exports: 'named', + chunkFileNames: 'chunks/[name]-[hash].js', + }, + ], }, { input: 'npm/index.ts', From 6005f06250fd997d3580b0aeb056032f5888658a Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Wed, 26 Apr 2023 17:38:51 +0300 Subject: [PATCH 024/112] add readme --- packages/contracts-versions/README.md | 58 +++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 packages/contracts-versions/README.md diff --git a/packages/contracts-versions/README.md b/packages/contracts-versions/README.md new file mode 100644 index 000000000..5ac2d3f81 --- /dev/null +++ b/packages/contracts-versions/README.md @@ -0,0 +1,58 @@ +# Aragon OSx Contracts Versions + +A package to manage different contract versions and provide easy access to their ABI, types, and active contracts. + +## Installation + +```bash +npm install contracts-versions +``` + +or + +```bash +yarn add contracts-versions +``` + +## Usage + +```javascript +import versions from 'contracts-versions'; + +// Access specific contract version +const v0_7_0_alpha = versions.v0_7_0_alpha; + +// Get the types for a specific version +v0_7_0_alpha.types().then(types => { + // Use types here +}); + +// Get the active contracts for a specific version +v0_7_0_alpha.active_contracts().then(activeContracts => { + // Use active contracts here +}); +``` + +## Adding new contract versions + +1. Update `commit_hashes.json` with the new version name and the associated commit hash. +2. Run the `create-contract-versions.js` script to build and generate the new version: + +```bash +yarn build:contracts +``` + +3. Add the new version to the `versions` object in `npm/index.ts`. +4. Run the Rollup build process: + +```bash +yarn build:npm +``` + +## Contributing + +Contributions are welcome! Feel free to open a pull request or create an issue to report bugs or request features. + +## License + +This project is licensed under the AGPL-3.0-or-later License. From 748b382477c58a4a18fc5a6f47d4f83a9d764167 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Wed, 26 Apr 2023 17:55:47 +0300 Subject: [PATCH 025/112] remove gitIgnore --- packages/contracts-versions/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/contracts-versions/.gitignore diff --git a/packages/contracts-versions/.gitignore b/packages/contracts-versions/.gitignore deleted file mode 100644 index e69de29bb..000000000 From f9858c7ee3388a8691254f233d47bf5cc40f27e2 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Thu, 27 Apr 2023 16:13:29 +0300 Subject: [PATCH 026/112] update typechain --- packages/contracts-versions/package.json | 4 ++-- yarn.lock | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/contracts-versions/package.json b/packages/contracts-versions/package.json index 85fc66784..41d0d6328 100644 --- a/packages/contracts-versions/package.json +++ b/packages/contracts-versions/package.json @@ -25,10 +25,10 @@ "homepage": "https://github.com/aragon/osx#readme", "devDependencies": { "@rollup/plugin-typescript": "^8.3.1", - "@typechain/ethers-v5": "^10.0.0", + "@typechain/ethers-v5": "^10.2.0", "rollup": "^2.70.1", "rollup-plugin-dts": "^4.2.0", - "typechain": "^8.0.0", + "typechain": "^8.1.1", "typescript": "^4.4.4" }, "dependencies": { diff --git a/yarn.lock b/yarn.lock index 7ae65e7fe..900bf891c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1993,6 +1993,14 @@ lodash "^4.17.15" ts-essentials "^7.0.1" +"@typechain/ethers-v5@^10.2.0": + version "10.2.0" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.2.0.tgz#68f5963efb5214cb2d881477228e4b5b315473e1" + integrity sha512-ikaq0N/w9fABM+G01OFmU3U3dNnyRwEahkdvi9mqy1a3XwKiPZaF/lu54OcNaEWnpvEYyhhS0N7buCtLQqC92w== + dependencies: + lodash "^4.17.15" + ts-essentials "^7.0.1" + "@typechain/ethers-v5@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-7.2.0.tgz#d559cffe0efe6bdbc20e644b817f6fa8add5e8f8" @@ -10774,6 +10782,22 @@ typechain@^8.0.0: ts-command-line-args "^2.2.0" ts-essentials "^7.0.1" +typechain@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.1.1.tgz#9c2e8012c2c4c586536fc18402dcd7034c4ff0bd" + integrity sha512-uF/sUvnXTOVF2FHKhQYnxHk4su4JjZR8vr4mA2mBaRwHTbwh0jIlqARz9XJr1tA0l7afJGvEa1dTSi4zt039LQ== + dependencies: + "@types/prettier" "^2.1.1" + debug "^4.3.1" + fs-extra "^7.0.0" + glob "7.1.7" + js-sha3 "^0.8.0" + lodash "^4.17.15" + mkdirp "^1.0.4" + prettier "^2.3.1" + ts-command-line-args "^2.2.0" + ts-essentials "^7.0.1" + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" From 1653ca1601e4726003fb3d4813851bcf48667fb0 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Thu, 27 Apr 2023 16:25:30 +0300 Subject: [PATCH 027/112] update typescript --- packages/contracts-versions/package.json | 2 +- yarn.lock | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/contracts-versions/package.json b/packages/contracts-versions/package.json index 41d0d6328..86cdec00f 100644 --- a/packages/contracts-versions/package.json +++ b/packages/contracts-versions/package.json @@ -29,7 +29,7 @@ "rollup": "^2.70.1", "rollup-plugin-dts": "^4.2.0", "typechain": "^8.1.1", - "typescript": "^4.4.4" + "typescript": "^5.0.4" }, "dependencies": { "ethers": "^5.6.2" diff --git a/yarn.lock b/yarn.lock index 900bf891c..48686c1d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10820,6 +10820,11 @@ typescript@^4.9.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + typical@^2.6.0, typical@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" From 03ad311c97b1b9891328be0dc637122d3f30face Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Thu, 27 Apr 2023 17:23:03 +0300 Subject: [PATCH 028/112] convert script to typescript --- ...ersions.js => create-contract-versions.ts} | 8 +- packages/contracts-versions/package.json | 5 +- yarn.lock | 104 ++++++++++++++++++ 3 files changed, 112 insertions(+), 5 deletions(-) rename packages/contracts-versions/{create-contract-versions.js => create-contract-versions.ts} (90%) diff --git a/packages/contracts-versions/create-contract-versions.js b/packages/contracts-versions/create-contract-versions.ts similarity index 90% rename from packages/contracts-versions/create-contract-versions.js rename to packages/contracts-versions/create-contract-versions.ts index 9576b8b0c..a98a2d5d1 100644 --- a/packages/contracts-versions/create-contract-versions.js +++ b/packages/contracts-versions/create-contract-versions.ts @@ -13,7 +13,7 @@ async function getCurrentBranch() { return stdout.trim(); } -async function buildContracts(commit) { +async function buildContracts(commit: string) { try { await exec(`git checkout ${commit}`, {cwd: contractsDir}); await exec('yarn build', {cwd: contractsDir}); @@ -22,7 +22,7 @@ async function buildContracts(commit) { } } -async function copyActiveContracts(commit, versionName) { +async function copyActiveContracts(commit: string, versionName: string) { try { console.log(`Copying active_contracts.json`); const srcActiveContracts = path.join(monorepoRoot, 'active_contracts.json'); @@ -37,7 +37,7 @@ async function copyActiveContracts(commit, versionName) { } } -async function generateTypechain(src, dest) { +async function generateTypechain(src: string, dest: string) { try { // Find all the .json files, excluding the .dbg.json files, in all subdirectories const {stdout} = await exec( @@ -46,7 +46,7 @@ async function generateTypechain(src, dest) { const jsonFiles = stdout .trim() .split('\n') - .map(file => `"${file}"`) + .map((file: string) => `"${file}"`) // Added type annotation here .join(' '); // Run typechain for all .json files at once diff --git a/packages/contracts-versions/package.json b/packages/contracts-versions/package.json index 86cdec00f..47866b77f 100644 --- a/packages/contracts-versions/package.json +++ b/packages/contracts-versions/package.json @@ -9,7 +9,7 @@ "access": "public" }, "scripts": { - "build:contracts": "node create-contract-versions.js", + "build:contracts": "ts-node create-contract-versions.ts", "build:npm": "rollup --config rollup.config.ts", "build": "yarn build:contracts && yarn build:npm" }, @@ -26,8 +26,11 @@ "devDependencies": { "@rollup/plugin-typescript": "^8.3.1", "@typechain/ethers-v5": "^10.2.0", + "@types/fs-extra": "^11.0.1", + "@types/node": "^18.16.1", "rollup": "^2.70.1", "rollup-plugin-dts": "^4.2.0", + "ts-node": "^10.9.1", "typechain": "^8.1.1", "typescript": "^5.0.4" }, diff --git a/yarn.lock b/yarn.lock index 48686c1d8..6ff4b1ba7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -65,6 +65,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + "@defi-wonderland/smock@^2.3.4": version "2.3.4" resolved "https://registry.yarnpkg.com/@defi-wonderland/smock/-/smock-2.3.4.tgz#2bfe7e19052140634b25db344d77de9b0ac7a96b" @@ -1331,6 +1338,24 @@ dependencies: multiformats "^9.5.4" +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" @@ -1985,6 +2010,26 @@ mkdirp "^1.0.4" path-browserify "^1.0.1" +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" + integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + "@typechain/ethers-v5@^10.0.0": version "10.0.0" resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.0.0.tgz#1b6e292d2ed9afb0d2f7a4674cc199bb95bad714" @@ -2087,6 +2132,14 @@ dependencies: "@types/node" "*" +"@types/fs-extra@^11.0.1": + version "11.0.1" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-11.0.1.tgz#f542ec47810532a8a252127e6e105f487e0a6ea5" + integrity sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA== + dependencies: + "@types/jsonfile" "*" + "@types/node" "*" + "@types/glob@^7.1.1": version "7.2.0" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" @@ -2110,6 +2163,13 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= +"@types/jsonfile@*": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@types/jsonfile/-/jsonfile-6.1.1.tgz#ac84e9aefa74a2425a0fb3012bdea44f58970f1b" + integrity sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png== + dependencies: + "@types/node" "*" + "@types/lodash@^4.14.159": version "4.14.178" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8" @@ -2160,6 +2220,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.37.tgz#abb38afa9d6e8a2f627a8cb52290b3c80fbe61ed" integrity sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA== +"@types/node@^18.16.1": + version "18.16.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.1.tgz#5db121e9c5352925bb1f1b892c4ae620e3526799" + integrity sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA== + "@types/node@^8.0.0": version "8.10.66" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" @@ -2415,6 +2480,11 @@ acorn-jsx@^5.0.0, acorn-jsx@^5.3.1: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + acorn@^6.0.7: version "6.4.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" @@ -2425,6 +2495,11 @@ acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.4.1: + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + acorn@^8.7.0: version "8.7.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" @@ -3843,6 +3918,11 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -10628,6 +10708,25 @@ ts-morph@^17.0.1: "@ts-morph/common" "~0.18.0" code-block-writer "^11.0.3" +ts-node@^10.9.1: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + ts-node@^8.1.0: version "8.10.2" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d" @@ -11023,6 +11122,11 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" From 5dd35fe94538e3949517169687f3aba3efd2ace1 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Thu, 27 Apr 2023 17:58:30 +0300 Subject: [PATCH 029/112] change commit hash json --- .../contracts-versions/commit_hashes.json | 19 +++++-------------- .../create-contract-versions.ts | 13 ++++++++----- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/packages/contracts-versions/commit_hashes.json b/packages/contracts-versions/commit_hashes.json index f26d6fcfa..0885adda0 100644 --- a/packages/contracts-versions/commit_hashes.json +++ b/packages/contracts-versions/commit_hashes.json @@ -1,16 +1,7 @@ { - "versions": [ - { - "name": "v0.7.0_alpha", - "commit": "9b912728c315f983af8c4bfd1f8d07021996563f" - }, - { - "name": "v1.0.0_mainnet_goerli", - "commit": "c2b9d23a96654e81f22fbf91e6f334ef26a370af" - }, - { - "name": "v1.0.0_mumbai", - "commit": "9485d97301611cfc78faa4bd00eb54abb6dd2d5e" - } - ] + "versions": { + "v0.7.0_alpha": "9b912728c315f983af8c4bfd1f8d07021996563f", + "v1.0.0_mainnet_goerli": "c2b9d23a96654e81f22fbf91e6f334ef26a370af", + "v1.0.0_mumbai": "9485d97301611cfc78faa4bd00eb54abb6dd2d5e" + } } diff --git a/packages/contracts-versions/create-contract-versions.ts b/packages/contracts-versions/create-contract-versions.ts index a98a2d5d1..7d7b89db4 100644 --- a/packages/contracts-versions/create-contract-versions.ts +++ b/packages/contracts-versions/create-contract-versions.ts @@ -59,15 +59,18 @@ async function generateTypechain(src: string, dest: string) { async function createVersions() { const currentBranch = await getCurrentBranch(); - for (const version of commitHashes.versions) { + for (const version in commitHashes.versions) { + const versionCommit = commitHashes.versions[version] as string; + const versionName = version; + console.log( - `Building contracts for version: ${version.name}, with commit: ${version.commit}` + `Building contracts for version: ${versionName}, with commit: ${versionCommit}` ); - await buildContracts(version.commit); - await copyActiveContracts(version.commit, version.name); + await buildContracts(versionCommit); + await copyActiveContracts(versionCommit, versionName); const srcArtifacts = path.join(contractsDir, 'artifacts/src'); - const destTypechain = path.join(contractVersionsDir, version.name, 'types'); + const destTypechain = path.join(contractVersionsDir, versionName, 'types'); await generateTypechain(srcArtifacts, destTypechain); } From 252b165afb3eeec872381b8ab7cceab232ef1ded Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Fri, 28 Apr 2023 11:42:22 +0300 Subject: [PATCH 030/112] rename types to typechain --- packages/contracts-versions/create-contract-versions.ts | 6 +++++- packages/contracts-versions/npm/index.ts | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/contracts-versions/create-contract-versions.ts b/packages/contracts-versions/create-contract-versions.ts index 7d7b89db4..59b1c84d1 100644 --- a/packages/contracts-versions/create-contract-versions.ts +++ b/packages/contracts-versions/create-contract-versions.ts @@ -70,7 +70,11 @@ async function createVersions() { await copyActiveContracts(versionCommit, versionName); const srcArtifacts = path.join(contractsDir, 'artifacts/src'); - const destTypechain = path.join(contractVersionsDir, versionName, 'types'); + const destTypechain = path.join( + contractVersionsDir, + versionName, + 'typechain' + ); await generateTypechain(srcArtifacts, destTypechain); } diff --git a/packages/contracts-versions/npm/index.ts b/packages/contracts-versions/npm/index.ts index 4c4dc0e65..77754d4dc 100644 --- a/packages/contracts-versions/npm/index.ts +++ b/packages/contracts-versions/npm/index.ts @@ -1,17 +1,17 @@ // Import and export the generated contract versions const versions = { v0_7_0_alpha: { - types: () => import('../build/v0.7.0_alpha/types'), + types: () => import('../build/v0.7.0_alpha/typechain'), active_contracts: () => import('../build/v0.7.0_alpha/active_contracts.json'), }, v1_0_0_mainnet_goerli: { - types: () => import('../build/v1.0.0_mainnet_goerli/types'), + types: () => import('../build/v1.0.0_mainnet_goerli/typechain'), active_contracts: () => import('../build/v1.0.0_mainnet_goerli/active_contracts.json'), }, v1_0_0_mumbai: { - types: () => import('../build/v1.0.0_mumbai/types'), + types: () => import('../build/v1.0.0_mumbai/typechain'), active_contracts: () => import('../build/v1.0.0_mumbai/active_contracts.json'), }, From ab50a5e922fc22b6a00506c2809417212394e2aa Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Fri, 28 Apr 2023 12:36:55 +0300 Subject: [PATCH 031/112] add test --- packages/contracts-versions/jest.config.js | 4 + packages/contracts-versions/npm/index.ts | 6 +- packages/contracts-versions/package.json | 6 +- .../contracts-versions/test/usage.test.ts | 15 + packages/contracts-versions/tsconfig.json | 6 +- yarn.lock | 1629 ++++++++++++++++- 6 files changed, 1641 insertions(+), 25 deletions(-) create mode 100644 packages/contracts-versions/jest.config.js create mode 100644 packages/contracts-versions/test/usage.test.ts diff --git a/packages/contracts-versions/jest.config.js b/packages/contracts-versions/jest.config.js new file mode 100644 index 000000000..4a5b465ec --- /dev/null +++ b/packages/contracts-versions/jest.config.js @@ -0,0 +1,4 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', +}; diff --git a/packages/contracts-versions/npm/index.ts b/packages/contracts-versions/npm/index.ts index 77754d4dc..3d6359189 100644 --- a/packages/contracts-versions/npm/index.ts +++ b/packages/contracts-versions/npm/index.ts @@ -1,17 +1,17 @@ // Import and export the generated contract versions const versions = { v0_7_0_alpha: { - types: () => import('../build/v0.7.0_alpha/typechain'), + typechain: () => import('../build/v0.7.0_alpha/typechain'), active_contracts: () => import('../build/v0.7.0_alpha/active_contracts.json'), }, v1_0_0_mainnet_goerli: { - types: () => import('../build/v1.0.0_mainnet_goerli/typechain'), + typechain: () => import('../build/v1.0.0_mainnet_goerli/typechain'), active_contracts: () => import('../build/v1.0.0_mainnet_goerli/active_contracts.json'), }, v1_0_0_mumbai: { - types: () => import('../build/v1.0.0_mumbai/typechain'), + typechain: () => import('../build/v1.0.0_mumbai/typechain'), active_contracts: () => import('../build/v1.0.0_mumbai/active_contracts.json'), }, diff --git a/packages/contracts-versions/package.json b/packages/contracts-versions/package.json index 47866b77f..414633283 100644 --- a/packages/contracts-versions/package.json +++ b/packages/contracts-versions/package.json @@ -11,7 +11,8 @@ "scripts": { "build:contracts": "ts-node create-contract-versions.ts", "build:npm": "rollup --config rollup.config.ts", - "build": "yarn build:contracts && yarn build:npm" + "build": "yarn build:contracts && yarn build:npm", + "test": "jest" }, "repository": { "type": "git", @@ -27,9 +28,12 @@ "@rollup/plugin-typescript": "^8.3.1", "@typechain/ethers-v5": "^10.2.0", "@types/fs-extra": "^11.0.1", + "@types/jest": "^29.5.1", "@types/node": "^18.16.1", + "jest": "^29.5.0", "rollup": "^2.70.1", "rollup-plugin-dts": "^4.2.0", + "ts-jest": "^29.1.0", "ts-node": "^10.9.1", "typechain": "^8.1.1", "typescript": "^5.0.4" diff --git a/packages/contracts-versions/test/usage.test.ts b/packages/contracts-versions/test/usage.test.ts new file mode 100644 index 000000000..cfb10c0c4 --- /dev/null +++ b/packages/contracts-versions/test/usage.test.ts @@ -0,0 +1,15 @@ +import versions from '@aragon/osx-versions'; + +describe('contract-versions', () => { + it('should get typechain for a specific version', async () => { + const v0_7_0_alpha = versions.v0_7_0_alpha; + const types = await v0_7_0_alpha.typechain(); + expect(types).toBeDefined(); + }); + + it('should get active contracts for a specific version', async () => { + const v0_7_0_alpha = versions.v0_7_0_alpha; + const activeContracts = await v0_7_0_alpha.active_contracts(); + expect(activeContracts).toBeDefined(); + }); +}); diff --git a/packages/contracts-versions/tsconfig.json b/packages/contracts-versions/tsconfig.json index 167010b1f..f80bbfe2c 100644 --- a/packages/contracts-versions/tsconfig.json +++ b/packages/contracts-versions/tsconfig.json @@ -8,7 +8,11 @@ "declaration": true, "moduleResolution": "node", "resolveJsonModule": true, - "rootDir": "../../" + "rootDir": "../../", + "baseUrl": "./", + "paths": { + "@aragon/osx-versions": ["node_modules/@aragon/osx-versions"] + } }, "include": ["./npm", "/build"], "files": ["./npm/index.ts"] diff --git a/yarn.lock b/yarn.lock index 6ff4b1ba7..ab2085dc5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,14 @@ # yarn lockfile v1 +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + "@babel/code-frame@7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -16,6 +24,13 @@ dependencies: "@babel/highlight" "^7.16.0" +"@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.21.4": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" + integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== + dependencies: + "@babel/highlight" "^7.18.6" + "@babel/code-frame@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" @@ -23,6 +38,118 @@ dependencies: "@babel/highlight" "^7.16.7" +"@babel/compat-data@^7.21.4": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.4.tgz#457ffe647c480dff59c2be092fc3acf71195c87f" + integrity sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g== + +"@babel/core@^7.11.6", "@babel/core@^7.12.3": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.4.tgz#c6dc73242507b8e2a27fd13a9c1814f9fa34a659" + integrity sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.21.4" + "@babel/generator" "^7.21.4" + "@babel/helper-compilation-targets" "^7.21.4" + "@babel/helper-module-transforms" "^7.21.2" + "@babel/helpers" "^7.21.0" + "@babel/parser" "^7.21.4" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.4" + "@babel/types" "^7.21.4" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.0" + +"@babel/generator@^7.21.4", "@babel/generator@^7.7.2": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.4.tgz#64a94b7448989f421f919d5239ef553b37bb26bc" + integrity sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA== + dependencies: + "@babel/types" "^7.21.4" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.21.4": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz#770cd1ce0889097ceacb99418ee6934ef0572656" + integrity sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg== + dependencies: + "@babel/compat-data" "^7.21.4" + "@babel/helper-validator-option" "^7.21.0" + browserslist "^4.21.3" + lru-cache "^5.1.1" + semver "^6.3.0" + +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + +"@babel/helper-function-name@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" + integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== + dependencies: + "@babel/template" "^7.20.7" + "@babel/types" "^7.21.0" + +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-imports@^7.18.6": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz#ac88b2f76093637489e718a90cec6cf8a9b029af" + integrity sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg== + dependencies: + "@babel/types" "^7.21.4" + +"@babel/helper-module-transforms@^7.21.2": + version "7.21.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz#160caafa4978ac8c00ac66636cb0fa37b024e2d2" + integrity sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.20.2" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.2" + "@babel/types" "^7.21.2" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" + integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== + +"@babel/helper-simple-access@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" + integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== + dependencies: + "@babel/types" "^7.20.2" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== + "@babel/helper-validator-identifier@^7.15.7": version "7.15.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" @@ -33,6 +160,25 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + +"@babel/helper-validator-option@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" + integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== + +"@babel/helpers@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e" + integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA== + dependencies: + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.0" + "@babel/types" "^7.21.0" + "@babel/highlight@^7.10.4", "@babel/highlight@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a" @@ -51,6 +197,118 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.21.4": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.4.tgz#94003fdfc520bbe2875d4ae557b43ddb6d880f17" + integrity sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz#f264ed7bf40ffc9ec239edabc17a50c4f5b6fea2" + integrity sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz#2751948e9b7c6d771a8efa59340c15d4a2891ff8" + integrity sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/runtime@^7.4.4": version "7.18.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.0.tgz#6d77142a19cb6088f0af662af1ada37a604d34ae" @@ -65,6 +323,45 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/template@^7.20.7", "@babel/template@^7.3.3": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" + integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + +"@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2", "@babel/traverse@^7.21.4", "@babel/traverse@^7.7.2": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.4.tgz#a836aca7b116634e97a6ed99976236b3282c9d36" + integrity sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q== + dependencies: + "@babel/code-frame" "^7.21.4" + "@babel/generator" "^7.21.4" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.21.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.21.4" + "@babel/types" "^7.21.4" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.2", "@babel/types@^7.21.4", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.4.tgz#2d5d6bb7908699b3b416409ffd3b5daa25b030d4" + integrity sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -1338,11 +1635,243 @@ dependencies: multiformats "^9.5.4" +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.5.0.tgz#593a6c5c0d3f75689835f1b3b4688c4f8544cb57" + integrity sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ== + dependencies: + "@jest/types" "^29.5.0" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" + slash "^3.0.0" + +"@jest/core@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.5.0.tgz#76674b96904484e8214614d17261cc491e5f1f03" + integrity sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ== + dependencies: + "@jest/console" "^29.5.0" + "@jest/reporters" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.5.0" + jest-config "^29.5.0" + jest-haste-map "^29.5.0" + jest-message-util "^29.5.0" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-resolve-dependencies "^29.5.0" + jest-runner "^29.5.0" + jest-runtime "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" + jest-watcher "^29.5.0" + micromatch "^4.0.4" + pretty-format "^29.5.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.5.0.tgz#9152d56317c1fdb1af389c46640ba74ef0bb4c65" + integrity sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ== + dependencies: + "@jest/fake-timers" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + jest-mock "^29.5.0" + +"@jest/expect-utils@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.5.0.tgz#f74fad6b6e20f924582dc8ecbf2cb800fe43a036" + integrity sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg== + dependencies: + jest-get-type "^29.4.3" + +"@jest/expect@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.5.0.tgz#80952f5316b23c483fbca4363ce822af79c38fba" + integrity sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g== + dependencies: + expect "^29.5.0" + jest-snapshot "^29.5.0" + +"@jest/fake-timers@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.5.0.tgz#d4d09ec3286b3d90c60bdcd66ed28d35f1b4dc2c" + integrity sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg== + dependencies: + "@jest/types" "^29.5.0" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.5.0" + jest-mock "^29.5.0" + jest-util "^29.5.0" + +"@jest/globals@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.5.0.tgz#6166c0bfc374c58268677539d0c181f9c1833298" + integrity sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ== + dependencies: + "@jest/environment" "^29.5.0" + "@jest/expect" "^29.5.0" + "@jest/types" "^29.5.0" + jest-mock "^29.5.0" + +"@jest/reporters@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.5.0.tgz#985dfd91290cd78ddae4914ba7921bcbabe8ac9b" + integrity sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" + "@jridgewell/trace-mapping" "^0.3.15" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.5.0" + jest-util "^29.5.0" + jest-worker "^29.5.0" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" + integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== + dependencies: + "@sinclair/typebox" "^0.25.16" + +"@jest/source-map@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.3.tgz#ff8d05cbfff875d4a791ab679b4333df47951d20" + integrity sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.15" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.5.0.tgz#7c856a6ca84f45cc36926a4e9c6b57f1973f1408" + integrity sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ== + dependencies: + "@jest/console" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz#34d7d82d3081abd523dbddc038a3ddcb9f6d3cc4" + integrity sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ== + dependencies: + "@jest/test-result" "^29.5.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.5.0" + slash "^3.0.0" + +"@jest/transform@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.5.0.tgz#cf9c872d0965f0cbd32f1458aa44a2b1988b00f9" + integrity sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.5.0" + "@jridgewell/trace-mapping" "^0.3.15" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.5.0" + jest-regex-util "^29.4.3" + jest-util "^29.5.0" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.2" + +"@jest/types@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.5.0.tgz#f59ef9b031ced83047c67032700d8c807d6e1593" + integrity sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog== + dependencies: + "@jest/schemas" "^29.4.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + "@jridgewell/resolve-uri@^3.0.3": version "3.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@1.4.14": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" @@ -1356,6 +1885,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" + integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" @@ -1883,11 +2420,30 @@ "@sentry/types" "5.30.0" tslib "^1.9.3" +"@sinclair/typebox@^0.25.16": + version "0.25.24" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" + integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== +"@sinonjs/commons@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" + integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz#d10549ed1f423d80639c528b6c7f5a1017747d0c" + integrity sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw== + dependencies: + "@sinonjs/commons" "^2.0.0" + "@solidity-parser/parser@^0.12.0": version "0.12.2" resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.12.2.tgz#1afad367cb29a2ed8cdd4a3a62701c2821fb578f" @@ -2066,6 +2622,39 @@ resolved "https://registry.yarnpkg.com/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz#f8e6280e87e8c60b2b938624b0a3530fb3e24712" integrity sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg== +"@types/babel__core@^7.1.14": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.0.tgz#61bc5a4cae505ce98e1e36c5445e4bee060d8891" + integrity sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.18.5" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.5.tgz#c107216842905afafd3b6e774f6f935da6f5db80" + integrity sha512-enCvTL8m/EHS/zIvJno9nE+ndYPh1/oNFzRYRmtUqJICG2VnCSBzMLW5VN2KCQU91f23tsNKR8v7VJJQMatl7Q== + dependencies: + "@babel/types" "^7.3.0" + "@types/bn.js@^4.11.3", "@types/bn.js@^4.11.5": version "4.11.6" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" @@ -2148,6 +2737,40 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/graceful-fs@^4.1.3": + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^29.5.1": + version "29.5.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.1.tgz#83c818aa9a87da27d6da85d3378e5a34d2f31a47" + integrity sha512-tEuVcHrpaixS36w7hpsfLBLpjtMRJUE09/MHXn923LOVojDwyC14cWcfc0rDs0VEfUyYmt/+iX1kxxp+gZMcaQ== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + "@types/json-schema@^7.0.7": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" @@ -2247,6 +2870,11 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.2.tgz#4c62fae93eb479660c3bd93f9d24d561597a8281" integrity sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA== +"@types/prettier@^2.1.5": + version "2.7.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" + integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== + "@types/qs@*", "@types/qs@^6.2.31", "@types/qs@^6.9.7": version "6.9.7" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" @@ -2264,6 +2892,11 @@ dependencies: "@types/node" "*" +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + "@types/ws@^7.4.4": version "7.4.7" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" @@ -2271,6 +2904,18 @@ dependencies: "@types/node" "*" +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + +"@types/yargs@^17.0.8": + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== + dependencies: + "@types/yargs-parser" "*" + "@typescript-eslint/eslint-plugin@^4.33.0": version "4.33.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" @@ -2580,7 +3225,7 @@ ansi-escapes@^3.2.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== -ansi-escapes@^4.3.0: +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -2621,6 +3266,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + antlr4@4.7.1: version "4.7.1" resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.7.1.tgz#69984014f096e9e775f53dd9744bf994d8959773" @@ -2639,6 +3289,14 @@ any-signal@^2.1.0, any-signal@^2.1.2: abort-controller "^3.0.0" native-abort-controller "^1.0.3" +anymatch@^3.0.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + anymatch@~3.1.1, anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" @@ -2847,6 +3505,66 @@ axios@^0.21.1, axios@^0.21.2: dependencies: follow-redirects "^1.14.0" +babel-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.5.0.tgz#3fe3ddb109198e78b1c88f9ebdecd5e4fc2f50a5" + integrity sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q== + dependencies: + "@jest/transform" "^29.5.0" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.5.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz#a97db437936f441ec196990c9738d4b88538618a" + integrity sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz#57bc8cc88097af7ff6a5ab59d1cd29d52a5916e2" + integrity sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg== + dependencies: + babel-plugin-jest-hoist "^29.5.0" + babel-preset-current-node-syntax "^1.0.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -3146,6 +3864,23 @@ browserify-sign@^4.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" +browserslist@^4.21.3: + version "4.21.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" + integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== + dependencies: + caniuse-lite "^1.0.30001449" + electron-to-chromium "^1.4.284" + node-releases "^2.0.8" + update-browserslist-db "^1.0.10" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" @@ -3162,6 +3897,13 @@ bs58check@^2.1.2: create-hash "^1.1.0" safe-buffer "^5.1.2" +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + buffer-alloc-unsafe@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" @@ -3303,16 +4045,21 @@ camelcase@^4.1.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw== -camelcase@^5.0.0: +camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0: +camelcase@^6.0.0, camelcase@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +caniuse-lite@^1.0.30001449: + version "1.0.30001481" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz#f58a717afe92f9e69d0e35ff64df596bfad93912" + integrity sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ== + caseless@^0.12.0, caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -3424,6 +4171,11 @@ change-case@3.0.2: upper-case "^1.1.1" upper-case-first "^1.1.0" +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -3540,6 +4292,11 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +ci-info@^3.2.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + cids@^0.7.1, cids@~0.7.0, cids@~0.7.1: version "0.7.5" resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" @@ -3570,6 +4327,11 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + class-is@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" @@ -3652,6 +4414,15 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + clone-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" @@ -3664,6 +4435,11 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + code-block-writer@^11.0.3: version "11.0.3" resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-11.0.3.tgz#9eec2993edfb79bfae845fbc093758c0a0b73b76" @@ -3674,6 +4450,11 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -3820,6 +4601,16 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== +convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -3934,7 +4725,7 @@ cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0, cross-spawn@^7.0.2: +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -4078,6 +4869,11 @@ decompress-response@^3.2.0, decompress-response@^3.3.0: dependencies: mimic-response "^1.0.0" +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== + deep-eql@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" @@ -4102,6 +4898,11 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + defaults@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" @@ -4159,6 +4960,11 @@ detect-indent@^5.0.0: resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + detect-node@^2.0.4: version "2.1.0" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" @@ -4172,6 +4978,11 @@ detect-port@^1.3.0: address "^1.0.1" debug "^2.6.0" +diff-sequences@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" + integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== + diff@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -4350,6 +5161,11 @@ electron-fetch@^1.7.2: dependencies: encoding "^0.1.13" +electron-to-chromium@^1.4.284: + version "1.4.376" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.376.tgz#a771d6c4db028634df126348a4f94075e07e7f65" + integrity sha512-TFeOKd98TpJzRHkr4Aorn16QkMnuCQuGAE6IZ0wYF+qkbSfMPqjplvRppR02tMUpVxZz8nyBNvVm9lIZsqrbPQ== + elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" @@ -4363,6 +5179,11 @@ elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== + emoji-regex@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -4536,6 +5357,11 @@ escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + escodegen@1.8.x: version "1.8.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" @@ -5236,11 +6062,42 @@ execa@^3.0.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + exit-on-epipe@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^29.0.0, expect@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" + integrity sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg== + dependencies: + "@jest/expect-utils" "^29.5.0" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" + explain-error@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/explain-error/-/explain-error-1.0.4.tgz#a793d3ac0cad4c6ab571e9968fbbab6cb2532929" @@ -5378,7 +6235,7 @@ fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -5395,6 +6252,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -5486,6 +6350,14 @@ find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + flat-cache@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" @@ -5708,16 +6580,16 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fsevents@^2.3.2, fsevents@~2.3.1, fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + fsevents@~2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== -fsevents@~2.3.1, fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -5728,6 +6600,11 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" @@ -5757,6 +6634,11 @@ get-iterator@^1.0.2: resolved "https://registry.yarnpkg.com/get-iterator/-/get-iterator-1.0.2.tgz#cd747c02b4c084461fac14f48f6b45a80ed25c82" integrity sha512-v+dm9bNVfOYsY1OrhaCrmyOcYoSeVvbt+hHZ0Au+T+p1y+0Uyj9aMaGIeUTT6xdpRbWzDeYKvfOslPhggQMcsg== +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + get-port@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" @@ -5781,6 +6663,11 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -5877,6 +6764,18 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.4: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-modules@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" @@ -5901,7 +6800,7 @@ global@~4.4.0: min-document "^2.19.0" process "^0.11.10" -globals@^11.7.0: +globals@^11.1.0, globals@^11.7.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== @@ -6034,6 +6933,11 @@ graceful-fs@^4.2.4: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + graphql@15.5.0: version "15.5.0" resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.0.tgz#39d19494dbe69d1ea719915b578bf920344a69d5" @@ -6289,6 +7193,11 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + htmlparser2@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010" @@ -6381,6 +7290,11 @@ human-signals@^1.1.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -6448,6 +7362,14 @@ import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + imul@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/imul/-/imul-1.0.1.tgz#9d5867161e8b3de96c2c38d5dc7cb102f35e2ac9" @@ -6880,6 +7802,11 @@ is-function@^1.0.1: resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + is-generator-function@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" @@ -7118,6 +8045,48 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + isurl@^1.0.0-alpha5: version "1.0.0" resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" @@ -7240,6 +8209,367 @@ jayson@3.6.6: uuid "^8.3.2" ws "^7.4.5" +jest-changed-files@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.5.0.tgz#e88786dca8bf2aa899ec4af7644e16d9dcf9b23e" + integrity sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag== + dependencies: + execa "^5.0.0" + p-limit "^3.1.0" + +jest-circus@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.5.0.tgz#b5926989449e75bff0d59944bae083c9d7fb7317" + integrity sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA== + dependencies: + "@jest/environment" "^29.5.0" + "@jest/expect" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + is-generator-fn "^2.0.0" + jest-each "^29.5.0" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-runtime "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" + p-limit "^3.1.0" + pretty-format "^29.5.0" + pure-rand "^6.0.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.5.0.tgz#b34c20a6d35968f3ee47a7437ff8e53e086b4a67" + integrity sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw== + dependencies: + "@jest/core" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" + prompts "^2.0.1" + yargs "^17.3.1" + +jest-config@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.5.0.tgz#3cc972faec8c8aaea9ae158c694541b79f3748da" + integrity sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.5.0" + "@jest/types" "^29.5.0" + babel-jest "^29.5.0" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.5.0" + jest-environment-node "^29.5.0" + jest-get-type "^29.4.3" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-runner "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.5.0" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.5.0.tgz#e0d83a58eb5451dcc1fa61b1c3ee4e8f5a290d63" + integrity sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.4.3" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" + +jest-docblock@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8" + integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg== + dependencies: + detect-newline "^3.0.0" + +jest-each@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.5.0.tgz#fc6e7014f83eac68e22b7195598de8554c2e5c06" + integrity sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA== + dependencies: + "@jest/types" "^29.5.0" + chalk "^4.0.0" + jest-get-type "^29.4.3" + jest-util "^29.5.0" + pretty-format "^29.5.0" + +jest-environment-node@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.5.0.tgz#f17219d0f0cc0e68e0727c58b792c040e332c967" + integrity sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw== + dependencies: + "@jest/environment" "^29.5.0" + "@jest/fake-timers" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + jest-mock "^29.5.0" + jest-util "^29.5.0" + +jest-get-type@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" + integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== + +jest-haste-map@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.5.0.tgz#69bd67dc9012d6e2723f20a945099e972b2e94de" + integrity sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA== + dependencies: + "@jest/types" "^29.5.0" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.4.3" + jest-util "^29.5.0" + jest-worker "^29.5.0" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz#cf4bdea9615c72bac4a3a7ba7e7930f9c0610c8c" + integrity sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow== + dependencies: + jest-get-type "^29.4.3" + pretty-format "^29.5.0" + +jest-matcher-utils@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz#d957af7f8c0692c5453666705621ad4abc2c59c5" + integrity sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw== + dependencies: + chalk "^4.0.0" + jest-diff "^29.5.0" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" + +jest-message-util@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.5.0.tgz#1f776cac3aca332ab8dd2e3b41625435085c900e" + integrity sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.5.0" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.5.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.5.0.tgz#26e2172bcc71d8b0195081ff1f146ac7e1518aed" + integrity sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw== + dependencies: + "@jest/types" "^29.5.0" + "@types/node" "*" + jest-util "^29.5.0" + +jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + +jest-regex-util@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" + integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== + +jest-resolve-dependencies@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz#f0ea29955996f49788bf70996052aa98e7befee4" + integrity sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg== + dependencies: + jest-regex-util "^29.4.3" + jest-snapshot "^29.5.0" + +jest-resolve@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.5.0.tgz#b053cc95ad1d5f6327f0ac8aae9f98795475ecdc" + integrity sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.5.0" + jest-pnp-resolver "^1.2.2" + jest-util "^29.5.0" + jest-validate "^29.5.0" + resolve "^1.20.0" + resolve.exports "^2.0.0" + slash "^3.0.0" + +jest-runner@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.5.0.tgz#6a57c282eb0ef749778d444c1d758c6a7693b6f8" + integrity sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ== + dependencies: + "@jest/console" "^29.5.0" + "@jest/environment" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.4.3" + jest-environment-node "^29.5.0" + jest-haste-map "^29.5.0" + jest-leak-detector "^29.5.0" + jest-message-util "^29.5.0" + jest-resolve "^29.5.0" + jest-runtime "^29.5.0" + jest-util "^29.5.0" + jest-watcher "^29.5.0" + jest-worker "^29.5.0" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.5.0.tgz#c83f943ee0c1da7eb91fa181b0811ebd59b03420" + integrity sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw== + dependencies: + "@jest/environment" "^29.5.0" + "@jest/fake-timers" "^29.5.0" + "@jest/globals" "^29.5.0" + "@jest/source-map" "^29.4.3" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.5.0" + jest-message-util "^29.5.0" + jest-mock "^29.5.0" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-snapshot@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.5.0.tgz#c9c1ce0331e5b63cd444e2f95a55a73b84b1e8ce" + integrity sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/babel__traverse" "^7.0.6" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.5.0" + graceful-fs "^4.2.9" + jest-diff "^29.5.0" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" + natural-compare "^1.4.0" + pretty-format "^29.5.0" + semver "^7.3.5" + +jest-util@^29.0.0, jest-util@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.5.0.tgz#24a4d3d92fc39ce90425311b23c27a6e0ef16b8f" + integrity sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ== + dependencies: + "@jest/types" "^29.5.0" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.5.0.tgz#8e5a8f36178d40e47138dc00866a5f3bd9916ffc" + integrity sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ== + dependencies: + "@jest/types" "^29.5.0" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.4.3" + leven "^3.1.0" + pretty-format "^29.5.0" + +jest-watcher@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.5.0.tgz#cf7f0f949828ba65ddbbb45c743a382a4d911363" + integrity sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA== + dependencies: + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.5.0" + string-length "^4.0.1" + +jest-worker@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.5.0.tgz#bdaefb06811bd3384d93f009755014d8acb4615d" + integrity sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA== + dependencies: + "@types/node" "*" + jest-util "^29.5.0" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.5.0.tgz#f75157622f5ce7ad53028f2f8888ab53e1f1f24e" + integrity sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ== + dependencies: + "@jest/core" "^29.5.0" + "@jest/types" "^29.5.0" + import-local "^3.0.2" + jest-cli "^29.5.0" + js-sha3@0.5.7, js-sha3@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" @@ -7283,6 +8613,11 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + json-buffer@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" @@ -7337,6 +8672,11 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.2.2, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -7433,6 +8773,11 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + ky-universal@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/ky-universal/-/ky-universal-0.2.2.tgz#7a36e1a75641a98f878157463513965f799f5bfe" @@ -7474,6 +8819,11 @@ level@^8.0.0: browser-level "^1.0.1" classic-level "^1.2.0" +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -7556,6 +8906,13 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -7598,6 +8955,11 @@ lodash.lowerfirst@^4.3.1: resolved "https://registry.yarnpkg.com/lodash.lowerfirst/-/lodash.lowerfirst-4.3.1.tgz#de3c7b12e02c6524a0059c2f6cb7c5c52655a13d" integrity sha1-3jx7EuAsZSSgBZwvbLfFxSZVoT0= +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" @@ -7762,11 +9124,25 @@ magic-string@^0.26.1: dependencies: sourcemap-codec "^1.4.8" -make-error@^1.1.1: +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-error@1.x, make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + markdown-table@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" @@ -7923,6 +9299,13 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimatch@^5.1.0: version "5.1.6" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" @@ -8408,6 +9791,16 @@ node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.8: + version "2.0.10" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" + integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== + nodeify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/nodeify/-/nodeify-1.0.1.tgz#64ab69a7bdbaf03ce107b4f0335c87c0b9e91b1d" @@ -8453,7 +9846,7 @@ normalize-url@^4.1.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== -npm-run-path@^4.0.0: +npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -8576,7 +9969,7 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -onetime@^5.1.0: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -8685,14 +10078,14 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0: +p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" -p-limit@^3.0.2: +p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -8713,6 +10106,13 @@ p-locate@^3.0.0: dependencies: p-limit "^2.0.0" +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + p-locate@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" @@ -8804,7 +10204,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -8963,6 +10363,11 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: version "2.3.0" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" @@ -8995,6 +10400,11 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -9002,6 +10412,13 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + pkginfo@0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff" @@ -9068,6 +10485,15 @@ prettier@^2.4.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.1.tgz#4e1fd11c34e2421bc1da9aea9bd8127cd0a35efc" integrity sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg== +pretty-format@^29.0.0, pretty-format@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a" + integrity sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw== + dependencies: + "@jest/schemas" "^29.4.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + printj@~1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" @@ -9112,6 +10538,14 @@ promisify-es6@^1.0.3: resolved "https://registry.yarnpkg.com/promisify-es6/-/promisify-es6-1.0.3.tgz#b012668c4df3c965ce13daac2b3a4d1726a96346" integrity sha512-N9iVG+CGJsI4b4ZGazjwLnxErD2d9Pe4DPvvXSxYA9tFNu8ymXME4Qs5HIQ0LMJpNM7zj+m0NlNnNeqFpKzqnA== +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + proper-lockfile@^4.1.1: version "4.1.2" resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f" @@ -9228,6 +10662,11 @@ pure-rand@^5.0.1: resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-5.0.1.tgz#97a287b4b4960b2a3448c0932bf28f2405cac51d" integrity sha512-ksWccjmXOHU2gJBnH0cK1lSYdvSZ0zLoCMSz/nTGh6hDvCSgcRxDyIcOBD6KNxFz3xhMPm/T267Tbe2JRymKEQ== +pure-rand@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.2.tgz#a9c2ddcae9b68d736a8163036f088a2781c8b306" + integrity sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ== + qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" @@ -9323,6 +10762,11 @@ raw-body@^2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + react-native-fetch-api@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/react-native-fetch-api/-/react-native-fetch-api-2.0.0.tgz#c4af188b4fce3f3eaf1f1ff4e61dae1a00d4ffa0" @@ -9522,6 +10966,13 @@ require-main-filename@^2.0.0: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -9532,6 +10983,16 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== + resolve@1.1.x: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" @@ -9789,7 +11250,14 @@ semver@7.3.5, semver@^7.0.0, semver@^7.2.1, semver@^7.3.4, semver@^7.3.5: dependencies: lru-cache "^6.0.0" -semver@^6.1.0, semver@^6.3.0: +semver@7.x: + version "7.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0" + integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== + dependencies: + lru-cache "^6.0.0" + +semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -9951,6 +11419,11 @@ signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== +signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + signed-varint@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/signed-varint/-/signed-varint-2.0.1.tgz#50a9989da7c98c2c61dad119bc97470ef8528129" @@ -9972,6 +11445,11 @@ simple-get@^2.7.0: once "^1.3.1" simple-concat "^1.0.0" +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -10099,6 +11577,14 @@ solidity-docgen@^0.6.0-beta.35: handlebars "^4.7.7" solidity-ast "^0.4.38" +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-support@^0.5.13, source-map-support@^0.5.17, source-map-support@^0.5.19: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" @@ -10187,6 +11673,13 @@ stable@~0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + stacktrace-parser@^0.1.10: version "0.1.10" resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" @@ -10234,6 +11727,14 @@ string-format@^2.0.0: resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -10344,6 +11845,11 @@ strip-bom@^3.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" @@ -10378,7 +11884,7 @@ supports-color@6.0.0: dependencies: has-flag "^3.0.0" -supports-color@8.1.1: +supports-color@8.1.1, supports-color@^8.0.0: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== @@ -10553,6 +12059,15 @@ tar@^6.1.0: mkdirp "^1.0.3" yallist "^4.0.0" +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + test-value@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" @@ -10650,11 +12165,21 @@ tmp@^0.2.0: dependencies: rimraf "^3.0.0" +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + to-buffer@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + to-readable-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" @@ -10700,6 +12225,20 @@ ts-essentials@^7.0.1: resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== +ts-jest@^29.1.0: + version "29.1.0" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.0.tgz#4a9db4104a49b76d2b368ea775b6c9535c603891" + integrity sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^29.0.0" + json5 "^2.2.3" + lodash.memoize "4.x" + make-error "1.x" + semver "7.x" + yargs-parser "^21.0.1" + ts-morph@^17.0.1: version "17.0.1" resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-17.0.1.tgz#d85df4fcf9a1fcda1b331d52c00655f381c932d1" @@ -10811,7 +12350,7 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-detect@^4.0.0, type-detect@^4.0.5: +type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== @@ -11017,6 +12556,14 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= +update-browserslist-db@^1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + upper-case-first@^1.1.0, upper-case-first@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-1.1.2.tgz#5d79bedcff14419518fd2edb0a0507c9b6859115" @@ -11132,6 +12679,15 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +v8-to-istanbul@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" + integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -11169,6 +12725,13 @@ wabt@1.0.24: resolved "https://registry.yarnpkg.com/wabt/-/wabt-1.0.24.tgz#c02e0b5b4503b94feaf4a30a426ef01c1bea7c6c" integrity sha512-8l7sIOd3i5GWfTWciPL0+ff/FK/deVK2Q6FN+MPz4vfUcD78i2M/49XJTwF6aml91uIiuXJEsLKWMB2cw/mtKg== +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -11810,6 +13373,14 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + write@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" @@ -11959,6 +13530,11 @@ yargs-parser@^20.2.2: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== +yargs-parser@^21.0.1, yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + yargs-unparser@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" @@ -12007,6 +13583,19 @@ yargs@16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^17.3.1: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + yargs@^4.7.1: version "4.8.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" From 0ad3a4fa66ba9b547264840a9294c9e604a339fb Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Fri, 28 Apr 2023 14:07:22 +0300 Subject: [PATCH 032/112] add json to rollup and export types --- .../contracts-versions/commit_hashes.json | 6 +-- packages/contracts-versions/npm/index.ts | 53 ++++++++++++------- packages/contracts-versions/rollup.config.ts | 2 +- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/packages/contracts-versions/commit_hashes.json b/packages/contracts-versions/commit_hashes.json index 0885adda0..c302aa9e0 100644 --- a/packages/contracts-versions/commit_hashes.json +++ b/packages/contracts-versions/commit_hashes.json @@ -1,7 +1,7 @@ { "versions": { - "v0.7.0_alpha": "9b912728c315f983af8c4bfd1f8d07021996563f", - "v1.0.0_mainnet_goerli": "c2b9d23a96654e81f22fbf91e6f334ef26a370af", - "v1.0.0_mumbai": "9485d97301611cfc78faa4bd00eb54abb6dd2d5e" + "v0_7_0_alpha": "9b912728c315f983af8c4bfd1f8d07021996563f", + "v1_0_0_mainnet_goerli": "c2b9d23a96654e81f22fbf91e6f334ef26a370af", + "v1_0_0_mumbai": "9485d97301611cfc78faa4bd00eb54abb6dd2d5e" } } diff --git a/packages/contracts-versions/npm/index.ts b/packages/contracts-versions/npm/index.ts index 3d6359189..a818b18d0 100644 --- a/packages/contracts-versions/npm/index.ts +++ b/packages/contracts-versions/npm/index.ts @@ -1,21 +1,36 @@ // Import and export the generated contract versions -const versions = { - v0_7_0_alpha: { - typechain: () => import('../build/v0.7.0_alpha/typechain'), - active_contracts: () => - import('../build/v0.7.0_alpha/active_contracts.json'), - }, - v1_0_0_mainnet_goerli: { - typechain: () => import('../build/v1.0.0_mainnet_goerli/typechain'), - active_contracts: () => - import('../build/v1.0.0_mainnet_goerli/active_contracts.json'), - }, - v1_0_0_mumbai: { - typechain: () => import('../build/v1.0.0_mumbai/typechain'), - active_contracts: () => - import('../build/v1.0.0_mumbai/active_contracts.json'), - }, - // Add more versions here if needed -}; +// const versions = { +// v0_7_0_alpha: { +// typechain: () => import('../build/v0.7.0_alpha/typechain'), +// active_contracts: () => +// import('../build/v0.7.0_alpha/active_contracts.json'), +// }, +// v1_0_0_mainnet_goerli: { +// typechain: () => import('../build/v1.0.0_mainnet_goerli/typechain'), +// active_contracts: () => +// import('../build/v1.0.0_mainnet_goerli/active_contracts.json'), +// }, +// v1_0_0_mumbai: { +// typechain: () => import('../build/v1.0.0_mumbai/typechain'), +// active_contracts: () => +// import('../build/v1.0.0_mumbai/active_contracts.json'), +// }, +// // Add more versions here if needed +// }; + +// export default versions; + +export * as v0_7_0_alpha_typechain from '../build/v0_7_0_alpha/typechain'; +import * as v0_7_0_alpha_active_contracts from '../build/v0.7.0_alpha/active_contracts.json'; -export default versions; +export * as v1_0_0_mainnet_goerli_typechain from '../build/v1_0_0_mainnet_goerli/typechain'; +import * as v1_0_0_mainnet_goerli_active_contracts from '../build/v1_0_0_mainnet_goerli/active_contracts.json'; + +export * as v1_0_0_mumbai_typechain from '../build/v1_0_0_mumbai/typechain'; +import * as v1_0_0_mumbai_active_contracts from '../build/v1_0_0_mumbai/active_contracts.json'; + +export { + v0_7_0_alpha_active_contracts, + v1_0_0_mainnet_goerli_active_contracts, + v1_0_0_mumbai_active_contracts, +}; diff --git a/packages/contracts-versions/rollup.config.ts b/packages/contracts-versions/rollup.config.ts index 86c7ccbc0..10e8e2dfa 100644 --- a/packages/contracts-versions/rollup.config.ts +++ b/packages/contracts-versions/rollup.config.ts @@ -25,7 +25,7 @@ export default [ }, { input: 'npm/index.ts', - plugins: [dts()], + plugins: [dts(), json()], output: { dir: 'dist', entryFileNames: 'bundle.d.ts', From b9230a7a2207a09ad7d8ab3f04df8377ace3be6b Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Fri, 28 Apr 2023 14:35:53 +0300 Subject: [PATCH 033/112] update usage test --- packages/contracts-versions/npm/index.ts | 24 +------------------ .../contracts-versions/test/usage.test.ts | 24 ++++++++++++++----- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/packages/contracts-versions/npm/index.ts b/packages/contracts-versions/npm/index.ts index a818b18d0..13c9d7d72 100644 --- a/packages/contracts-versions/npm/index.ts +++ b/packages/contracts-versions/npm/index.ts @@ -1,27 +1,5 @@ -// Import and export the generated contract versions -// const versions = { -// v0_7_0_alpha: { -// typechain: () => import('../build/v0.7.0_alpha/typechain'), -// active_contracts: () => -// import('../build/v0.7.0_alpha/active_contracts.json'), -// }, -// v1_0_0_mainnet_goerli: { -// typechain: () => import('../build/v1.0.0_mainnet_goerli/typechain'), -// active_contracts: () => -// import('../build/v1.0.0_mainnet_goerli/active_contracts.json'), -// }, -// v1_0_0_mumbai: { -// typechain: () => import('../build/v1.0.0_mumbai/typechain'), -// active_contracts: () => -// import('../build/v1.0.0_mumbai/active_contracts.json'), -// }, -// // Add more versions here if needed -// }; - -// export default versions; - export * as v0_7_0_alpha_typechain from '../build/v0_7_0_alpha/typechain'; -import * as v0_7_0_alpha_active_contracts from '../build/v0.7.0_alpha/active_contracts.json'; +import * as v0_7_0_alpha_active_contracts from '../build/v0_7_0_alpha/active_contracts.json'; export * as v1_0_0_mainnet_goerli_typechain from '../build/v1_0_0_mainnet_goerli/typechain'; import * as v1_0_0_mainnet_goerli_active_contracts from '../build/v1_0_0_mainnet_goerli/active_contracts.json'; diff --git a/packages/contracts-versions/test/usage.test.ts b/packages/contracts-versions/test/usage.test.ts index cfb10c0c4..f49d1e703 100644 --- a/packages/contracts-versions/test/usage.test.ts +++ b/packages/contracts-versions/test/usage.test.ts @@ -1,15 +1,27 @@ -import versions from '@aragon/osx-versions'; +import { + v1_0_0_mainnet_goerli_active_contracts, + v1_0_0_mainnet_goerli_typechain, +} from '@aragon/osx-versions'; +import {ethers} from 'ethers'; describe('contract-versions', () => { it('should get typechain for a specific version', async () => { - const v0_7_0_alpha = versions.v0_7_0_alpha; - const types = await v0_7_0_alpha.typechain(); - expect(types).toBeDefined(); + const typechain = v1_0_0_mainnet_goerli_typechain; + expect(typechain).toBeDefined(); }); it('should get active contracts for a specific version', async () => { - const v0_7_0_alpha = versions.v0_7_0_alpha; - const activeContracts = await v0_7_0_alpha.active_contracts(); + const activeContracts = v1_0_0_mainnet_goerli_active_contracts; expect(activeContracts).toBeDefined(); }); + + it('should exported the types properly for a specific version', async () => { + const typechain = v1_0_0_mainnet_goerli_typechain; + const idao: v1_0_0_mainnet_goerli_typechain.IDAO = + typechain.IDAO__factory.connect( + ethers.constants.AddressZero, + ethers.providers.getDefaultProvider() + ); + expect(idao).toBeDefined(); + }); }); From 30c9593bdeceeb1ede4cc18bf832d81edfd9dca4 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Fri, 28 Apr 2023 14:48:01 +0300 Subject: [PATCH 034/112] generate index.ts dynamically --- packages/contracts-versions/.gitignore | 1 + .../create-contract-versions.ts | 21 +++++++++++++++++++ packages/contracts-versions/npm/index.ts | 14 ------------- 3 files changed, 22 insertions(+), 14 deletions(-) create mode 100644 packages/contracts-versions/.gitignore delete mode 100644 packages/contracts-versions/npm/index.ts diff --git a/packages/contracts-versions/.gitignore b/packages/contracts-versions/.gitignore new file mode 100644 index 000000000..bafa77460 --- /dev/null +++ b/packages/contracts-versions/.gitignore @@ -0,0 +1 @@ +npm/index.ts \ No newline at end of file diff --git a/packages/contracts-versions/create-contract-versions.ts b/packages/contracts-versions/create-contract-versions.ts index 59b1c84d1..69feb806f 100644 --- a/packages/contracts-versions/create-contract-versions.ts +++ b/packages/contracts-versions/create-contract-versions.ts @@ -80,6 +80,27 @@ async function createVersions() { // Return to the original branch await exec(`git checkout ${currentBranch}`, {cwd: contractsDir}); + + // Generate npm/index.ts file + const exports: string[] = []; + for (const version in commitHashes.versions) { + const versionName = version; + exports.push( + `export * as ${versionName}_typechain from '../build/${versionName}/typechain';` + ); + exports.push( + `import * as ${versionName}_active_contracts from '../build/${versionName}/active_contracts.json';` + ); + } + exports.push( + `export { ${Object.keys(commitHashes.versions) + .map(versionName => `${versionName}_active_contracts`) + .join(', ')} };` + ); + await fs.writeFile( + path.join(__dirname, 'npm', 'index.ts'), + exports.join('\n') + ); } createVersions(); diff --git a/packages/contracts-versions/npm/index.ts b/packages/contracts-versions/npm/index.ts deleted file mode 100644 index 13c9d7d72..000000000 --- a/packages/contracts-versions/npm/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -export * as v0_7_0_alpha_typechain from '../build/v0_7_0_alpha/typechain'; -import * as v0_7_0_alpha_active_contracts from '../build/v0_7_0_alpha/active_contracts.json'; - -export * as v1_0_0_mainnet_goerli_typechain from '../build/v1_0_0_mainnet_goerli/typechain'; -import * as v1_0_0_mainnet_goerli_active_contracts from '../build/v1_0_0_mainnet_goerli/active_contracts.json'; - -export * as v1_0_0_mumbai_typechain from '../build/v1_0_0_mumbai/typechain'; -import * as v1_0_0_mumbai_active_contracts from '../build/v1_0_0_mumbai/active_contracts.json'; - -export { - v0_7_0_alpha_active_contracts, - v1_0_0_mainnet_goerli_active_contracts, - v1_0_0_mumbai_active_contracts, -}; From 50e094cb07d1d6a2e03e3fc83adbf7c90b8f8405 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Fri, 28 Apr 2023 15:24:30 +0300 Subject: [PATCH 035/112] update readme --- packages/contracts-versions/README.md | 31 +++++++++++---------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/packages/contracts-versions/README.md b/packages/contracts-versions/README.md index 5ac2d3f81..bc590d9f5 100644 --- a/packages/contracts-versions/README.md +++ b/packages/contracts-versions/README.md @@ -5,45 +5,38 @@ A package to manage different contract versions and provide easy access to their ## Installation ```bash -npm install contracts-versions +npm install @aragon/osx-versions ``` or ```bash -yarn add contracts-versions +yarn add @aragon/osx-versions ``` ## Usage ```javascript -import versions from 'contracts-versions'; - -// Access specific contract version -const v0_7_0_alpha = versions.v0_7_0_alpha; - -// Get the types for a specific version -v0_7_0_alpha.types().then(types => { - // Use types here -}); - -// Get the active contracts for a specific version -v0_7_0_alpha.active_contracts().then(activeContracts => { - // Use active contracts here -}); +// import specific version +import {v0_7_0_alpha_active_contracts, v0_7_0_alpha_typechain} from '@aragon/osx-versions'; + +const typechain = v0_7_0_alpha_typechain; +const idao: v0_7_0_alpha_typechain.IDAO = typechain.IDAO__factory.connect( + ethers.constants.AddressZero, + ethers.providers.getDefaultProvider() +); ``` ## Adding new contract versions 1. Update `commit_hashes.json` with the new version name and the associated commit hash. -2. Run the `create-contract-versions.js` script to build and generate the new version: +2. Run the `create-contract-versions.ts` script to build and generate the new version: ```bash yarn build:contracts ``` -3. Add the new version to the `versions` object in `npm/index.ts`. -4. Run the Rollup build process: +3. Run the Rollup build process: ```bash yarn build:npm From 744f4f792e35cb2de6e5bb493748883bc67a4f2f Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Fri, 28 Apr 2023 15:25:53 +0300 Subject: [PATCH 036/112] add empty line --- packages/contracts-versions/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-versions/.gitignore b/packages/contracts-versions/.gitignore index bafa77460..3fe66d47a 100644 --- a/packages/contracts-versions/.gitignore +++ b/packages/contracts-versions/.gitignore @@ -1 +1 @@ -npm/index.ts \ No newline at end of file +npm/index.ts From ece3a1f7e7a8b637b5a0ea396bd64c5d377314bd Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 28 Apr 2023 15:25:58 +0200 Subject: [PATCH 037/112] update commit hashes --- packages/contracts-versions/commit_hashes.json | 4 +--- packages/contracts/test/upgrade/dao.ts | 5 ++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/contracts-versions/commit_hashes.json b/packages/contracts-versions/commit_hashes.json index c302aa9e0..9442c1fe5 100644 --- a/packages/contracts-versions/commit_hashes.json +++ b/packages/contracts-versions/commit_hashes.json @@ -1,7 +1,5 @@ { "versions": { - "v0_7_0_alpha": "9b912728c315f983af8c4bfd1f8d07021996563f", - "v1_0_0_mainnet_goerli": "c2b9d23a96654e81f22fbf91e6f334ef26a370af", - "v1_0_0_mumbai": "9485d97301611cfc78faa4bd00eb54abb6dd2d5e" + "v1_0_0": "c2b9d23a96654e81f22fbf91e6f334ef26a370af" } } diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index a9fda8c6d..223cc9b6a 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -2,7 +2,10 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; -import {DAO__factory, DAOV100, DAOV100__factory} from '../../typechain'; +import {DAO__factory} from '../../typechain'; + +import {v1_0_0} from '@aragon/osx-versions'; +import {ethers} from 'ethers'; import {daoExampleURI} from '../test-utils/dao'; From 62f5bdb46eb45dece36563a72137aa5aec194dff Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Fri, 28 Apr 2023 16:26:45 +0300 Subject: [PATCH 038/112] fix index.ts --- packages/contracts-versions/.gitignore | 2 +- packages/contracts-versions/create-contract-versions.ts | 9 +++------ packages/contracts-versions/rollup.config.ts | 4 ++-- packages/contracts-versions/tsconfig.json | 4 ++-- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/contracts-versions/.gitignore b/packages/contracts-versions/.gitignore index 3fe66d47a..1e21beece 100644 --- a/packages/contracts-versions/.gitignore +++ b/packages/contracts-versions/.gitignore @@ -1 +1 @@ -npm/index.ts +index.ts diff --git a/packages/contracts-versions/create-contract-versions.ts b/packages/contracts-versions/create-contract-versions.ts index 69feb806f..ae748296b 100644 --- a/packages/contracts-versions/create-contract-versions.ts +++ b/packages/contracts-versions/create-contract-versions.ts @@ -86,10 +86,10 @@ async function createVersions() { for (const version in commitHashes.versions) { const versionName = version; exports.push( - `export * as ${versionName}_typechain from '../build/${versionName}/typechain';` + `export * as ${versionName}_typechain from 'build/${versionName}/typechain';` ); exports.push( - `import * as ${versionName}_active_contracts from '../build/${versionName}/active_contracts.json';` + `import * as ${versionName}_active_contracts from 'build/${versionName}/active_contracts.json';` ); } exports.push( @@ -97,10 +97,7 @@ async function createVersions() { .map(versionName => `${versionName}_active_contracts`) .join(', ')} };` ); - await fs.writeFile( - path.join(__dirname, 'npm', 'index.ts'), - exports.join('\n') - ); + await fs.writeFile(path.join(__dirname, 'index.ts'), exports.join('\n')); } createVersions(); diff --git a/packages/contracts-versions/rollup.config.ts b/packages/contracts-versions/rollup.config.ts index 10e8e2dfa..882ed10df 100644 --- a/packages/contracts-versions/rollup.config.ts +++ b/packages/contracts-versions/rollup.config.ts @@ -4,7 +4,7 @@ import json from '@rollup/plugin-json'; export default [ { - input: 'npm/index.ts', + input: 'index.ts', plugins: [typescript({project: './tsconfig.json'}), json()], output: [ { @@ -24,7 +24,7 @@ export default [ ], }, { - input: 'npm/index.ts', + input: 'index.ts', plugins: [dts(), json()], output: { dir: 'dist', diff --git a/packages/contracts-versions/tsconfig.json b/packages/contracts-versions/tsconfig.json index f80bbfe2c..6a98523f1 100644 --- a/packages/contracts-versions/tsconfig.json +++ b/packages/contracts-versions/tsconfig.json @@ -14,6 +14,6 @@ "@aragon/osx-versions": ["node_modules/@aragon/osx-versions"] } }, - "include": ["./npm", "/build"], - "files": ["./npm/index.ts"] + "include": ["/build"], + "files": ["./index.ts"] } From 559d1545b8f1b80656a74fb1840ab5229203667c Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 28 Apr 2023 15:38:00 +0200 Subject: [PATCH 039/112] chore: update test --- packages/contracts/test/upgrade/dao.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 223cc9b6a..f0d33f139 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -4,8 +4,7 @@ import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {DAO__factory} from '../../typechain'; -import {v1_0_0} from '@aragon/osx-versions'; -import {ethers} from 'ethers'; +import {v1_0_0_active_contracts, v1_0_0_typechain} from '@aragon/osx-versions'; import {daoExampleURI} from '../test-utils/dao'; @@ -13,10 +12,11 @@ import {deployWithProxy} from '../test-utils/proxy'; import {UPGRADE_PERMISSIONS} from '../test-utils/permissions'; import {findEventTopicLog} from '../../utils/event'; import {readImplementationValueFromSlot} from '../../utils/storage'; +import {ContractFactory} from 'ethers'; let signers: SignerWithAddress[]; -let DaoV100: DAOV100__factory; -let DaoV110: DAO__factory; +let DaoV1_0_0: v1_0_0_typechain.DAO__factory; +let DaoCurrent: DAO__factory; const DUMMY_METADATA = ethers.utils.hexlify( ethers.utils.toUtf8Bytes('0x123456789') @@ -25,12 +25,12 @@ const DUMMY_METADATA = ethers.utils.hexlify( describe('DAO Upgrade', function () { before(async function () { signers = await ethers.getSigners(); - DaoV100 = new DAOV100__factory(signers[0]); - DaoV110 = new DAO__factory(signers[0]); + DaoV1_0_0 = new v1_0_0_typechain.DAO__factory(signers[0]); + DaoCurrent = new DAO__factory(signers[0]); }); it('upgrades v1.0.0 to v1.1.0', async () => { - const proxy = await deployWithProxy(DaoV100); + const proxy = await deployWithProxy(DaoV1_0_0); await proxy.initialize( DUMMY_METADATA, signers[0].address, @@ -50,7 +50,7 @@ describe('DAO Upgrade', function () { ); // Deploy the new implementation - const newImplementation = await DaoV110.deploy(); + const newImplementation = await DaoCurrent.deploy(); // Upgrade to the new implementation const upgradeTx = await proxy.upgradeTo(newImplementation.address); @@ -66,7 +66,7 @@ describe('DAO Upgrade', function () { // Check the emitted implementation. const emittedImplementation = ( - await findEventTopicLog(upgradeTx, DaoV100.interface, 'Upgraded') + await findEventTopicLog(upgradeTx, DaoV1_0_0.interface, 'Upgraded') ).args.implementation; expect(emittedImplementation).to.equal(newImplementation.address); From cd35fe04e5b6a6896ef3ce8e9d80b893621011b0 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 28 Apr 2023 15:41:45 +0200 Subject: [PATCH 040/112] fix: removed redundant imports --- packages/contracts/test/upgrade/dao.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index f0d33f139..e13905e90 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -3,16 +3,13 @@ import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {DAO__factory} from '../../typechain'; - -import {v1_0_0_active_contracts, v1_0_0_typechain} from '@aragon/osx-versions'; +import {v1_0_0_typechain} from '@aragon/osx-versions'; import {daoExampleURI} from '../test-utils/dao'; - import {deployWithProxy} from '../test-utils/proxy'; import {UPGRADE_PERMISSIONS} from '../test-utils/permissions'; import {findEventTopicLog} from '../../utils/event'; import {readImplementationValueFromSlot} from '../../utils/storage'; -import {ContractFactory} from 'ethers'; let signers: SignerWithAddress[]; let DaoV1_0_0: v1_0_0_typechain.DAO__factory; From 57f755cca767d96616195763d2611aebee6caf58 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 28 Apr 2023 15:42:03 +0200 Subject: [PATCH 041/112] chore: remove legacy version files of DAO --- .../core/dao/previous_versions/DAO_v1_0_0.sol | 340 ------------------ .../dao/previous_versions/IDAO_v1_0_0.sol | 136 ------- 2 files changed, 476 deletions(-) delete mode 100644 packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol delete mode 100644 packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol diff --git a/packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol b/packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol deleted file mode 100644 index 77c55af71..000000000 --- a/packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol +++ /dev/null @@ -1,340 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity 0.8.17; - -import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165StorageUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; -import "@openzeppelin/contracts/interfaces/IERC1271.sol"; - -import {PermissionManager} from "../../permission/PermissionManager.sol"; -import {CallbackHandler} from "../../utils/CallbackHandler.sol"; -import {hasBit, flipBit} from "../../utils/BitMap.sol"; -import {IEIP4824} from "../IEIP4824.sol"; -import {IDAO_v1_0_0} from "./IDAO_v1_0_0.sol"; - -/// @title DAO v1.0.0 -/// @author Aragon Association - 2021-2023 -/// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. -/// @dev Public API of the Aragon DAO framework. -contract DAO_v1_0_0 is - IEIP4824, - Initializable, - IERC1271, - ERC165StorageUpgradeable, - IDAO_v1_0_0, - UUPSUpgradeable, - PermissionManager, - CallbackHandler -{ - using SafeERC20Upgradeable for IERC20Upgradeable; - using AddressUpgradeable for address; - - /// @notice The ID of the permission required to call the `execute` function. - bytes32 public constant EXECUTE_PERMISSION_ID = keccak256("EXECUTE_PERMISSION"); - - /// @notice The ID of the permission required to call the `_authorizeUpgrade` function. - bytes32 public constant UPGRADE_DAO_PERMISSION_ID = keccak256("UPGRADE_DAO_PERMISSION"); - - /// @notice The ID of the permission required to call the `setMetadata` function. - bytes32 public constant SET_METADATA_PERMISSION_ID = keccak256("SET_METADATA_PERMISSION"); - - /// @notice The ID of the permission required to call the `setTrustedForwarder` function. - bytes32 public constant SET_TRUSTED_FORWARDER_PERMISSION_ID = - keccak256("SET_TRUSTED_FORWARDER_PERMISSION"); - - /// @notice The ID of the permission required to call the `setSignatureValidator` function. - bytes32 public constant SET_SIGNATURE_VALIDATOR_PERMISSION_ID = - keccak256("SET_SIGNATURE_VALIDATOR_PERMISSION"); - - /// @notice The ID of the permission required to call the `registerStandardCallback` function. - bytes32 public constant REGISTER_STANDARD_CALLBACK_PERMISSION_ID = - keccak256("REGISTER_STANDARD_CALLBACK_PERMISSION"); - - /// @notice The internal constant storing the maximal action array length. - uint256 internal constant MAX_ACTIONS = 256; - - /// @notice The [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. - IERC1271 public signatureValidator; - - /// @notice The address of the trusted forwarder verifying meta transactions. - address private trustedForwarder; - - /// @notice The [EIP-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO uri. - string private _daoURI; - - /// @notice Thrown if the action array length is larger than `MAX_ACTIONS`. - error TooManyActions(); - - /// @notice Thrown if action execution has failed. - /// @param index The index of the action in the action array that failed. - error ActionFailed(uint256 index); - - /// @notice Thrown if the deposit amount is zero. - error ZeroAmount(); - - /// @notice Thrown if there is a mismatch between the expected and actually deposited amount of native tokens. - /// @param expected The expected native token amount. - /// @param actual The actual native token amount deposited. - error NativeTokenDepositAmountMismatch(uint256 expected, uint256 actual); - - /// @notice Emitted when a new DAO uri is set. - /// @param daoURI The new uri. - event NewURI(string daoURI); - - /// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized. - constructor() { - _disableInitializers(); - } - - /// @notice Initializes the DAO by - /// - registering the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID - /// - setting the trusted forwarder for meta transactions - /// - giving the `ROOT_PERMISSION_ID` permission to the initial owner (that should be revoked and transferred to the DAO after setup). - /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). - /// @param _metadata IPFS hash that points to all the metadata (logo, description, tags, etc.) of a DAO. - /// @param _initialOwner The initial owner of the DAO having the `ROOT_PERMISSION_ID` permission. - /// @param _trustedForwarder The trusted forwarder responsible for verifying meta transactions. - function initialize( - bytes calldata _metadata, - address _initialOwner, - address _trustedForwarder, - string calldata daoURI_ - ) external initializer { - _registerInterface(type(IDAO_v1_0_0).interfaceId); - _registerInterface(type(IERC1271).interfaceId); - _registerInterface(type(IEIP4824).interfaceId); - _registerTokenInterfaces(); - - _setMetadata(_metadata); - _setTrustedForwarder(_trustedForwarder); - _setDaoURI(daoURI_); - __PermissionManager_init(_initialOwner); - } - - /// @inheritdoc PermissionManager - function isPermissionRestrictedForAnyAddr( - bytes32 _permissionId - ) internal pure override returns (bool) { - return - _permissionId == EXECUTE_PERMISSION_ID || - _permissionId == UPGRADE_DAO_PERMISSION_ID || - _permissionId == SET_METADATA_PERMISSION_ID || - _permissionId == SET_TRUSTED_FORWARDER_PERMISSION_ID || - _permissionId == SET_SIGNATURE_VALIDATOR_PERMISSION_ID || - _permissionId == REGISTER_STANDARD_CALLBACK_PERMISSION_ID; - } - - /// @notice Internal method authorizing the upgrade of the contract via the [upgradeabilty mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). - /// @dev The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. - function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {} - - /// @inheritdoc IDAO_v1_0_0 - function setTrustedForwarder( - address _newTrustedForwarder - ) external override auth(SET_TRUSTED_FORWARDER_PERMISSION_ID) { - _setTrustedForwarder(_newTrustedForwarder); - } - - /// @inheritdoc IDAO_v1_0_0 - function getTrustedForwarder() external view virtual override returns (address) { - return trustedForwarder; - } - - /// @inheritdoc IDAO_v1_0_0 - function hasPermission( - address _where, - address _who, - bytes32 _permissionId, - bytes memory _data - ) external view override returns (bool) { - return isGranted(_where, _who, _permissionId, _data); - } - - /// @inheritdoc IDAO_v1_0_0 - function setMetadata( - bytes calldata _metadata - ) external override auth(SET_METADATA_PERMISSION_ID) { - _setMetadata(_metadata); - } - - /// @inheritdoc IDAO_v1_0_0 - function execute( - bytes32 _callId, - Action[] calldata _actions, - uint256 _allowFailureMap - ) - external - override - auth(EXECUTE_PERMISSION_ID) - returns (bytes[] memory execResults, uint256 failureMap) - { - if (_actions.length > MAX_ACTIONS) { - revert TooManyActions(); - } - - execResults = new bytes[](_actions.length); - - for (uint256 i = 0; i < _actions.length; ) { - address to = _actions[i].to; - (bool success, bytes memory response) = to.call{value: _actions[i].value}( - _actions[i].data - ); - - if (!success) { - // If the call failed and wasn't allowed in allowFailureMap, revert. - if (!hasBit(_allowFailureMap, uint8(i))) { - revert ActionFailed(i); - } - - // If the call failed, but was allowed in allowFailureMap, store that - // this specific action has actually failed. - failureMap = flipBit(failureMap, uint8(i)); - } - - execResults[i] = response; - - unchecked { - ++i; - } - } - - emit Executed({ - actor: msg.sender, - callId: _callId, - actions: _actions, - failureMap: failureMap, - execResults: execResults - }); - } - - /// @inheritdoc IDAO_v1_0_0 - function deposit( - address _token, - uint256 _amount, - string calldata _reference - ) external payable override { - if (_amount == 0) revert ZeroAmount(); - - if (_token == address(0)) { - if (msg.value != _amount) - revert NativeTokenDepositAmountMismatch({expected: _amount, actual: msg.value}); - } else { - if (msg.value != 0) - revert NativeTokenDepositAmountMismatch({expected: 0, actual: msg.value}); - - IERC20Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _amount); - } - - emit Deposited(msg.sender, _token, _amount, _reference); - } - - /// @inheritdoc IDAO_v1_0_0 - function setSignatureValidator( - address _signatureValidator - ) external override auth(SET_SIGNATURE_VALIDATOR_PERMISSION_ID) { - signatureValidator = IERC1271(_signatureValidator); - - emit SignatureValidatorSet({signatureValidator: _signatureValidator}); - } - - /// @inheritdoc IDAO_v1_0_0 - function isValidSignature( - bytes32 _hash, - bytes memory _signature - ) external view override(IDAO_v1_0_0, IERC1271) returns (bytes4) { - if (address(signatureValidator) == address(0)) { - // Return the invalid magic number - return bytes4(0); - } - // Forward the call to the set signature validator contract - return signatureValidator.isValidSignature(_hash, _signature); - } - - /// @notice Emits the `NativeTokenDeposited` event to track native token deposits that weren't made via the deposit method. - /// @dev This call is bound by the gas limitations for `send`/`transfer` calls introduced by EIP-2929. - /// Gas cost increases in future hard forks might break this function. As an alternative, EIP-2930-type transactions using access lists can be employed. - receive() external payable { - emit NativeTokenDeposited(msg.sender, msg.value); - } - - /// @notice Fallback to handle future versions of the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) standard. - /// @param _input An alias being equivalent to `msg.data`. This feature of the fallback function was introduced with the [solidity compiler version 0.7.6](https://github.com/ethereum/solidity/releases/tag/v0.7.6) - /// @return The magic number registered for the function selector triggering the fallback. - fallback(bytes calldata _input) external returns (bytes memory) { - bytes4 magicNumber = _handleCallback(msg.sig, _input); - return abi.encode(magicNumber); - } - - /// @notice Emits the MetadataSet event if new metadata is set. - /// @param _metadata Hash of the IPFS metadata object. - function _setMetadata(bytes calldata _metadata) internal { - emit MetadataSet(_metadata); - } - - /// @notice Sets the trusted forwarder on the DAO and emits the associated event. - /// @param _trustedForwarder The trusted forwarder address. - function _setTrustedForwarder(address _trustedForwarder) internal { - trustedForwarder = _trustedForwarder; - - emit TrustedForwarderSet(_trustedForwarder); - } - - /// @notice Registers the ERC721/ERC1155 interfaces and callbacks. - function _registerTokenInterfaces() private { - _registerInterface(type(IERC721ReceiverUpgradeable).interfaceId); - _registerInterface(type(IERC1155ReceiverUpgradeable).interfaceId); - - _registerCallback( - IERC721ReceiverUpgradeable.onERC721Received.selector, - IERC721ReceiverUpgradeable.onERC721Received.selector - ); - _registerCallback( - IERC1155ReceiverUpgradeable.onERC1155Received.selector, - IERC1155ReceiverUpgradeable.onERC1155Received.selector - ); - _registerCallback( - IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector, - IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector - ); - } - - /// @inheritdoc IDAO_v1_0_0 - function registerStandardCallback( - bytes4 _interfaceId, - bytes4 _callbackSelector, - bytes4 _magicNumber - ) external override auth(REGISTER_STANDARD_CALLBACK_PERMISSION_ID) { - _registerInterface(_interfaceId); - _registerCallback(_callbackSelector, _magicNumber); - emit StandardCallbackRegistered(_interfaceId, _callbackSelector, _magicNumber); - } - - /// @inheritdoc IEIP4824 - function daoURI() external view returns (string memory) { - return _daoURI; - } - - /// @notice Updates the set DAO uri to a new value. - /// @param newDaoURI The new DAO uri to be set. - function setDaoURI(string calldata newDaoURI) external auth(SET_METADATA_PERMISSION_ID) { - _setDaoURI(newDaoURI); - } - - /// @notice Sets the new DAO uri and emits the associated event. - /// @param daoURI_ The new DAO uri. - function _setDaoURI(string calldata daoURI_) internal { - _daoURI = daoURI_; - - emit NewURI(daoURI_); - } - - /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). - uint256[47] private __gap; -} diff --git a/packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol b/packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol deleted file mode 100644 index f7318726b..000000000 --- a/packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol +++ /dev/null @@ -1,136 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity 0.8.17; - -/// @title IDAO v1.0.0 -/// @author Aragon Association - 2022-2023 -/// @notice The interface required for DAOs within the Aragon App DAO framework. -interface IDAO_v1_0_0 { - /// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call. - /// @param to The address to call. - /// @param value The native token value to be sent with the call. - /// @param data The bytes-encoded function selector and calldata for the call. - struct Action { - address to; - uint256 value; - bytes data; - } - - /// @notice Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process. - /// @param _where The address of the contract. - /// @param _who The address of a EOA or contract to give the permissions. - /// @param _permissionId The permission identifier. - /// @param _data The optional data passed to the `PermissionCondition` registered. - /// @return Returns true if the address has permission, false if not. - function hasPermission( - address _where, - address _who, - bytes32 _permissionId, - bytes memory _data - ) external view returns (bool); - - /// @notice Updates the DAO metadata (e.g., an IPFS hash). - /// @param _metadata The IPFS hash of the new metadata object. - function setMetadata(bytes calldata _metadata) external; - - /// @notice Emitted when the DAO metadata is updated. - /// @param metadata The IPFS hash of the new metadata object. - event MetadataSet(bytes metadata); - - /// @notice Executes a list of actions. If no failure map is provided, one failing action results in the entire excution to be reverted. If a non-zero failure map is provided, allowed actions can fail without the remaining actions being reverted. - /// @param _callId The ID of the call. The definition of the value of `callId` is up to the calling contract and can be used, e.g., as a nonce. - /// @param _actions The array of actions. - /// @param _allowFailureMap A bitmap allowing execution to succeed, even if individual actions might revert. If the bit at index `i` is 1, the execution succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. - /// @return The array of results obtained from the executed actions in `bytes`. - /// @return The constructed failureMap which contains which actions have actually failed. - function execute( - bytes32 _callId, - Action[] memory _actions, - uint256 _allowFailureMap - ) external returns (bytes[] memory, uint256); - - /// @notice Emitted when a proposal is executed. - /// @param actor The address of the caller. - /// @param callId The ID of the call. - /// @param actions The array of actions executed. - /// @param failureMap The failure map encoding which actions have failed. - /// @param execResults The array with the results of the executed actions. - /// @dev The value of `callId` is defined by the component/contract calling the execute function. A `Plugin` implementation can use it, for example, as a nonce. - event Executed( - address indexed actor, - bytes32 callId, - Action[] actions, - uint256 failureMap, - bytes[] execResults - ); - - /// @notice Emitted when a standard callback is registered. - /// @param interfaceId The ID of the interface. - /// @param callbackSelector The selector of the callback function. - /// @param magicNumber The magic number to be registered for the callback function selector. - event StandardCallbackRegistered( - bytes4 interfaceId, - bytes4 callbackSelector, - bytes4 magicNumber - ); - - /// @notice Deposits (native) tokens to the DAO contract with a reference string. - /// @param _token The address of the token or address(0) in case of the native token. - /// @param _amount The amount of tokens to deposit. - /// @param _reference The reference describing the deposit reason. - function deposit(address _token, uint256 _amount, string calldata _reference) external payable; - - /// @notice Emitted when a token deposit has been made to the DAO. - /// @param sender The address of the sender. - /// @param token The address of the deposited token. - /// @param amount The amount of tokens deposited. - /// @param _reference The reference describing the deposit reason. - event Deposited( - address indexed sender, - address indexed token, - uint256 amount, - string _reference - ); - - /// @notice Emitted when a native token deposit has been made to the DAO. - /// @dev This event is intended to be emitted in the `receive` function and is therefore bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929). - /// @param sender The address of the sender. - /// @param amount The amount of native tokens deposited. - event NativeTokenDeposited(address sender, uint256 amount); - - /// @notice Setter for the trusted forwarder verifying the meta transaction. - /// @param _trustedForwarder The trusted forwarder address. - function setTrustedForwarder(address _trustedForwarder) external; - - /// @notice Getter for the trusted forwarder verifying the meta transaction. - /// @return The trusted forwarder address. - function getTrustedForwarder() external view returns (address); - - /// @notice Emitted when a new TrustedForwarder is set on the DAO. - /// @param forwarder the new forwarder address. - event TrustedForwarderSet(address forwarder); - - /// @notice Setter for the [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. - /// @param _signatureValidator The address of the signature validator. - function setSignatureValidator(address _signatureValidator) external; - - /// @notice Emitted when the signature validator address is updated. - /// @param signatureValidator The address of the signature validator. - event SignatureValidatorSet(address signatureValidator); - - /// @notice Checks whether a signature is valid for the provided hash by forwarding the call to the set [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. - /// @param _hash The hash of the data to be signed. - /// @param _signature The signature byte array associated with `_hash`. - /// @return Returns the `bytes4` magic value `0x1626ba7e` if the signature is valid. - function isValidSignature(bytes32 _hash, bytes memory _signature) external returns (bytes4); - - /// @notice Registers an ERC standard having a callback by registering its [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID and callback function signature. - /// @param _interfaceId The ID of the interface. - /// @param _callbackSelector The selector of the callback function. - /// @param _magicNumber The magic number to be registered for the function signature. - function registerStandardCallback( - bytes4 _interfaceId, - bytes4 _callbackSelector, - bytes4 _magicNumber - ) external; -} From 8fb39dfc5fc242cfbdeae81d58a76a8ae62bb031 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 28 Apr 2023 15:57:28 +0200 Subject: [PATCH 042/112] fix: adapt contracts-version tests --- .../contracts-versions/test/usage.test.ts | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/contracts-versions/test/usage.test.ts b/packages/contracts-versions/test/usage.test.ts index f49d1e703..67aa5b07c 100644 --- a/packages/contracts-versions/test/usage.test.ts +++ b/packages/contracts-versions/test/usage.test.ts @@ -1,27 +1,23 @@ -import { - v1_0_0_mainnet_goerli_active_contracts, - v1_0_0_mainnet_goerli_typechain, -} from '@aragon/osx-versions'; +import {v1_0_0_active_contracts, v1_0_0_typechain} from '@aragon/osx-versions'; import {ethers} from 'ethers'; describe('contract-versions', () => { it('should get typechain for a specific version', async () => { - const typechain = v1_0_0_mainnet_goerli_typechain; + const typechain = v1_0_0_typechain; expect(typechain).toBeDefined(); }); it('should get active contracts for a specific version', async () => { - const activeContracts = v1_0_0_mainnet_goerli_active_contracts; + const activeContracts = v1_0_0_active_contracts; expect(activeContracts).toBeDefined(); }); it('should exported the types properly for a specific version', async () => { - const typechain = v1_0_0_mainnet_goerli_typechain; - const idao: v1_0_0_mainnet_goerli_typechain.IDAO = - typechain.IDAO__factory.connect( - ethers.constants.AddressZero, - ethers.providers.getDefaultProvider() - ); + const typechain = v1_0_0_typechain; + const idao: v1_0_0_typechain.IDAO = typechain.IDAO__factory.connect( + ethers.constants.AddressZero, + ethers.providers.getDefaultProvider() + ); expect(idao).toBeDefined(); }); }); From c40940985fe8ac923aa7e03ac56d2da1492b3c9f Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 28 Apr 2023 16:06:15 +0200 Subject: [PATCH 043/112] fix: remove version in title as contracts will get a constant --- packages/contracts/src/core/dao/DAO.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 1a05bb917..909b44bc4 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -19,7 +19,7 @@ import {hasBit, flipBit} from "../utils/BitMap.sol"; import {IEIP4824} from "./IEIP4824.sol"; import {IDAO} from "./IDAO.sol"; -/// @title DAO v1.1.0 +/// @title DAO /// @author Aragon Association - 2021-2023 /// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. /// @dev Public API of the Aragon DAO framework. From 403436c6a7fddcfc1dd998681642f6ba2b0cb75b Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 28 Apr 2023 16:18:22 +0200 Subject: [PATCH 044/112] fix: compile legacy contracts for regression testing --- .github/workflows/contract-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/contract-tests.yml b/.github/workflows/contract-tests.yml index 18e017ad5..7c257ff9d 100644 --- a/.github/workflows/contract-tests.yml +++ b/.github/workflows/contract-tests.yml @@ -28,6 +28,8 @@ jobs: run: yarn run formatting:check - name: Compile contracts run: yarn run build && yarn run build:npm + - name: Compile legacy contracts + run: cd ../contracts-versions/ && yarn build - name: Run Hardhat Tests env: REPORT_GAS: true From 1043debeadc1cf7c491d6a140cbe2aa6c53f78db Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 28 Apr 2023 16:18:22 +0200 Subject: [PATCH 045/112] Revert "fix: compile legacy contracts for regression testing " This reverts commit 403436c6a7fddcfc1dd998681642f6ba2b0cb75b. --- .github/workflows/contract-tests.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/contract-tests.yml b/.github/workflows/contract-tests.yml index 7c257ff9d..18e017ad5 100644 --- a/.github/workflows/contract-tests.yml +++ b/.github/workflows/contract-tests.yml @@ -28,8 +28,6 @@ jobs: run: yarn run formatting:check - name: Compile contracts run: yarn run build && yarn run build:npm - - name: Compile legacy contracts - run: cd ../contracts-versions/ && yarn build - name: Run Hardhat Tests env: REPORT_GAS: true From c900797502c6d1e101dd63e1d6b195d68afe79cd Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Tue, 2 May 2023 17:20:50 +0200 Subject: [PATCH 046/112] revert versioning changes --- .../contracts-versions/commit_hashes.json | 4 +++- .../contracts-versions/test/usage.test.ts | 20 +++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/contracts-versions/commit_hashes.json b/packages/contracts-versions/commit_hashes.json index 9442c1fe5..c302aa9e0 100644 --- a/packages/contracts-versions/commit_hashes.json +++ b/packages/contracts-versions/commit_hashes.json @@ -1,5 +1,7 @@ { "versions": { - "v1_0_0": "c2b9d23a96654e81f22fbf91e6f334ef26a370af" + "v0_7_0_alpha": "9b912728c315f983af8c4bfd1f8d07021996563f", + "v1_0_0_mainnet_goerli": "c2b9d23a96654e81f22fbf91e6f334ef26a370af", + "v1_0_0_mumbai": "9485d97301611cfc78faa4bd00eb54abb6dd2d5e" } } diff --git a/packages/contracts-versions/test/usage.test.ts b/packages/contracts-versions/test/usage.test.ts index 67aa5b07c..f49d1e703 100644 --- a/packages/contracts-versions/test/usage.test.ts +++ b/packages/contracts-versions/test/usage.test.ts @@ -1,23 +1,27 @@ -import {v1_0_0_active_contracts, v1_0_0_typechain} from '@aragon/osx-versions'; +import { + v1_0_0_mainnet_goerli_active_contracts, + v1_0_0_mainnet_goerli_typechain, +} from '@aragon/osx-versions'; import {ethers} from 'ethers'; describe('contract-versions', () => { it('should get typechain for a specific version', async () => { - const typechain = v1_0_0_typechain; + const typechain = v1_0_0_mainnet_goerli_typechain; expect(typechain).toBeDefined(); }); it('should get active contracts for a specific version', async () => { - const activeContracts = v1_0_0_active_contracts; + const activeContracts = v1_0_0_mainnet_goerli_active_contracts; expect(activeContracts).toBeDefined(); }); it('should exported the types properly for a specific version', async () => { - const typechain = v1_0_0_typechain; - const idao: v1_0_0_typechain.IDAO = typechain.IDAO__factory.connect( - ethers.constants.AddressZero, - ethers.providers.getDefaultProvider() - ); + const typechain = v1_0_0_mainnet_goerli_typechain; + const idao: v1_0_0_mainnet_goerli_typechain.IDAO = + typechain.IDAO__factory.connect( + ethers.constants.AddressZero, + ethers.providers.getDefaultProvider() + ); expect(idao).toBeDefined(); }); }); From 96297281f6a14b77a1f9148572e3bac193487362 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Tue, 2 May 2023 17:31:51 +0200 Subject: [PATCH 047/112] adapt tests --- packages/contracts/test/upgrade/dao.ts | 76 ++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index e13905e90..62ca7d05b 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -3,7 +3,10 @@ import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {DAO__factory} from '../../typechain'; -import {v1_0_0_typechain} from '@aragon/osx-versions'; +import { + v1_0_0_mainnet_goerli_typechain, + v1_0_0_mumbai_typechain, +} from '@aragon/osx-versions'; import {daoExampleURI} from '../test-utils/dao'; import {deployWithProxy} from '../test-utils/proxy'; @@ -12,7 +15,8 @@ import {findEventTopicLog} from '../../utils/event'; import {readImplementationValueFromSlot} from '../../utils/storage'; let signers: SignerWithAddress[]; -let DaoV1_0_0: v1_0_0_typechain.DAO__factory; +let Dao_mainnet_goerli_V1_0_0: v1_0_0_mainnet_goerli_typechain.DAO__factory; +let Dao_mumbai_V1_0_0: v1_0_0_mumbai_typechain.DAO__factory; let DaoCurrent: DAO__factory; const DUMMY_METADATA = ethers.utils.hexlify( @@ -22,12 +26,68 @@ const DUMMY_METADATA = ethers.utils.hexlify( describe('DAO Upgrade', function () { before(async function () { signers = await ethers.getSigners(); - DaoV1_0_0 = new v1_0_0_typechain.DAO__factory(signers[0]); + Dao_mainnet_goerli_V1_0_0 = + new v1_0_0_mainnet_goerli_typechain.DAO__factory(signers[0]); + Dao_mumbai_V1_0_0 = new v1_0_0_mumbai_typechain.DAO__factory(signers[0]); + DaoCurrent = new DAO__factory(signers[0]); }); - it('upgrades v1.0.0 to v1.1.0', async () => { - const proxy = await deployWithProxy(DaoV1_0_0); + it('upgrades mainnet/goerli v1.0.0 to v1.1.0', async () => { + const proxy = await deployWithProxy( + Dao_mainnet_goerli_V1_0_0 + ); + await proxy.initialize( + DUMMY_METADATA, + signers[0].address, + ethers.constants.AddressZero, + daoExampleURI + ); + + // Store the current implementation + const implementationBeforeUpgrade = await readImplementationValueFromSlot( + proxy.address + ); + + proxy.grant( + proxy.address, + signers[0].address, + UPGRADE_PERMISSIONS.UPGRADE_DAO_PERMISSION_ID + ); + + // Deploy the new implementation + const newImplementation = await DaoCurrent.deploy(); + + // Upgrade to the new implementation + const upgradeTx = await proxy.upgradeTo(newImplementation.address); + + // Check the stored implementation. + const implementationAfterUpgrade = await readImplementationValueFromSlot( + proxy.address + ); + expect(implementationAfterUpgrade).to.equal(newImplementation.address); + expect(implementationAfterUpgrade).to.not.equal( + implementationBeforeUpgrade + ); + + // Check the emitted implementation. + const emittedImplementation = ( + await findEventTopicLog( + upgradeTx, + Dao_mainnet_goerli_V1_0_0.interface, + 'Upgraded' + ) + ).args.implementation; + expect(emittedImplementation).to.equal(newImplementation.address); + + // Check that storage is not corrupted. + expect(await proxy.callStatic.daoURI()).to.equal(daoExampleURI); + }); + + it('upgrades mumbai v1.0.0 to v1.1.0', async () => { + const proxy = await deployWithProxy( + Dao_mumbai_V1_0_0 + ); await proxy.initialize( DUMMY_METADATA, signers[0].address, @@ -63,7 +123,11 @@ describe('DAO Upgrade', function () { // Check the emitted implementation. const emittedImplementation = ( - await findEventTopicLog(upgradeTx, DaoV1_0_0.interface, 'Upgraded') + await findEventTopicLog( + upgradeTx, + Dao_mumbai_V1_0_0.interface, + 'Upgraded' + ) ).args.implementation; expect(emittedImplementation).to.equal(newImplementation.address); From 6261b854492f906e9a2199848ce1f975a9706319 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 2 May 2023 17:41:27 +0200 Subject: [PATCH 048/112] test with creating symbolic link --- .github/workflows/contract-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/contract-tests.yml b/.github/workflows/contract-tests.yml index b9d563b63..12147d1c2 100644 --- a/.github/workflows/contract-tests.yml +++ b/.github/workflows/contract-tests.yml @@ -34,6 +34,8 @@ jobs: run: rm -rf artifact cache deployments typechain - name: Check formatting run: yarn run formatting:check + - name: Create symlink to contracts-versions + run: ln -s ../contracts-versions node_modules/@aragon/osx-versions - name: Compile contracts run: yarn run build && yarn run build:npm - name: Run Hardhat Tests From b2df3f0e9dcff206a2cd7f6671f5360c84a9b6dc Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Tue, 2 May 2023 18:12:37 +0200 Subject: [PATCH 049/112] correct path --- .github/workflows/contract-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/contract-tests.yml b/.github/workflows/contract-tests.yml index 12147d1c2..5ad68b3e8 100644 --- a/.github/workflows/contract-tests.yml +++ b/.github/workflows/contract-tests.yml @@ -35,7 +35,7 @@ jobs: - name: Check formatting run: yarn run formatting:check - name: Create symlink to contracts-versions - run: ln -s ../contracts-versions node_modules/@aragon/osx-versions + run: ln -s ../contracts-versions ../../node_modules/@aragon/osx-versions - name: Compile contracts run: yarn run build && yarn run build:npm - name: Run Hardhat Tests From 57ecd706f12ec307fb1bb025e708c19a4136e828 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 3 May 2023 18:25:21 +0200 Subject: [PATCH 050/112] feat: added tests for proposal start and end date handling --- .../addresslist/addresslist-voting.ts | 28 +++++++++++++++++ .../majority-voting/token/token-voting.ts | 30 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts index f29f26f55..b37122e81 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts @@ -394,6 +394,34 @@ describe('AddresslistVoting', function () { .withArgs(earliestEndDate, tooEarlyEndDate); }); + it('sets the start date to now and end date to now + minDuration if 0 is provided as an input', async () => { + await voting.initialize(dao.address, votingSettings, [ + signers[0].address, + ]); + const startDate = 0; // now + const endDate = 0; // startDate + minDuration + + const creationTx = await voting.createProposal( + dummyMetadata, + [], + 0, + startDate, + endDate, + VoteOption.None, + false + ); + + const currentTime = ( + await ethers.provider.getBlock((await creationTx.wait()).blockNumber) + ).timestamp; + const proposalData = await voting.getProposal(id); + + expect(proposalData.parameters.startDate).to.eq(currentTime); + expect(proposalData.parameters.endDate).to.eq( + currentTime + votingSettings.minDuration + ); + }); + it('ceils the `minVotingPower` value if it has a remainder', async () => { votingSettings.minParticipation = pctToRatio(30).add(1); // 30.0001 % diff --git a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts index 378e619a6..3c641c3c6 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts @@ -489,6 +489,36 @@ describe('TokenVoting', function () { .withArgs(earliestEndDate, tooEarlyEndDate); }); + it('sets the start date to now and end date to now + minDuration if 0 is provided as an input', async () => { + await voting.initialize( + dao.address, + votingSettings, + governanceErc20Mock.address + ); + const startDate = 0; // now + const endDate = 0; // startDate + minDuration + + const creationTx = await voting.createProposal( + dummyMetadata, + [], + 0, + startDate, + endDate, + VoteOption.None, + false + ); + + const currentTime = ( + await ethers.provider.getBlock((await creationTx.wait()).blockNumber) + ).timestamp; + const proposalData = await voting.getProposal(id); + + expect(proposalData.parameters.startDate).to.eq(currentTime); + expect(proposalData.parameters.endDate).to.eq( + currentTime + votingSettings.minDuration + ); + }); + it('ceils the `minVotingPower` value if it has a remainder', async () => { votingSettings.minParticipation = pctToRatio(30).add(1); // 30.0001 % From ca5235133678e7a5d8bd87a20af27edbb0a877a6 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 3 May 2023 19:01:33 +0200 Subject: [PATCH 051/112] fix: corrected wrong validation order --- .../addresslist/AddresslistVoting.sol | 8 +++--- .../majority-voting/token/TokenVoting.sol | 8 +++--- .../addresslist/addresslist-voting.ts | 26 +++++++++++++++---- .../majority-voting/token/token-voting.ts | 26 +++++++++++++++---- 4 files changed, 50 insertions(+), 18 deletions(-) diff --git a/packages/contracts/src/plugins/governance/majority-voting/addresslist/AddresslistVoting.sol b/packages/contracts/src/plugins/governance/majority-voting/addresslist/AddresslistVoting.sol index 1ca96245e..ecd401aaa 100644 --- a/packages/contracts/src/plugins/governance/majority-voting/addresslist/AddresslistVoting.sol +++ b/packages/contracts/src/plugins/governance/majority-voting/addresslist/AddresslistVoting.sol @@ -98,6 +98,8 @@ contract AddresslistVoting is IMembership, Addresslist, MajorityVotingBase { revert ProposalCreationForbidden(_msgSender()); } + (_startDate, _endDate) = _validateProposalDates(_startDate, _endDate); + proposalId = _createProposal({ _creator: _msgSender(), _metadata: _metadata, @@ -110,10 +112,8 @@ contract AddresslistVoting is IMembership, Addresslist, MajorityVotingBase { // Store proposal related information Proposal storage proposal_ = proposals[proposalId]; - (proposal_.parameters.startDate, proposal_.parameters.endDate) = _validateProposalDates({ - _start: _startDate, - _end: _endDate - }); + proposal_.parameters.startDate = _startDate; + proposal_.parameters.endDate = _endDate; proposal_.parameters.snapshotBlock = snapshotBlock; proposal_.parameters.votingMode = votingMode(); proposal_.parameters.supportThreshold = supportThreshold(); diff --git a/packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol b/packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol index 7b6c6089d..a941bb1ae 100644 --- a/packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol +++ b/packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol @@ -92,6 +92,8 @@ contract TokenVoting is IMembership, MajorityVotingBase { revert ProposalCreationForbidden(_msgSender()); } + (_startDate, _endDate) = _validateProposalDates(_startDate, _endDate); + proposalId = _createProposal({ _creator: _msgSender(), _metadata: _metadata, @@ -104,10 +106,8 @@ contract TokenVoting is IMembership, MajorityVotingBase { // Store proposal related information Proposal storage proposal_ = proposals[proposalId]; - (proposal_.parameters.startDate, proposal_.parameters.endDate) = _validateProposalDates( - _startDate, - _endDate - ); + proposal_.parameters.startDate = _startDate; + proposal_.parameters.endDate = _endDate; proposal_.parameters.snapshotBlock = snapshotBlock.toUint64(); proposal_.parameters.votingMode = votingMode(); proposal_.parameters.supportThreshold = supportThreshold(); diff --git a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts index b37122e81..af87c9bfc 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts @@ -394,7 +394,7 @@ describe('AddresslistVoting', function () { .withArgs(earliestEndDate, tooEarlyEndDate); }); - it('sets the start date to now and end date to now + minDuration if 0 is provided as an input', async () => { + it('sets the startDate to now and endDate to startDate + minDuration, if 0 is provided as an input', async () => { await voting.initialize(dao.address, votingSettings, [ signers[0].address, ]); @@ -414,12 +414,28 @@ describe('AddresslistVoting', function () { const currentTime = ( await ethers.provider.getBlock((await creationTx.wait()).blockNumber) ).timestamp; - const proposalData = await voting.getProposal(id); - expect(proposalData.parameters.startDate).to.eq(currentTime); - expect(proposalData.parameters.endDate).to.eq( - currentTime + votingSettings.minDuration + const expectedStartDate = currentTime; + const expectedEndDate = expectedStartDate + votingSettings.minDuration; + + // Check the state + const proposal = await voting.getProposal(id); + expect(proposal.parameters.startDate).to.eq(expectedStartDate); + expect(proposal.parameters.endDate).to.eq(expectedEndDate); + + // Check the event + const event = await findEvent( + creationTx, + 'ProposalCreated' ); + + expect(event.args.proposalId).to.equal(id); + expect(event.args.creator).to.equal(signers[0].address); + expect(event.args.startDate).to.equal(expectedStartDate); + expect(event.args.endDate).to.equal(expectedEndDate); + expect(event.args.metadata).to.equal(dummyMetadata); + expect(event.args.actions).to.deep.equal([]); + expect(event.args.allowFailureMap).to.equal(0); }); it('ceils the `minVotingPower` value if it has a remainder', async () => { diff --git a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts index 3c641c3c6..4cf49f499 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts @@ -489,7 +489,7 @@ describe('TokenVoting', function () { .withArgs(earliestEndDate, tooEarlyEndDate); }); - it('sets the start date to now and end date to now + minDuration if 0 is provided as an input', async () => { + it('sets the startDate to now and endDate to startDate + minDuration, if 0 is provided as an input', async () => { await voting.initialize( dao.address, votingSettings, @@ -511,12 +511,28 @@ describe('TokenVoting', function () { const currentTime = ( await ethers.provider.getBlock((await creationTx.wait()).blockNumber) ).timestamp; - const proposalData = await voting.getProposal(id); - expect(proposalData.parameters.startDate).to.eq(currentTime); - expect(proposalData.parameters.endDate).to.eq( - currentTime + votingSettings.minDuration + const expectedStartDate = currentTime; + const expectedEndDate = expectedStartDate + votingSettings.minDuration; + + // heck the state + const proposal = await voting.getProposal(id); + expect(proposal.parameters.startDate).to.eq(expectedStartDate); + expect(proposal.parameters.endDate).to.eq(expectedEndDate); + + // Check the event + const event = await findEvent( + creationTx, + 'ProposalCreated' ); + + expect(event.args.proposalId).to.equal(id); + expect(event.args.creator).to.equal(signers[0].address); + expect(event.args.startDate).to.equal(expectedStartDate); + expect(event.args.endDate).to.equal(expectedEndDate); + expect(event.args.metadata).to.equal(dummyMetadata); + expect(event.args.actions).to.deep.equal([]); + expect(event.args.allowFailureMap).to.equal(0); }); it('ceils the `minVotingPower` value if it has a remainder', async () => { From abfa6af07be413af91dde0bcbb91b11860349612 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 28 Apr 2023 15:42:03 +0200 Subject: [PATCH 052/112] Revert "chore: remove legacy version files of DAO" This reverts commit 57f755cca767d96616195763d2611aebee6caf58. --- .../core/dao/previous_versions/DAO_v1_0_0.sol | 340 ++++++++++++++++++ .../dao/previous_versions/IDAO_v1_0_0.sol | 136 +++++++ 2 files changed, 476 insertions(+) create mode 100644 packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol create mode 100644 packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol diff --git a/packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol b/packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol new file mode 100644 index 000000000..77c55af71 --- /dev/null +++ b/packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.17; + +import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165StorageUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; +import "@openzeppelin/contracts/interfaces/IERC1271.sol"; + +import {PermissionManager} from "../../permission/PermissionManager.sol"; +import {CallbackHandler} from "../../utils/CallbackHandler.sol"; +import {hasBit, flipBit} from "../../utils/BitMap.sol"; +import {IEIP4824} from "../IEIP4824.sol"; +import {IDAO_v1_0_0} from "./IDAO_v1_0_0.sol"; + +/// @title DAO v1.0.0 +/// @author Aragon Association - 2021-2023 +/// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. +/// @dev Public API of the Aragon DAO framework. +contract DAO_v1_0_0 is + IEIP4824, + Initializable, + IERC1271, + ERC165StorageUpgradeable, + IDAO_v1_0_0, + UUPSUpgradeable, + PermissionManager, + CallbackHandler +{ + using SafeERC20Upgradeable for IERC20Upgradeable; + using AddressUpgradeable for address; + + /// @notice The ID of the permission required to call the `execute` function. + bytes32 public constant EXECUTE_PERMISSION_ID = keccak256("EXECUTE_PERMISSION"); + + /// @notice The ID of the permission required to call the `_authorizeUpgrade` function. + bytes32 public constant UPGRADE_DAO_PERMISSION_ID = keccak256("UPGRADE_DAO_PERMISSION"); + + /// @notice The ID of the permission required to call the `setMetadata` function. + bytes32 public constant SET_METADATA_PERMISSION_ID = keccak256("SET_METADATA_PERMISSION"); + + /// @notice The ID of the permission required to call the `setTrustedForwarder` function. + bytes32 public constant SET_TRUSTED_FORWARDER_PERMISSION_ID = + keccak256("SET_TRUSTED_FORWARDER_PERMISSION"); + + /// @notice The ID of the permission required to call the `setSignatureValidator` function. + bytes32 public constant SET_SIGNATURE_VALIDATOR_PERMISSION_ID = + keccak256("SET_SIGNATURE_VALIDATOR_PERMISSION"); + + /// @notice The ID of the permission required to call the `registerStandardCallback` function. + bytes32 public constant REGISTER_STANDARD_CALLBACK_PERMISSION_ID = + keccak256("REGISTER_STANDARD_CALLBACK_PERMISSION"); + + /// @notice The internal constant storing the maximal action array length. + uint256 internal constant MAX_ACTIONS = 256; + + /// @notice The [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. + IERC1271 public signatureValidator; + + /// @notice The address of the trusted forwarder verifying meta transactions. + address private trustedForwarder; + + /// @notice The [EIP-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO uri. + string private _daoURI; + + /// @notice Thrown if the action array length is larger than `MAX_ACTIONS`. + error TooManyActions(); + + /// @notice Thrown if action execution has failed. + /// @param index The index of the action in the action array that failed. + error ActionFailed(uint256 index); + + /// @notice Thrown if the deposit amount is zero. + error ZeroAmount(); + + /// @notice Thrown if there is a mismatch between the expected and actually deposited amount of native tokens. + /// @param expected The expected native token amount. + /// @param actual The actual native token amount deposited. + error NativeTokenDepositAmountMismatch(uint256 expected, uint256 actual); + + /// @notice Emitted when a new DAO uri is set. + /// @param daoURI The new uri. + event NewURI(string daoURI); + + /// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized. + constructor() { + _disableInitializers(); + } + + /// @notice Initializes the DAO by + /// - registering the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID + /// - setting the trusted forwarder for meta transactions + /// - giving the `ROOT_PERMISSION_ID` permission to the initial owner (that should be revoked and transferred to the DAO after setup). + /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). + /// @param _metadata IPFS hash that points to all the metadata (logo, description, tags, etc.) of a DAO. + /// @param _initialOwner The initial owner of the DAO having the `ROOT_PERMISSION_ID` permission. + /// @param _trustedForwarder The trusted forwarder responsible for verifying meta transactions. + function initialize( + bytes calldata _metadata, + address _initialOwner, + address _trustedForwarder, + string calldata daoURI_ + ) external initializer { + _registerInterface(type(IDAO_v1_0_0).interfaceId); + _registerInterface(type(IERC1271).interfaceId); + _registerInterface(type(IEIP4824).interfaceId); + _registerTokenInterfaces(); + + _setMetadata(_metadata); + _setTrustedForwarder(_trustedForwarder); + _setDaoURI(daoURI_); + __PermissionManager_init(_initialOwner); + } + + /// @inheritdoc PermissionManager + function isPermissionRestrictedForAnyAddr( + bytes32 _permissionId + ) internal pure override returns (bool) { + return + _permissionId == EXECUTE_PERMISSION_ID || + _permissionId == UPGRADE_DAO_PERMISSION_ID || + _permissionId == SET_METADATA_PERMISSION_ID || + _permissionId == SET_TRUSTED_FORWARDER_PERMISSION_ID || + _permissionId == SET_SIGNATURE_VALIDATOR_PERMISSION_ID || + _permissionId == REGISTER_STANDARD_CALLBACK_PERMISSION_ID; + } + + /// @notice Internal method authorizing the upgrade of the contract via the [upgradeabilty mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). + /// @dev The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. + function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {} + + /// @inheritdoc IDAO_v1_0_0 + function setTrustedForwarder( + address _newTrustedForwarder + ) external override auth(SET_TRUSTED_FORWARDER_PERMISSION_ID) { + _setTrustedForwarder(_newTrustedForwarder); + } + + /// @inheritdoc IDAO_v1_0_0 + function getTrustedForwarder() external view virtual override returns (address) { + return trustedForwarder; + } + + /// @inheritdoc IDAO_v1_0_0 + function hasPermission( + address _where, + address _who, + bytes32 _permissionId, + bytes memory _data + ) external view override returns (bool) { + return isGranted(_where, _who, _permissionId, _data); + } + + /// @inheritdoc IDAO_v1_0_0 + function setMetadata( + bytes calldata _metadata + ) external override auth(SET_METADATA_PERMISSION_ID) { + _setMetadata(_metadata); + } + + /// @inheritdoc IDAO_v1_0_0 + function execute( + bytes32 _callId, + Action[] calldata _actions, + uint256 _allowFailureMap + ) + external + override + auth(EXECUTE_PERMISSION_ID) + returns (bytes[] memory execResults, uint256 failureMap) + { + if (_actions.length > MAX_ACTIONS) { + revert TooManyActions(); + } + + execResults = new bytes[](_actions.length); + + for (uint256 i = 0; i < _actions.length; ) { + address to = _actions[i].to; + (bool success, bytes memory response) = to.call{value: _actions[i].value}( + _actions[i].data + ); + + if (!success) { + // If the call failed and wasn't allowed in allowFailureMap, revert. + if (!hasBit(_allowFailureMap, uint8(i))) { + revert ActionFailed(i); + } + + // If the call failed, but was allowed in allowFailureMap, store that + // this specific action has actually failed. + failureMap = flipBit(failureMap, uint8(i)); + } + + execResults[i] = response; + + unchecked { + ++i; + } + } + + emit Executed({ + actor: msg.sender, + callId: _callId, + actions: _actions, + failureMap: failureMap, + execResults: execResults + }); + } + + /// @inheritdoc IDAO_v1_0_0 + function deposit( + address _token, + uint256 _amount, + string calldata _reference + ) external payable override { + if (_amount == 0) revert ZeroAmount(); + + if (_token == address(0)) { + if (msg.value != _amount) + revert NativeTokenDepositAmountMismatch({expected: _amount, actual: msg.value}); + } else { + if (msg.value != 0) + revert NativeTokenDepositAmountMismatch({expected: 0, actual: msg.value}); + + IERC20Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _amount); + } + + emit Deposited(msg.sender, _token, _amount, _reference); + } + + /// @inheritdoc IDAO_v1_0_0 + function setSignatureValidator( + address _signatureValidator + ) external override auth(SET_SIGNATURE_VALIDATOR_PERMISSION_ID) { + signatureValidator = IERC1271(_signatureValidator); + + emit SignatureValidatorSet({signatureValidator: _signatureValidator}); + } + + /// @inheritdoc IDAO_v1_0_0 + function isValidSignature( + bytes32 _hash, + bytes memory _signature + ) external view override(IDAO_v1_0_0, IERC1271) returns (bytes4) { + if (address(signatureValidator) == address(0)) { + // Return the invalid magic number + return bytes4(0); + } + // Forward the call to the set signature validator contract + return signatureValidator.isValidSignature(_hash, _signature); + } + + /// @notice Emits the `NativeTokenDeposited` event to track native token deposits that weren't made via the deposit method. + /// @dev This call is bound by the gas limitations for `send`/`transfer` calls introduced by EIP-2929. + /// Gas cost increases in future hard forks might break this function. As an alternative, EIP-2930-type transactions using access lists can be employed. + receive() external payable { + emit NativeTokenDeposited(msg.sender, msg.value); + } + + /// @notice Fallback to handle future versions of the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) standard. + /// @param _input An alias being equivalent to `msg.data`. This feature of the fallback function was introduced with the [solidity compiler version 0.7.6](https://github.com/ethereum/solidity/releases/tag/v0.7.6) + /// @return The magic number registered for the function selector triggering the fallback. + fallback(bytes calldata _input) external returns (bytes memory) { + bytes4 magicNumber = _handleCallback(msg.sig, _input); + return abi.encode(magicNumber); + } + + /// @notice Emits the MetadataSet event if new metadata is set. + /// @param _metadata Hash of the IPFS metadata object. + function _setMetadata(bytes calldata _metadata) internal { + emit MetadataSet(_metadata); + } + + /// @notice Sets the trusted forwarder on the DAO and emits the associated event. + /// @param _trustedForwarder The trusted forwarder address. + function _setTrustedForwarder(address _trustedForwarder) internal { + trustedForwarder = _trustedForwarder; + + emit TrustedForwarderSet(_trustedForwarder); + } + + /// @notice Registers the ERC721/ERC1155 interfaces and callbacks. + function _registerTokenInterfaces() private { + _registerInterface(type(IERC721ReceiverUpgradeable).interfaceId); + _registerInterface(type(IERC1155ReceiverUpgradeable).interfaceId); + + _registerCallback( + IERC721ReceiverUpgradeable.onERC721Received.selector, + IERC721ReceiverUpgradeable.onERC721Received.selector + ); + _registerCallback( + IERC1155ReceiverUpgradeable.onERC1155Received.selector, + IERC1155ReceiverUpgradeable.onERC1155Received.selector + ); + _registerCallback( + IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector, + IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector + ); + } + + /// @inheritdoc IDAO_v1_0_0 + function registerStandardCallback( + bytes4 _interfaceId, + bytes4 _callbackSelector, + bytes4 _magicNumber + ) external override auth(REGISTER_STANDARD_CALLBACK_PERMISSION_ID) { + _registerInterface(_interfaceId); + _registerCallback(_callbackSelector, _magicNumber); + emit StandardCallbackRegistered(_interfaceId, _callbackSelector, _magicNumber); + } + + /// @inheritdoc IEIP4824 + function daoURI() external view returns (string memory) { + return _daoURI; + } + + /// @notice Updates the set DAO uri to a new value. + /// @param newDaoURI The new DAO uri to be set. + function setDaoURI(string calldata newDaoURI) external auth(SET_METADATA_PERMISSION_ID) { + _setDaoURI(newDaoURI); + } + + /// @notice Sets the new DAO uri and emits the associated event. + /// @param daoURI_ The new DAO uri. + function _setDaoURI(string calldata daoURI_) internal { + _daoURI = daoURI_; + + emit NewURI(daoURI_); + } + + /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). + uint256[47] private __gap; +} diff --git a/packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol b/packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol new file mode 100644 index 000000000..f7318726b --- /dev/null +++ b/packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.17; + +/// @title IDAO v1.0.0 +/// @author Aragon Association - 2022-2023 +/// @notice The interface required for DAOs within the Aragon App DAO framework. +interface IDAO_v1_0_0 { + /// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call. + /// @param to The address to call. + /// @param value The native token value to be sent with the call. + /// @param data The bytes-encoded function selector and calldata for the call. + struct Action { + address to; + uint256 value; + bytes data; + } + + /// @notice Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process. + /// @param _where The address of the contract. + /// @param _who The address of a EOA or contract to give the permissions. + /// @param _permissionId The permission identifier. + /// @param _data The optional data passed to the `PermissionCondition` registered. + /// @return Returns true if the address has permission, false if not. + function hasPermission( + address _where, + address _who, + bytes32 _permissionId, + bytes memory _data + ) external view returns (bool); + + /// @notice Updates the DAO metadata (e.g., an IPFS hash). + /// @param _metadata The IPFS hash of the new metadata object. + function setMetadata(bytes calldata _metadata) external; + + /// @notice Emitted when the DAO metadata is updated. + /// @param metadata The IPFS hash of the new metadata object. + event MetadataSet(bytes metadata); + + /// @notice Executes a list of actions. If no failure map is provided, one failing action results in the entire excution to be reverted. If a non-zero failure map is provided, allowed actions can fail without the remaining actions being reverted. + /// @param _callId The ID of the call. The definition of the value of `callId` is up to the calling contract and can be used, e.g., as a nonce. + /// @param _actions The array of actions. + /// @param _allowFailureMap A bitmap allowing execution to succeed, even if individual actions might revert. If the bit at index `i` is 1, the execution succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. + /// @return The array of results obtained from the executed actions in `bytes`. + /// @return The constructed failureMap which contains which actions have actually failed. + function execute( + bytes32 _callId, + Action[] memory _actions, + uint256 _allowFailureMap + ) external returns (bytes[] memory, uint256); + + /// @notice Emitted when a proposal is executed. + /// @param actor The address of the caller. + /// @param callId The ID of the call. + /// @param actions The array of actions executed. + /// @param failureMap The failure map encoding which actions have failed. + /// @param execResults The array with the results of the executed actions. + /// @dev The value of `callId` is defined by the component/contract calling the execute function. A `Plugin` implementation can use it, for example, as a nonce. + event Executed( + address indexed actor, + bytes32 callId, + Action[] actions, + uint256 failureMap, + bytes[] execResults + ); + + /// @notice Emitted when a standard callback is registered. + /// @param interfaceId The ID of the interface. + /// @param callbackSelector The selector of the callback function. + /// @param magicNumber The magic number to be registered for the callback function selector. + event StandardCallbackRegistered( + bytes4 interfaceId, + bytes4 callbackSelector, + bytes4 magicNumber + ); + + /// @notice Deposits (native) tokens to the DAO contract with a reference string. + /// @param _token The address of the token or address(0) in case of the native token. + /// @param _amount The amount of tokens to deposit. + /// @param _reference The reference describing the deposit reason. + function deposit(address _token, uint256 _amount, string calldata _reference) external payable; + + /// @notice Emitted when a token deposit has been made to the DAO. + /// @param sender The address of the sender. + /// @param token The address of the deposited token. + /// @param amount The amount of tokens deposited. + /// @param _reference The reference describing the deposit reason. + event Deposited( + address indexed sender, + address indexed token, + uint256 amount, + string _reference + ); + + /// @notice Emitted when a native token deposit has been made to the DAO. + /// @dev This event is intended to be emitted in the `receive` function and is therefore bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929). + /// @param sender The address of the sender. + /// @param amount The amount of native tokens deposited. + event NativeTokenDeposited(address sender, uint256 amount); + + /// @notice Setter for the trusted forwarder verifying the meta transaction. + /// @param _trustedForwarder The trusted forwarder address. + function setTrustedForwarder(address _trustedForwarder) external; + + /// @notice Getter for the trusted forwarder verifying the meta transaction. + /// @return The trusted forwarder address. + function getTrustedForwarder() external view returns (address); + + /// @notice Emitted when a new TrustedForwarder is set on the DAO. + /// @param forwarder the new forwarder address. + event TrustedForwarderSet(address forwarder); + + /// @notice Setter for the [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. + /// @param _signatureValidator The address of the signature validator. + function setSignatureValidator(address _signatureValidator) external; + + /// @notice Emitted when the signature validator address is updated. + /// @param signatureValidator The address of the signature validator. + event SignatureValidatorSet(address signatureValidator); + + /// @notice Checks whether a signature is valid for the provided hash by forwarding the call to the set [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. + /// @param _hash The hash of the data to be signed. + /// @param _signature The signature byte array associated with `_hash`. + /// @return Returns the `bytes4` magic value `0x1626ba7e` if the signature is valid. + function isValidSignature(bytes32 _hash, bytes memory _signature) external returns (bytes4); + + /// @notice Registers an ERC standard having a callback by registering its [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID and callback function signature. + /// @param _interfaceId The ID of the interface. + /// @param _callbackSelector The selector of the callback function. + /// @param _magicNumber The magic number to be registered for the function signature. + function registerStandardCallback( + bytes4 _interfaceId, + bytes4 _callbackSelector, + bytes4 _magicNumber + ) external; +} From 3e25be2b4f5fad6ecd01f373d20862c2068d57ba Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 5 May 2023 10:19:16 +0200 Subject: [PATCH 053/112] add legacy versions --- .../DAO_v1_0_0.sol | 0 .../src/core/dao/legacy/DAO_v1_1_0-alpha.sol | 386 ++++++++++++++++++ .../IDAO_v1_0_0.sol | 0 .../src/core/dao/legacy/IDAO_v1_1_0_alpha.sol | 138 +++++++ packages/contracts/test/upgrade/dao.ts | 43 +- 5 files changed, 540 insertions(+), 27 deletions(-) rename packages/contracts/src/core/dao/{previous_versions => legacy}/DAO_v1_0_0.sol (100%) create mode 100644 packages/contracts/src/core/dao/legacy/DAO_v1_1_0-alpha.sol rename packages/contracts/src/core/dao/{previous_versions => legacy}/IDAO_v1_0_0.sol (100%) create mode 100644 packages/contracts/src/core/dao/legacy/IDAO_v1_1_0_alpha.sol diff --git a/packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol b/packages/contracts/src/core/dao/legacy/DAO_v1_0_0.sol similarity index 100% rename from packages/contracts/src/core/dao/previous_versions/DAO_v1_0_0.sol rename to packages/contracts/src/core/dao/legacy/DAO_v1_0_0.sol diff --git a/packages/contracts/src/core/dao/legacy/DAO_v1_1_0-alpha.sol b/packages/contracts/src/core/dao/legacy/DAO_v1_1_0-alpha.sol new file mode 100644 index 000000000..1f24a6c61 --- /dev/null +++ b/packages/contracts/src/core/dao/legacy/DAO_v1_1_0-alpha.sol @@ -0,0 +1,386 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.17; + +import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165StorageUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; +import "@openzeppelin/contracts/interfaces/IERC1271.sol"; + +import {PermissionManager} from "../../permission/PermissionManager.sol"; +import {CallbackHandler} from "../../utils/CallbackHandler.sol"; +import {hasBit, flipBit} from "../../utils/BitMap.sol"; +import {IEIP4824} from "../IEIP4824.sol"; +import {IDAO} from "../IDAO.sol"; + +/// @title DAO v1.1.0-alpha (mumbai pre-release) +/// @author Aragon Association - 2021-2023 +/// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. +/// @dev Public API of the Aragon DAO framework. +contract DAO_v1_1_0_alpha is + IEIP4824, + Initializable, + IERC1271, + ERC165StorageUpgradeable, + IDAO, + UUPSUpgradeable, + PermissionManager, + CallbackHandler +{ + using SafeERC20Upgradeable for IERC20Upgradeable; + using AddressUpgradeable for address; + + /// @notice The ID of the permission required to call the `execute` function. + bytes32 public constant EXECUTE_PERMISSION_ID = keccak256("EXECUTE_PERMISSION"); + + /// @notice The ID of the permission required to call the `_authorizeUpgrade` function. + bytes32 public constant UPGRADE_DAO_PERMISSION_ID = keccak256("UPGRADE_DAO_PERMISSION"); + + /// @notice The ID of the permission required to call the `setMetadata` function. + bytes32 public constant SET_METADATA_PERMISSION_ID = keccak256("SET_METADATA_PERMISSION"); + + /// @notice The ID of the permission required to call the `setTrustedForwarder` function. + bytes32 public constant SET_TRUSTED_FORWARDER_PERMISSION_ID = + keccak256("SET_TRUSTED_FORWARDER_PERMISSION"); + + /// @notice The ID of the permission required to call the `setSignatureValidator` function. + bytes32 public constant SET_SIGNATURE_VALIDATOR_PERMISSION_ID = + keccak256("SET_SIGNATURE_VALIDATOR_PERMISSION"); + + /// @notice The ID of the permission required to call the `registerStandardCallback` function. + bytes32 public constant REGISTER_STANDARD_CALLBACK_PERMISSION_ID = + keccak256("REGISTER_STANDARD_CALLBACK_PERMISSION"); + + /// @notice The internal constant storing the maximal action array length. + uint256 internal constant MAX_ACTIONS = 256; + + uint256 private constant _NOT_ENTERED = 1; + uint256 private constant _ENTERED = 2; + + /// @notice The [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. + IERC1271 public signatureValidator; + + /// @notice The address of the trusted forwarder verifying meta transactions. + address private trustedForwarder; + + /// @notice The [EIP-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO URI. + string private _daoURI; + + /// @notice The state variable for the reentrancy guard of the `execute` function. + uint256 private _reentrancyStatus; + + /// @notice Thrown if a call is reentrant. + error ReentrantCall(); + + /// @notice Thrown if the action array length is larger than `MAX_ACTIONS`. + error TooManyActions(); + + /// @notice Thrown if action execution has failed. + /// @param index The index of the action in the action array that failed. + error ActionFailed(uint256 index); + + /// @notice Thrown if an action has insufficent gas left. + error InsufficientGas(); + + /// @notice Thrown if the deposit amount is zero. + error ZeroAmount(); + + /// @notice Thrown if there is a mismatch between the expected and actually deposited amount of native tokens. + /// @param expected The expected native token amount. + /// @param actual The actual native token amount deposited. + error NativeTokenDepositAmountMismatch(uint256 expected, uint256 actual); + + /// @notice Emitted when a new DAO URI is set. + /// @param daoURI The new URI. + event NewURI(string daoURI); + + /// @notice A modifier to protect the `execute()` function against reentrancy. + /// @dev If this is used multiple times, private `_beforeNonReentrant()` and `_afterNonReentrant()` functions should be created to prevent code duplication. + modifier nonReentrant() { + if (_reentrancyStatus == _ENTERED) { + revert ReentrantCall(); + } + _reentrancyStatus = _ENTERED; + + _; + + _reentrancyStatus = _NOT_ENTERED; + } + + /// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized. + constructor() { + _disableInitializers(); + } + + /// @notice Initializes the DAO by + /// - registering the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID + /// - setting the trusted forwarder for meta transactions + /// - giving the `ROOT_PERMISSION_ID` permission to the initial owner (that should be revoked and transferred to the DAO after setup). + /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). + /// @param _metadata IPFS hash that points to all the metadata (logo, description, tags, etc.) of a DAO. + /// @param _initialOwner The initial owner of the DAO having the `ROOT_PERMISSION_ID` permission. + /// @param _trustedForwarder The trusted forwarder responsible for verifying meta transactions. + /// @param daoURI_ The DAO URI required to support [ERC-4824](https://eips.ethereum.org/EIPS/eip-4824). + function initialize( + bytes calldata _metadata, + address _initialOwner, + address _trustedForwarder, + string calldata daoURI_ + ) external initializer { + _reentrancyStatus = _NOT_ENTERED; + + _registerInterface(type(IDAO).interfaceId); + _registerInterface(type(IERC1271).interfaceId); + _registerInterface(type(IEIP4824).interfaceId); + _registerTokenInterfaces(); + + _setMetadata(_metadata); + _setTrustedForwarder(_trustedForwarder); + _setDaoURI(daoURI_); + __PermissionManager_init(_initialOwner); + } + + /// @inheritdoc PermissionManager + function isPermissionRestrictedForAnyAddr( + bytes32 _permissionId + ) internal pure override returns (bool) { + return + _permissionId == EXECUTE_PERMISSION_ID || + _permissionId == UPGRADE_DAO_PERMISSION_ID || + _permissionId == SET_METADATA_PERMISSION_ID || + _permissionId == SET_TRUSTED_FORWARDER_PERMISSION_ID || + _permissionId == SET_SIGNATURE_VALIDATOR_PERMISSION_ID || + _permissionId == REGISTER_STANDARD_CALLBACK_PERMISSION_ID; + } + + /// @notice Internal method authorizing the upgrade of the contract via the [upgradeability mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). + /// @dev The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. + function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {} + + /// @inheritdoc IDAO + function setTrustedForwarder( + address _newTrustedForwarder + ) external override auth(SET_TRUSTED_FORWARDER_PERMISSION_ID) { + _setTrustedForwarder(_newTrustedForwarder); + } + + /// @inheritdoc IDAO + function getTrustedForwarder() external view virtual override returns (address) { + return trustedForwarder; + } + + /// @inheritdoc IDAO + function hasPermission( + address _where, + address _who, + bytes32 _permissionId, + bytes memory _data + ) external view override returns (bool) { + return isGranted(_where, _who, _permissionId, _data); + } + + /// @inheritdoc IDAO + function setMetadata( + bytes calldata _metadata + ) external override auth(SET_METADATA_PERMISSION_ID) { + _setMetadata(_metadata); + } + + /// @inheritdoc IDAO + function execute( + bytes32 _callId, + Action[] calldata _actions, + uint256 _allowFailureMap + ) + external + override + nonReentrant + auth(EXECUTE_PERMISSION_ID) + returns (bytes[] memory execResults, uint256 failureMap) + { + // Check that the action array length is within bounds. + if (_actions.length > MAX_ACTIONS) { + revert TooManyActions(); + } + + execResults = new bytes[](_actions.length); + + uint256 gasBefore; + uint256 gasAfter; + + for (uint256 i = 0; i < _actions.length; ) { + gasBefore = gasleft(); + + (bool success, bytes memory result) = _actions[i].to.call{value: _actions[i].value}( + _actions[i].data + ); + gasAfter = gasleft(); + + // Check if failure is allowed + if (!hasBit(_allowFailureMap, uint8(i))) { + // Check if the call failed. + if (!success) { + revert ActionFailed(i); + } + } else { + // Check if the call failed. + if (!success) { + // Make sure that the action call did not fail because 63/64 of `gasleft()` was insufficient to execute the external call `.to.call` (see [ERC-150](https://eips.ethereum.org/EIPS/eip-150)). + // In specific scenarios, i.e. proposal execution where the last action in the action array is allowed to fail, the account calling `execute` could force-fail this action by setting a gas limit + // where 63/64 is insufficient causing the `.to.call` to fail, but where the remaining 1/64 gas are sufficient to successfully finish the `execute` call. + if (gasAfter < gasBefore / 64) { + revert InsufficientGas(); + } + + // Store that this action failed. + failureMap = flipBit(failureMap, uint8(i)); + } + } + + execResults[i] = result; + + unchecked { + ++i; + } + } + + emit Executed({ + actor: msg.sender, + callId: _callId, + actions: _actions, + allowFailureMap: _allowFailureMap, + failureMap: failureMap, + execResults: execResults + }); + } + + /// @inheritdoc IDAO + function deposit( + address _token, + uint256 _amount, + string calldata _reference + ) external payable override { + if (_amount == 0) revert ZeroAmount(); + + if (_token == address(0)) { + if (msg.value != _amount) + revert NativeTokenDepositAmountMismatch({expected: _amount, actual: msg.value}); + } else { + if (msg.value != 0) + revert NativeTokenDepositAmountMismatch({expected: 0, actual: msg.value}); + + IERC20Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _amount); + } + + emit Deposited(msg.sender, _token, _amount, _reference); + } + + /// @inheritdoc IDAO + function setSignatureValidator( + address _signatureValidator + ) external override auth(SET_SIGNATURE_VALIDATOR_PERMISSION_ID) { + signatureValidator = IERC1271(_signatureValidator); + + emit SignatureValidatorSet({signatureValidator: _signatureValidator}); + } + + /// @inheritdoc IDAO + function isValidSignature( + bytes32 _hash, + bytes memory _signature + ) external view override(IDAO, IERC1271) returns (bytes4) { + if (address(signatureValidator) == address(0)) { + // Return the invalid magic number + return bytes4(0); + } + // Forward the call to the set signature validator contract + return signatureValidator.isValidSignature(_hash, _signature); + } + + /// @notice Emits the `NativeTokenDeposited` event to track native token deposits that weren't made via the deposit method. + /// @dev This call is bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929). + /// Gas cost increases in future hard forks might break this function. As an alternative, [ERC-2930](https://eips.ethereum.org/EIPS/eip-2930)-type transactions using access lists can be employed. + receive() external payable { + emit NativeTokenDeposited(msg.sender, msg.value); + } + + /// @notice Fallback to handle future versions of the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) standard. + /// @param _input An alias being equivalent to `msg.data`. This feature of the fallback function was introduced with the [solidity compiler version 0.7.6](https://github.com/ethereum/solidity/releases/tag/v0.7.6) + /// @return The magic number registered for the function selector triggering the fallback. + fallback(bytes calldata _input) external returns (bytes memory) { + bytes4 magicNumber = _handleCallback(msg.sig, _input); + return abi.encode(magicNumber); + } + + /// @notice Emits the MetadataSet event if new metadata is set. + /// @param _metadata Hash of the IPFS metadata object. + function _setMetadata(bytes calldata _metadata) internal { + emit MetadataSet(_metadata); + } + + /// @notice Sets the trusted forwarder on the DAO and emits the associated event. + /// @param _trustedForwarder The trusted forwarder address. + function _setTrustedForwarder(address _trustedForwarder) internal { + trustedForwarder = _trustedForwarder; + + emit TrustedForwarderSet(_trustedForwarder); + } + + /// @notice Registers the [ERC-721](https://eips.ethereum.org/EIPS/eip-721) and [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) interfaces and callbacks. + function _registerTokenInterfaces() private { + _registerInterface(type(IERC721ReceiverUpgradeable).interfaceId); + _registerInterface(type(IERC1155ReceiverUpgradeable).interfaceId); + + _registerCallback( + IERC721ReceiverUpgradeable.onERC721Received.selector, + IERC721ReceiverUpgradeable.onERC721Received.selector + ); + _registerCallback( + IERC1155ReceiverUpgradeable.onERC1155Received.selector, + IERC1155ReceiverUpgradeable.onERC1155Received.selector + ); + _registerCallback( + IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector, + IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector + ); + } + + /// @inheritdoc IDAO + function registerStandardCallback( + bytes4 _interfaceId, + bytes4 _callbackSelector, + bytes4 _magicNumber + ) external override auth(REGISTER_STANDARD_CALLBACK_PERMISSION_ID) { + _registerInterface(_interfaceId); + _registerCallback(_callbackSelector, _magicNumber); + emit StandardCallbackRegistered(_interfaceId, _callbackSelector, _magicNumber); + } + + /// @inheritdoc IEIP4824 + function daoURI() external view returns (string memory) { + return _daoURI; + } + + /// @notice Updates the set DAO URI to a new value. + /// @param newDaoURI The new DAO URI to be set. + function setDaoURI(string calldata newDaoURI) external auth(SET_METADATA_PERMISSION_ID) { + _setDaoURI(newDaoURI); + } + + /// @notice Sets the new [ERC-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO URI and emits the associated event. + /// @param daoURI_ The new DAO URI. + function _setDaoURI(string calldata daoURI_) internal { + _daoURI = daoURI_; + + emit NewURI(daoURI_); + } + + /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). + uint256[46] private __gap; +} diff --git a/packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol b/packages/contracts/src/core/dao/legacy/IDAO_v1_0_0.sol similarity index 100% rename from packages/contracts/src/core/dao/previous_versions/IDAO_v1_0_0.sol rename to packages/contracts/src/core/dao/legacy/IDAO_v1_0_0.sol diff --git a/packages/contracts/src/core/dao/legacy/IDAO_v1_1_0_alpha.sol b/packages/contracts/src/core/dao/legacy/IDAO_v1_1_0_alpha.sol new file mode 100644 index 000000000..857be2a9f --- /dev/null +++ b/packages/contracts/src/core/dao/legacy/IDAO_v1_1_0_alpha.sol @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity ^0.8.8; + +/// @title IDAO v1.1.0-alpha (mumbai pre-release) +/// @author Aragon Association - 2022-2023 +/// @notice The interface required for DAOs within the Aragon App DAO framework. +interface IDAO_v1_1_0_alpha { + /// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call. + /// @param to The address to call. + /// @param value The native token value to be sent with the call. + /// @param data The bytes-encoded function selector and calldata for the call. + struct Action { + address to; + uint256 value; + bytes data; + } + + /// @notice Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process. + /// @param _where The address of the contract. + /// @param _who The address of a EOA or contract to give the permissions. + /// @param _permissionId The permission identifier. + /// @param _data The optional data passed to the `PermissionCondition` registered. + /// @return Returns true if the address has permission, false if not. + function hasPermission( + address _where, + address _who, + bytes32 _permissionId, + bytes memory _data + ) external view returns (bool); + + /// @notice Updates the DAO metadata (e.g., an IPFS hash). + /// @param _metadata The IPFS hash of the new metadata object. + function setMetadata(bytes calldata _metadata) external; + + /// @notice Emitted when the DAO metadata is updated. + /// @param metadata The IPFS hash of the new metadata object. + event MetadataSet(bytes metadata); + + /// @notice Executes a list of actions. If a zero allow-failure map is provided, a failing action reverts the entire execution. If a non-zero allow-failure map is provided, allowed actions can fail without the entire call being reverted. + /// @param _callId The ID of the call. The definition of the value of `callId` is up to the calling contract and can be used, e.g., as a nonce. + /// @param _actions The array of actions. + /// @param _allowFailureMap A bitmap allowing execution to succeed, even if individual actions might revert. If the bit at index `i` is 1, the execution succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. + /// @return The array of results obtained from the executed actions in `bytes`. + /// @return The resulting failure map containing the actions have actually failed. + function execute( + bytes32 _callId, + Action[] memory _actions, + uint256 _allowFailureMap + ) external returns (bytes[] memory, uint256); + + /// @notice Emitted when a proposal is executed. + /// @param actor The address of the caller. + /// @param callId The ID of the call. + /// @param actions The array of actions executed. + /// @param allowFailureMap The allow failure map encoding which actions are allowed to fail. + /// @param failureMap The failure map encoding which actions have failed. + /// @param execResults The array with the results of the executed actions. + /// @dev The value of `callId` is defined by the component/contract calling the execute function. A `Plugin` implementation can use it, for example, as a nonce. + event Executed( + address indexed actor, + bytes32 callId, + Action[] actions, + uint256 allowFailureMap, + uint256 failureMap, + bytes[] execResults + ); + + /// @notice Emitted when a standard callback is registered. + /// @param interfaceId The ID of the interface. + /// @param callbackSelector The selector of the callback function. + /// @param magicNumber The magic number to be registered for the callback function selector. + event StandardCallbackRegistered( + bytes4 interfaceId, + bytes4 callbackSelector, + bytes4 magicNumber + ); + + /// @notice Deposits (native) tokens to the DAO contract with a reference string. + /// @param _token The address of the token or address(0) in case of the native token. + /// @param _amount The amount of tokens to deposit. + /// @param _reference The reference describing the deposit reason. + function deposit(address _token, uint256 _amount, string calldata _reference) external payable; + + /// @notice Emitted when a token deposit has been made to the DAO. + /// @param sender The address of the sender. + /// @param token The address of the deposited token. + /// @param amount The amount of tokens deposited. + /// @param _reference The reference describing the deposit reason. + event Deposited( + address indexed sender, + address indexed token, + uint256 amount, + string _reference + ); + + /// @notice Emitted when a native token deposit has been made to the DAO. + /// @dev This event is intended to be emitted in the `receive` function and is therefore bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929). + /// @param sender The address of the sender. + /// @param amount The amount of native tokens deposited. + event NativeTokenDeposited(address sender, uint256 amount); + + /// @notice Setter for the trusted forwarder verifying the meta transaction. + /// @param _trustedForwarder The trusted forwarder address. + function setTrustedForwarder(address _trustedForwarder) external; + + /// @notice Getter for the trusted forwarder verifying the meta transaction. + /// @return The trusted forwarder address. + function getTrustedForwarder() external view returns (address); + + /// @notice Emitted when a new TrustedForwarder is set on the DAO. + /// @param forwarder the new forwarder address. + event TrustedForwarderSet(address forwarder); + + /// @notice Setter for the [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. + /// @param _signatureValidator The address of the signature validator. + function setSignatureValidator(address _signatureValidator) external; + + /// @notice Emitted when the signature validator address is updated. + /// @param signatureValidator The address of the signature validator. + event SignatureValidatorSet(address signatureValidator); + + /// @notice Checks whether a signature is valid for the provided hash by forwarding the call to the set [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. + /// @param _hash The hash of the data to be signed. + /// @param _signature The signature byte array associated with `_hash`. + /// @return Returns the `bytes4` magic value `0x1626ba7e` if the signature is valid. + function isValidSignature(bytes32 _hash, bytes memory _signature) external returns (bytes4); + + /// @notice Registers an ERC standard having a callback by registering its [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID and callback function signature. + /// @param _interfaceId The ID of the interface. + /// @param _callbackSelector The selector of the callback function. + /// @param _magicNumber The magic number to be registered for the function signature. + function registerStandardCallback( + bytes4 _interfaceId, + bytes4 _callbackSelector, + bytes4 _magicNumber + ) external; +} diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 62ca7d05b..ddaee4b50 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -2,11 +2,13 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; -import {DAO__factory} from '../../typechain'; import { - v1_0_0_mainnet_goerli_typechain, - v1_0_0_mumbai_typechain, -} from '@aragon/osx-versions'; + DAO__factory, + DAOV100, + DAOV100__factory, + DAOV110Alpha, + DAOV110Alpha__factory, +} from '../../typechain'; import {daoExampleURI} from '../test-utils/dao'; import {deployWithProxy} from '../test-utils/proxy'; @@ -15,8 +17,8 @@ import {findEventTopicLog} from '../../utils/event'; import {readImplementationValueFromSlot} from '../../utils/storage'; let signers: SignerWithAddress[]; -let Dao_mainnet_goerli_V1_0_0: v1_0_0_mainnet_goerli_typechain.DAO__factory; -let Dao_mumbai_V1_0_0: v1_0_0_mumbai_typechain.DAO__factory; +let Dao_v1_0_0: DAOV100__factory; +let Dao_v1_1_0_alpha: DAOV110Alpha__factory; let DaoCurrent: DAO__factory; const DUMMY_METADATA = ethers.utils.hexlify( @@ -26,17 +28,14 @@ const DUMMY_METADATA = ethers.utils.hexlify( describe('DAO Upgrade', function () { before(async function () { signers = await ethers.getSigners(); - Dao_mainnet_goerli_V1_0_0 = - new v1_0_0_mainnet_goerli_typechain.DAO__factory(signers[0]); - Dao_mumbai_V1_0_0 = new v1_0_0_mumbai_typechain.DAO__factory(signers[0]); + Dao_v1_0_0 = new DAOV100__factory(signers[0]); + Dao_v1_1_0_alpha = new DAOV110Alpha__factory(signers[0]); DaoCurrent = new DAO__factory(signers[0]); }); - it('upgrades mainnet/goerli v1.0.0 to v1.1.0', async () => { - const proxy = await deployWithProxy( - Dao_mainnet_goerli_V1_0_0 - ); + it('upgrades v1.0.0 to v1.1.0', async () => { + const proxy = await deployWithProxy(Dao_v1_0_0); await proxy.initialize( DUMMY_METADATA, signers[0].address, @@ -72,11 +71,7 @@ describe('DAO Upgrade', function () { // Check the emitted implementation. const emittedImplementation = ( - await findEventTopicLog( - upgradeTx, - Dao_mainnet_goerli_V1_0_0.interface, - 'Upgraded' - ) + await findEventTopicLog(upgradeTx, Dao_v1_0_0.interface, 'Upgraded') ).args.implementation; expect(emittedImplementation).to.equal(newImplementation.address); @@ -84,10 +79,8 @@ describe('DAO Upgrade', function () { expect(await proxy.callStatic.daoURI()).to.equal(daoExampleURI); }); - it('upgrades mumbai v1.0.0 to v1.1.0', async () => { - const proxy = await deployWithProxy( - Dao_mumbai_V1_0_0 - ); + it('upgrades v1.0.0-alpha (mumbai pre-release) to v1.1.0', async () => { + const proxy = await deployWithProxy(Dao_v1_1_0_alpha); await proxy.initialize( DUMMY_METADATA, signers[0].address, @@ -123,11 +116,7 @@ describe('DAO Upgrade', function () { // Check the emitted implementation. const emittedImplementation = ( - await findEventTopicLog( - upgradeTx, - Dao_mumbai_V1_0_0.interface, - 'Upgraded' - ) + await findEventTopicLog(upgradeTx, Dao_v1_1_0_alpha.interface, 'Upgraded') ).args.implementation; expect(emittedImplementation).to.equal(newImplementation.address); From aaff5bda43097de5ca40fc54a4552f32ae18ff91 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 5 May 2023 11:10:12 +0200 Subject: [PATCH 054/112] fix: renaming of the versions --- .../{DAO_v1_1_0-alpha.sol => DAO_v1_3_0-alpha.sol} | 4 ++-- ...IDAO_v1_1_0_alpha.sol => IDAO_v1_3_0_alpha.sol} | 4 ++-- packages/contracts/test/upgrade/dao.ts | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) rename packages/contracts/src/core/dao/legacy/{DAO_v1_1_0-alpha.sol => DAO_v1_3_0-alpha.sol} (99%) rename packages/contracts/src/core/dao/legacy/{IDAO_v1_1_0_alpha.sol => IDAO_v1_3_0_alpha.sol} (98%) diff --git a/packages/contracts/src/core/dao/legacy/DAO_v1_1_0-alpha.sol b/packages/contracts/src/core/dao/legacy/DAO_v1_3_0-alpha.sol similarity index 99% rename from packages/contracts/src/core/dao/legacy/DAO_v1_1_0-alpha.sol rename to packages/contracts/src/core/dao/legacy/DAO_v1_3_0-alpha.sol index 1f24a6c61..9826660c9 100644 --- a/packages/contracts/src/core/dao/legacy/DAO_v1_1_0-alpha.sol +++ b/packages/contracts/src/core/dao/legacy/DAO_v1_3_0-alpha.sol @@ -19,11 +19,11 @@ import {hasBit, flipBit} from "../../utils/BitMap.sol"; import {IEIP4824} from "../IEIP4824.sol"; import {IDAO} from "../IDAO.sol"; -/// @title DAO v1.1.0-alpha (mumbai pre-release) +/// @title DAO v1.3.0-alpha (mumbai pre-release) /// @author Aragon Association - 2021-2023 /// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. /// @dev Public API of the Aragon DAO framework. -contract DAO_v1_1_0_alpha is +contract DAO_v1_3_0_alpha is IEIP4824, Initializable, IERC1271, diff --git a/packages/contracts/src/core/dao/legacy/IDAO_v1_1_0_alpha.sol b/packages/contracts/src/core/dao/legacy/IDAO_v1_3_0_alpha.sol similarity index 98% rename from packages/contracts/src/core/dao/legacy/IDAO_v1_1_0_alpha.sol rename to packages/contracts/src/core/dao/legacy/IDAO_v1_3_0_alpha.sol index 857be2a9f..6a9cec9cc 100644 --- a/packages/contracts/src/core/dao/legacy/IDAO_v1_1_0_alpha.sol +++ b/packages/contracts/src/core/dao/legacy/IDAO_v1_3_0_alpha.sol @@ -2,10 +2,10 @@ pragma solidity ^0.8.8; -/// @title IDAO v1.1.0-alpha (mumbai pre-release) +/// @title IDAO v1.3.0-alpha (mumbai pre-release) /// @author Aragon Association - 2022-2023 /// @notice The interface required for DAOs within the Aragon App DAO framework. -interface IDAO_v1_1_0_alpha { +interface IDAO_v1_3_0_alpha { /// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call. /// @param to The address to call. /// @param value The native token value to be sent with the call. diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index ddaee4b50..788c9e500 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -6,8 +6,8 @@ import { DAO__factory, DAOV100, DAOV100__factory, - DAOV110Alpha, - DAOV110Alpha__factory, + DAOV130Alpha, + DAOV130Alpha__factory, } from '../../typechain'; import {daoExampleURI} from '../test-utils/dao'; @@ -18,7 +18,7 @@ import {readImplementationValueFromSlot} from '../../utils/storage'; let signers: SignerWithAddress[]; let Dao_v1_0_0: DAOV100__factory; -let Dao_v1_1_0_alpha: DAOV110Alpha__factory; +let Dao_v1_3_0_alpha: DAOV130Alpha__factory; let DaoCurrent: DAO__factory; const DUMMY_METADATA = ethers.utils.hexlify( @@ -29,12 +29,12 @@ describe('DAO Upgrade', function () { before(async function () { signers = await ethers.getSigners(); Dao_v1_0_0 = new DAOV100__factory(signers[0]); - Dao_v1_1_0_alpha = new DAOV110Alpha__factory(signers[0]); + Dao_v1_3_0_alpha = new DAOV130Alpha__factory(signers[0]); DaoCurrent = new DAO__factory(signers[0]); }); - it('upgrades v1.0.0 to v1.1.0', async () => { + it('upgrades v1.0.0 to v1.3.0', async () => { const proxy = await deployWithProxy(Dao_v1_0_0); await proxy.initialize( DUMMY_METADATA, @@ -80,7 +80,7 @@ describe('DAO Upgrade', function () { }); it('upgrades v1.0.0-alpha (mumbai pre-release) to v1.1.0', async () => { - const proxy = await deployWithProxy(Dao_v1_1_0_alpha); + const proxy = await deployWithProxy(Dao_v1_3_0_alpha); await proxy.initialize( DUMMY_METADATA, signers[0].address, @@ -116,7 +116,7 @@ describe('DAO Upgrade', function () { // Check the emitted implementation. const emittedImplementation = ( - await findEventTopicLog(upgradeTx, Dao_v1_1_0_alpha.interface, 'Upgraded') + await findEventTopicLog(upgradeTx, Dao_v1_3_0_alpha.interface, 'Upgraded') ).args.implementation; expect(emittedImplementation).to.equal(newImplementation.address); From 1ce07f3f04b9b92ff575f31ec7fc3e117ccb66d8 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 5 May 2023 12:04:55 +0200 Subject: [PATCH 055/112] chore: remove old CI task --- .github/workflows/contract-tests.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/contract-tests.yml b/.github/workflows/contract-tests.yml index 5ad68b3e8..b9d563b63 100644 --- a/.github/workflows/contract-tests.yml +++ b/.github/workflows/contract-tests.yml @@ -34,8 +34,6 @@ jobs: run: rm -rf artifact cache deployments typechain - name: Check formatting run: yarn run formatting:check - - name: Create symlink to contracts-versions - run: ln -s ../contracts-versions ../../node_modules/@aragon/osx-versions - name: Compile contracts run: yarn run build && yarn run build:npm - name: Run Hardhat Tests From 96d35af395af0240495cee93c7e43701d0ae3fdb Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 5 May 2023 13:04:48 +0200 Subject: [PATCH 056/112] chore: maintained changelog --- packages/contracts/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/contracts/CHANGELOG.md b/packages/contracts/CHANGELOG.md index 8f9462262..fa83fadee 100644 --- a/packages/contracts/CHANGELOG.md +++ b/packages/contracts/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Fixed ordering bug in the `createProposal` function used by the `TokenVoting` and `AddresslistVoting` implementations resulting emitting the unvalidated `_startDate` and `_endDate` input arguments (that both can be zero) in the `ProposalCreated` event instead of the validated ones. - Changed the solidity compiler pragma from `0.8.17` to `^0.8.8` for files that external developers inherit from. ### Removed From 857a9db418f05c7ce43550d9c49a9a8b199d499b Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 5 May 2023 13:26:46 +0200 Subject: [PATCH 057/112] fix: version numbers --- .../legacy/{DAO_v1_0_0.sol => DAO_v1_0_1.sol} | 8 ++++---- .../legacy/{IDAO_v1_0_0.sol => IDAO_v1_0_1.sol} | 4 ++-- packages/contracts/test/upgrade/dao.ts | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) rename packages/contracts/src/core/dao/legacy/{DAO_v1_0_0.sol => DAO_v1_0_1.sol} (99%) rename packages/contracts/src/core/dao/legacy/{IDAO_v1_0_0.sol => IDAO_v1_0_1.sol} (99%) diff --git a/packages/contracts/src/core/dao/legacy/DAO_v1_0_0.sol b/packages/contracts/src/core/dao/legacy/DAO_v1_0_1.sol similarity index 99% rename from packages/contracts/src/core/dao/legacy/DAO_v1_0_0.sol rename to packages/contracts/src/core/dao/legacy/DAO_v1_0_1.sol index 77c55af71..cfa7ef93a 100644 --- a/packages/contracts/src/core/dao/legacy/DAO_v1_0_0.sol +++ b/packages/contracts/src/core/dao/legacy/DAO_v1_0_1.sol @@ -17,18 +17,18 @@ import {PermissionManager} from "../../permission/PermissionManager.sol"; import {CallbackHandler} from "../../utils/CallbackHandler.sol"; import {hasBit, flipBit} from "../../utils/BitMap.sol"; import {IEIP4824} from "../IEIP4824.sol"; -import {IDAO_v1_0_0} from "./IDAO_v1_0_0.sol"; +import {IDAO_v1_0_1} from "./IDAO_v1_0_1.sol"; -/// @title DAO v1.0.0 +/// @title DAO v1.0.1 /// @author Aragon Association - 2021-2023 /// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. /// @dev Public API of the Aragon DAO framework. -contract DAO_v1_0_0 is +contract DAO_v1_0_1 is IEIP4824, Initializable, IERC1271, ERC165StorageUpgradeable, - IDAO_v1_0_0, + IDAO_v1_0_1, UUPSUpgradeable, PermissionManager, CallbackHandler diff --git a/packages/contracts/src/core/dao/legacy/IDAO_v1_0_0.sol b/packages/contracts/src/core/dao/legacy/IDAO_v1_0_1.sol similarity index 99% rename from packages/contracts/src/core/dao/legacy/IDAO_v1_0_0.sol rename to packages/contracts/src/core/dao/legacy/IDAO_v1_0_1.sol index f7318726b..7c135603e 100644 --- a/packages/contracts/src/core/dao/legacy/IDAO_v1_0_0.sol +++ b/packages/contracts/src/core/dao/legacy/IDAO_v1_0_1.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.17; -/// @title IDAO v1.0.0 +/// @title IDAO v1.0.1 /// @author Aragon Association - 2022-2023 /// @notice The interface required for DAOs within the Aragon App DAO framework. -interface IDAO_v1_0_0 { +interface IDAO_v1_0_1 { /// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call. /// @param to The address to call. /// @param value The native token value to be sent with the call. diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 788c9e500..5ca652852 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -4,8 +4,8 @@ import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import { DAO__factory, - DAOV100, - DAOV100__factory, + DAOV101, + DAOV101__factory, DAOV130Alpha, DAOV130Alpha__factory, } from '../../typechain'; @@ -17,7 +17,7 @@ import {findEventTopicLog} from '../../utils/event'; import {readImplementationValueFromSlot} from '../../utils/storage'; let signers: SignerWithAddress[]; -let Dao_v1_0_0: DAOV100__factory; +let Dao_v1_0_1: DAOV101__factory; let Dao_v1_3_0_alpha: DAOV130Alpha__factory; let DaoCurrent: DAO__factory; @@ -28,14 +28,14 @@ const DUMMY_METADATA = ethers.utils.hexlify( describe('DAO Upgrade', function () { before(async function () { signers = await ethers.getSigners(); - Dao_v1_0_0 = new DAOV100__factory(signers[0]); + Dao_v1_0_1 = new DAOV101__factory(signers[0]); Dao_v1_3_0_alpha = new DAOV130Alpha__factory(signers[0]); DaoCurrent = new DAO__factory(signers[0]); }); - it('upgrades v1.0.0 to v1.3.0', async () => { - const proxy = await deployWithProxy(Dao_v1_0_0); + it('upgrades v1.0.1 to v1.3.0', async () => { + const proxy = await deployWithProxy(Dao_v1_0_1); await proxy.initialize( DUMMY_METADATA, signers[0].address, @@ -71,7 +71,7 @@ describe('DAO Upgrade', function () { // Check the emitted implementation. const emittedImplementation = ( - await findEventTopicLog(upgradeTx, Dao_v1_0_0.interface, 'Upgraded') + await findEventTopicLog(upgradeTx, Dao_v1_0_1.interface, 'Upgraded') ).args.implementation; expect(emittedImplementation).to.equal(newImplementation.address); @@ -79,7 +79,7 @@ describe('DAO Upgrade', function () { expect(await proxy.callStatic.daoURI()).to.equal(daoExampleURI); }); - it('upgrades v1.0.0-alpha (mumbai pre-release) to v1.1.0', async () => { + it('upgrades v1.3.0-alpha (mumbai pre-release) to v1.3.0', async () => { const proxy = await deployWithProxy(Dao_v1_3_0_alpha); await proxy.initialize( DUMMY_METADATA, From 9d129f43c4175f27509985ac27fb0e21984cc84e Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 5 May 2023 13:32:19 +0200 Subject: [PATCH 058/112] fix: imports --- .../src/core/dao/legacy/DAO_v1_0_1.sol | 22 ++++++++-------- .../src/core/dao/legacy/DAO_v1_3_0-alpha.sol | 26 +++++++++---------- packages/contracts/test/upgrade/dao.ts | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/packages/contracts/src/core/dao/legacy/DAO_v1_0_1.sol b/packages/contracts/src/core/dao/legacy/DAO_v1_0_1.sol index cfa7ef93a..fcdfc7dde 100644 --- a/packages/contracts/src/core/dao/legacy/DAO_v1_0_1.sol +++ b/packages/contracts/src/core/dao/legacy/DAO_v1_0_1.sol @@ -107,7 +107,7 @@ contract DAO_v1_0_1 is address _trustedForwarder, string calldata daoURI_ ) external initializer { - _registerInterface(type(IDAO_v1_0_0).interfaceId); + _registerInterface(type(IDAO_v1_0_1).interfaceId); _registerInterface(type(IERC1271).interfaceId); _registerInterface(type(IEIP4824).interfaceId); _registerTokenInterfaces(); @@ -135,19 +135,19 @@ contract DAO_v1_0_1 is /// @dev The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {} - /// @inheritdoc IDAO_v1_0_0 + /// @inheritdoc IDAO_v1_0_1 function setTrustedForwarder( address _newTrustedForwarder ) external override auth(SET_TRUSTED_FORWARDER_PERMISSION_ID) { _setTrustedForwarder(_newTrustedForwarder); } - /// @inheritdoc IDAO_v1_0_0 + /// @inheritdoc IDAO_v1_0_1 function getTrustedForwarder() external view virtual override returns (address) { return trustedForwarder; } - /// @inheritdoc IDAO_v1_0_0 + /// @inheritdoc IDAO_v1_0_1 function hasPermission( address _where, address _who, @@ -157,14 +157,14 @@ contract DAO_v1_0_1 is return isGranted(_where, _who, _permissionId, _data); } - /// @inheritdoc IDAO_v1_0_0 + /// @inheritdoc IDAO_v1_0_1 function setMetadata( bytes calldata _metadata ) external override auth(SET_METADATA_PERMISSION_ID) { _setMetadata(_metadata); } - /// @inheritdoc IDAO_v1_0_0 + /// @inheritdoc IDAO_v1_0_1 function execute( bytes32 _callId, Action[] calldata _actions, @@ -214,7 +214,7 @@ contract DAO_v1_0_1 is }); } - /// @inheritdoc IDAO_v1_0_0 + /// @inheritdoc IDAO_v1_0_1 function deposit( address _token, uint256 _amount, @@ -235,7 +235,7 @@ contract DAO_v1_0_1 is emit Deposited(msg.sender, _token, _amount, _reference); } - /// @inheritdoc IDAO_v1_0_0 + /// @inheritdoc IDAO_v1_0_1 function setSignatureValidator( address _signatureValidator ) external override auth(SET_SIGNATURE_VALIDATOR_PERMISSION_ID) { @@ -244,11 +244,11 @@ contract DAO_v1_0_1 is emit SignatureValidatorSet({signatureValidator: _signatureValidator}); } - /// @inheritdoc IDAO_v1_0_0 + /// @inheritdoc IDAO_v1_0_1 function isValidSignature( bytes32 _hash, bytes memory _signature - ) external view override(IDAO_v1_0_0, IERC1271) returns (bytes4) { + ) external view override(IDAO_v1_0_1, IERC1271) returns (bytes4) { if (address(signatureValidator) == address(0)) { // Return the invalid magic number return bytes4(0); @@ -305,7 +305,7 @@ contract DAO_v1_0_1 is ); } - /// @inheritdoc IDAO_v1_0_0 + /// @inheritdoc IDAO_v1_0_1 function registerStandardCallback( bytes4 _interfaceId, bytes4 _callbackSelector, diff --git a/packages/contracts/src/core/dao/legacy/DAO_v1_3_0-alpha.sol b/packages/contracts/src/core/dao/legacy/DAO_v1_3_0-alpha.sol index 9826660c9..ce174bb1f 100644 --- a/packages/contracts/src/core/dao/legacy/DAO_v1_3_0-alpha.sol +++ b/packages/contracts/src/core/dao/legacy/DAO_v1_3_0-alpha.sol @@ -17,7 +17,7 @@ import {PermissionManager} from "../../permission/PermissionManager.sol"; import {CallbackHandler} from "../../utils/CallbackHandler.sol"; import {hasBit, flipBit} from "../../utils/BitMap.sol"; import {IEIP4824} from "../IEIP4824.sol"; -import {IDAO} from "../IDAO.sol"; +import {IDAO_v1_3_0_alpha} from "./IDAO_v1_3_0_alpha.sol"; /// @title DAO v1.3.0-alpha (mumbai pre-release) /// @author Aragon Association - 2021-2023 @@ -28,7 +28,7 @@ contract DAO_v1_3_0_alpha is Initializable, IERC1271, ERC165StorageUpgradeable, - IDAO, + IDAO_v1_3_0_alpha, UUPSUpgradeable, PermissionManager, CallbackHandler @@ -135,7 +135,7 @@ contract DAO_v1_3_0_alpha is ) external initializer { _reentrancyStatus = _NOT_ENTERED; - _registerInterface(type(IDAO).interfaceId); + _registerInterface(type(IDAO_v1_3_0_alpha).interfaceId); _registerInterface(type(IERC1271).interfaceId); _registerInterface(type(IEIP4824).interfaceId); _registerTokenInterfaces(); @@ -163,19 +163,19 @@ contract DAO_v1_3_0_alpha is /// @dev The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {} - /// @inheritdoc IDAO + /// @inheritdoc IDAO_v1_3_0_alpha function setTrustedForwarder( address _newTrustedForwarder ) external override auth(SET_TRUSTED_FORWARDER_PERMISSION_ID) { _setTrustedForwarder(_newTrustedForwarder); } - /// @inheritdoc IDAO + /// @inheritdoc IDAO_v1_3_0_alpha function getTrustedForwarder() external view virtual override returns (address) { return trustedForwarder; } - /// @inheritdoc IDAO + /// @inheritdoc IDAO_v1_3_0_alpha function hasPermission( address _where, address _who, @@ -185,14 +185,14 @@ contract DAO_v1_3_0_alpha is return isGranted(_where, _who, _permissionId, _data); } - /// @inheritdoc IDAO + /// @inheritdoc IDAO_v1_3_0_alpha function setMetadata( bytes calldata _metadata ) external override auth(SET_METADATA_PERMISSION_ID) { _setMetadata(_metadata); } - /// @inheritdoc IDAO + /// @inheritdoc IDAO_v1_3_0_alpha function execute( bytes32 _callId, Action[] calldata _actions, @@ -260,7 +260,7 @@ contract DAO_v1_3_0_alpha is }); } - /// @inheritdoc IDAO + /// @inheritdoc IDAO_v1_3_0_alpha function deposit( address _token, uint256 _amount, @@ -281,7 +281,7 @@ contract DAO_v1_3_0_alpha is emit Deposited(msg.sender, _token, _amount, _reference); } - /// @inheritdoc IDAO + /// @inheritdoc IDAO_v1_3_0_alpha function setSignatureValidator( address _signatureValidator ) external override auth(SET_SIGNATURE_VALIDATOR_PERMISSION_ID) { @@ -290,11 +290,11 @@ contract DAO_v1_3_0_alpha is emit SignatureValidatorSet({signatureValidator: _signatureValidator}); } - /// @inheritdoc IDAO + /// @inheritdoc IDAO_v1_3_0_alpha function isValidSignature( bytes32 _hash, bytes memory _signature - ) external view override(IDAO, IERC1271) returns (bytes4) { + ) external view override(IDAO_v1_3_0_alpha, IERC1271) returns (bytes4) { if (address(signatureValidator) == address(0)) { // Return the invalid magic number return bytes4(0); @@ -351,7 +351,7 @@ contract DAO_v1_3_0_alpha is ); } - /// @inheritdoc IDAO + /// @inheritdoc IDAO_v1_3_0_alpha function registerStandardCallback( bytes4 _interfaceId, bytes4 _callbackSelector, diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 5ca652852..7077b4fc5 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -31,7 +31,7 @@ describe('DAO Upgrade', function () { Dao_v1_0_1 = new DAOV101__factory(signers[0]); Dao_v1_3_0_alpha = new DAOV130Alpha__factory(signers[0]); - DaoCurrent = new DAO__factory(signers[0]); + DaoCurrent = new DAO__factory(signers[0]); // 1.3.0 }); it('upgrades v1.0.1 to v1.3.0', async () => { From b9d3dc3fe25068e38a12242752d17a00f3a8c8ee Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 5 May 2023 15:36:18 +0200 Subject: [PATCH 059/112] WIP --- .../update/to_v1.3.0/10_TokenVoting_Plugin.ts | 86 ++++++ .../11_TokenVoting_Plugin_conclude.ts | 11 + .../addresslist/build-metadata.json | 4 +- .../addresslist/build1/AddresslistVoting.sol | 228 ++++++++++++++ .../build1/AddresslistVotingSetup.sol | 132 ++++++++ .../addresslist/build1/build-metadata.json | 12 + .../majority-voting/token/build-metadata.json | 4 +- .../token/build1/TokenVoting.sol | 225 ++++++++++++++ .../token/build1/TokenVotingSetup.sol | 282 ++++++++++++++++++ .../token/build1/build-metadata.json | 13 + 10 files changed, 993 insertions(+), 4 deletions(-) create mode 100644 packages/contracts/deploy/update/to_v1.3.0/10_TokenVoting_Plugin.ts create mode 100644 packages/contracts/deploy/update/to_v1.3.0/11_TokenVoting_Plugin_conclude.ts create mode 100644 packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVoting.sol create mode 100644 packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVotingSetup.sol create mode 100644 packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/build-metadata.json create mode 100644 packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVoting.sol create mode 100644 packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVotingSetup.sol create mode 100644 packages/contracts/src/plugins/governance/majority-voting/token/build1/build-metadata.json diff --git a/packages/contracts/deploy/update/to_v1.3.0/10_TokenVoting_Plugin.ts b/packages/contracts/deploy/update/to_v1.3.0/10_TokenVoting_Plugin.ts new file mode 100644 index 000000000..9cef80f9f --- /dev/null +++ b/packages/contracts/deploy/update/to_v1.3.0/10_TokenVoting_Plugin.ts @@ -0,0 +1,86 @@ +import {DeployFunction} from 'hardhat-deploy/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {PluginRepo__factory} from '../../../typechain'; +import {getContractAddress, uploadToIPFS} from '../../helpers'; + +import tokenVotingReleaseMetadata from '../../../src/plugins/governance/majority-voting/token/release-metadata.json'; +import tokenVotingBuildMetadata from '../../../src/plugins/governance/majority-voting/token/build-metadata.json'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + console.log('\nUpdate TokenVoting Plugin'); + const {deployments, ethers, network} = hre; + const {deploy} = deployments; + const [deployer] = await ethers.getSigners(); + + const deployResult = await deploy('TokenVotingSetup', { + from: deployer.address, + args: [], + log: true, + }); + + const tokenVotingReleaseCIDPath = await uploadToIPFS( + JSON.stringify(tokenVotingReleaseMetadata), + network.name + ); + const tokenVotingBuildCIDPath = await uploadToIPFS( + JSON.stringify(tokenVotingBuildMetadata), + network.name + ); + + const tokenVotingRepoAddress = await getContractAddress( + 'token-voting-repo', + hre + ); + const tokenVotingRepo = PluginRepo__factory.connect( + tokenVotingRepoAddress, + ethers.provider + ); + if ( + await tokenVotingRepo.callStatic.isGranted( + tokenVotingRepoAddress, + deployer.address, + await tokenVotingRepo.MAINTAINER_PERMISSION_ID(), + '0x00' + ) + ) { + console.log(`Deployer has permission to install new TokenVoting version`); + const tx = await tokenVotingRepo + .connect(deployer) + .createVersion( + 1, + deployResult.address, + ethers.utils.toUtf8Bytes(`ipfs://${tokenVotingBuildCIDPath}`), + ethers.utils.toUtf8Bytes(`ipfs://${tokenVotingReleaseCIDPath}`) + ); + console.log(`Creating new TokenVoting build version with ${tx.hash}`); + await tx.wait(); + return; + } + + const tx = await tokenVotingRepo + .connect(deployer) + .populateTransaction.createVersion( + 1, + deployResult.address, + ethers.utils.toUtf8Bytes(`ipfs://${tokenVotingBuildCIDPath}`), + ethers.utils.toUtf8Bytes(`ipfs://${tokenVotingReleaseCIDPath}`) + ); + + if (!tx.to || !tx.data) { + throw new Error( + `Failed to populate TokenVoting Repo createVersion transaction` + ); + } + + console.log( + `Deployer has no permission to create a new version. Adding managingDAO action` + ); + hre.managingDAOActions.push({ + to: tx.to, + data: tx.data, + value: 0, + description: `Creates a new build for release 1 in the TokenVotingRepo (${tokenVotingRepoAddress}) with TokenVotingSetup (${deployResult.address})`, + }); +}; +export default func; +func.tags = ['TokenVotingPlugin']; diff --git a/packages/contracts/deploy/update/to_v1.3.0/11_TokenVoting_Plugin_conclude.ts b/packages/contracts/deploy/update/to_v1.3.0/11_TokenVoting_Plugin_conclude.ts new file mode 100644 index 000000000..eeae40165 --- /dev/null +++ b/packages/contracts/deploy/update/to_v1.3.0/11_TokenVoting_Plugin_conclude.ts @@ -0,0 +1,11 @@ +import {DeployFunction} from 'hardhat-deploy/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + console.log('\nConcluding TokenVoting Plugin Update'); + + hre.aragonToVerifyContracts.push( + await hre.deployments.get('TokenVotingSetup') + ); +}; +export default func; +func.tags = ['TokenVotingPlugin', 'Verify']; diff --git a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build-metadata.json b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build-metadata.json index e746b71aa..683173e55 100644 --- a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build-metadata.json +++ b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build-metadata.json @@ -6,7 +6,7 @@ "tuple(uint8 votingMode, uint64 supportThreshold, uint64 minParticipation, uint64 minDuration, uint256 minProposerVotingPower) votingSettings", "address[] members" ], - "prepareUpdate": [""], - "prepareUninstallation": [""] + "prepareUpdate": [], + "prepareUninstallation": [] } } diff --git a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVoting.sol b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVoting.sol new file mode 100644 index 000000000..aa9d3a13d --- /dev/null +++ b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVoting.sol @@ -0,0 +1,228 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.17; + +import {SafeCastUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; + +import {IDAO} from "../../../../../core/dao/IDAO.sol"; +import {RATIO_BASE, _applyRatioCeiled} from "../../../../utils/Ratio.sol"; + +import {IMembership} from "../../../../../core/plugin/membership/IMembership.sol"; +import {Addresslist} from "../../../../utils/Addresslist.sol"; +import {IMajorityVoting} from "../../IMajorityVoting.sol"; +import {MajorityVotingBase} from "../../MajorityVotingBase.sol"; + +/// @title AddresslistVoting v1.0.0 +/// @author Aragon Association - 2021-2023. +/// @notice The majority voting implementation using a list of member addresses. +/// @dev This contract inherits from `MajorityVotingBase` and implements the `IMajorityVoting` interface. +contract AddresslistVoting_v1_0_0 is IMembership, Addresslist, MajorityVotingBase { + using SafeCastUpgradeable for uint256; + + /// @notice The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract. + bytes4 internal constant ADDRESSLIST_VOTING_INTERFACE_ID = + this.initialize.selector ^ this.addAddresses.selector ^ this.removeAddresses.selector; + + /// @notice The ID of the permission required to call the `addAddresses` and `removeAddresses` functions. + bytes32 public constant UPDATE_ADDRESSES_PERMISSION_ID = + keccak256("UPDATE_ADDRESSES_PERMISSION"); + + /// @notice Initializes the component. + /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). + /// @param _dao The IDAO interface of the associated DAO. + /// @param _votingSettings The voting settings. + function initialize( + IDAO _dao, + VotingSettings calldata _votingSettings, + address[] calldata _members + ) external initializer { + __MajorityVotingBase_init(_dao, _votingSettings); + + _addAddresses(_members); + emit MembersAdded({members: _members}); + } + + /// @notice Checks if this or the parent contract supports an interface by its ID. + /// @param _interfaceId The ID of the interface. + /// @return Returns `true` if the interface is supported. + function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { + return + _interfaceId == ADDRESSLIST_VOTING_INTERFACE_ID || + _interfaceId == type(Addresslist).interfaceId || + _interfaceId == type(IMembership).interfaceId || + super.supportsInterface(_interfaceId); + } + + /// @notice Adds new members to the address list. + /// @param _members The addresses of members to be added. + /// @dev This function is used during the plugin initialization. + function addAddresses( + address[] calldata _members + ) external auth(UPDATE_ADDRESSES_PERMISSION_ID) { + _addAddresses(_members); + + emit MembersAdded({members: _members}); + } + + /// @notice Removes existing members from the address list. + /// @param _members The addresses of the members to be removed. + function removeAddresses( + address[] calldata _members + ) external auth(UPDATE_ADDRESSES_PERMISSION_ID) { + _removeAddresses(_members); + + emit MembersRemoved({members: _members}); + } + + /// @inheritdoc MajorityVotingBase + function totalVotingPower(uint256 _blockNumber) public view override returns (uint256) { + return addresslistLengthAtBlock(_blockNumber); + } + + /// @inheritdoc MajorityVotingBase + function createProposal( + bytes calldata _metadata, + IDAO.Action[] calldata _actions, + uint256 _allowFailureMap, + uint64 _startDate, + uint64 _endDate, + VoteOption _voteOption, + bool _tryEarlyExecution + ) external override returns (uint256 proposalId) { + uint64 snapshotBlock; + unchecked { + snapshotBlock = block.number.toUint64() - 1; + } + + if (minProposerVotingPower() != 0 && !isListedAtBlock(_msgSender(), snapshotBlock)) { + revert ProposalCreationForbidden(_msgSender()); + } + + (_startDate, _endDate) = _validateProposalDates(_startDate, _endDate); + + proposalId = _createProposal({ + _creator: _msgSender(), + _metadata: _metadata, + _startDate: _startDate, + _endDate: _endDate, + _actions: _actions, + _allowFailureMap: _allowFailureMap + }); + + // Store proposal related information + Proposal storage proposal_ = proposals[proposalId]; + + proposal_.parameters.startDate = _startDate; + proposal_.parameters.endDate = _endDate; + proposal_.parameters.snapshotBlock = snapshotBlock; + proposal_.parameters.votingMode = votingMode(); + proposal_.parameters.supportThreshold = supportThreshold(); + proposal_.parameters.minVotingPower = _applyRatioCeiled( + totalVotingPower(snapshotBlock), + minParticipation() + ); + + // Reduce costs + if (_allowFailureMap != 0) { + proposal_.allowFailureMap = _allowFailureMap; + } + + for (uint256 i; i < _actions.length; ) { + proposal_.actions.push(_actions[i]); + unchecked { + ++i; + } + } + + if (_voteOption != VoteOption.None) { + vote(proposalId, _voteOption, _tryEarlyExecution); + } + } + + /// @inheritdoc IMembership + function isMember(address _account) external view returns (bool) { + return isListed(_account); + } + + /// @inheritdoc MajorityVotingBase + function _vote( + uint256 _proposalId, + VoteOption _voteOption, + address _voter, + bool _tryEarlyExecution + ) internal override { + Proposal storage proposal_ = proposals[_proposalId]; + + VoteOption state = proposal_.voters[_voter]; + + // Remove the previous vote. + if (state == VoteOption.Yes) { + proposal_.tally.yes = proposal_.tally.yes - 1; + } else if (state == VoteOption.No) { + proposal_.tally.no = proposal_.tally.no - 1; + } else if (state == VoteOption.Abstain) { + proposal_.tally.abstain = proposal_.tally.abstain - 1; + } + + // Store the updated/new vote for the voter. + if (_voteOption == VoteOption.Yes) { + proposal_.tally.yes = proposal_.tally.yes + 1; + } else if (_voteOption == VoteOption.No) { + proposal_.tally.no = proposal_.tally.no + 1; + } else if (_voteOption == VoteOption.Abstain) { + proposal_.tally.abstain = proposal_.tally.abstain + 1; + } + + proposal_.voters[_voter] = _voteOption; + + emit VoteCast({ + proposalId: _proposalId, + voter: _voter, + voteOption: _voteOption, + votingPower: 1 + }); + + if (_tryEarlyExecution && _canExecute(_proposalId)) { + _execute(_proposalId); + } + } + + /// @inheritdoc MajorityVotingBase + function _canVote( + uint256 _proposalId, + address _account, + VoteOption _voteOption + ) internal view override returns (bool) { + Proposal storage proposal_ = proposals[_proposalId]; + + // The proposal vote hasn't started or has already ended. + if (!_isProposalOpen(proposal_)) { + return false; + } + + // The voter votes `None` which is not allowed. + if (_voteOption == VoteOption.None) { + return false; + } + + // The voter has no voting power. + if (!isListedAtBlock(_account, proposal_.parameters.snapshotBlock)) { + return false; + } + + // The voter has already voted but vote replacement is not allowed. + if ( + proposal_.voters[_account] != VoteOption.None && + proposal_.parameters.votingMode != VotingMode.VoteReplacement + ) { + return false; + } + + return true; + } + + /// @dev This empty reserved space is put in place to allow future versions to add new + /// variables without shifting down storage in the inheritance chain. + /// https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps + uint256[50] private __gap; +} diff --git a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVotingSetup.sol b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVotingSetup.sol new file mode 100644 index 000000000..fbc447b3d --- /dev/null +++ b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVotingSetup.sol @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.17; + +import {IDAO_v1_0_0} from "../../../../../core/dao/legacy/IDAO_v1_0_0.sol"; +import {DAO_v1_0_0} from "../../../../../core/dao/legacy/DAO_v1_0_0.sol"; +import {PermissionLib} from "../../../../../core/permission/PermissionLib.sol"; +import {PluginSetup, IPluginSetup} from "../../../../../framework/plugin/setup/PluginSetup.sol"; +import {MajorityVotingBase} from "../../MajorityVotingBase.sol"; +import {AddresslistVoting} from "./AddresslistVoting.sol"; + +/// @title AddresslistVotingSetup Release 1, Build 1 +/// @author Aragon Association - 2022-2023 +/// @notice The setup contract of the `AddresslistVoting` plugin. +contract AddresslistVotingSetup_R1B1 is PluginSetup { + /// @notice The address of `AddresslistVoting` plugin logic contract to be used in creating proxy contracts. + AddresslistVoting private immutable addresslistVotingBase; + + /// @notice The contract constructor, that deploys the `AddresslistVoting` plugin logic contract. + constructor() { + addresslistVotingBase = new AddresslistVoting(); + } + + /// @inheritdoc IPluginSetup + function prepareInstallation( + address _dao, + bytes calldata _data + ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { + // Decode `_data` to extract the params needed for deploying and initializing `AddresslistVoting` plugin. + (MajorityVotingBase.VotingSettings memory votingSettings, address[] memory members) = abi + .decode(_data, (MajorityVotingBase.VotingSettings, address[])); + + // Prepare and Deploy the plugin proxy. + plugin = createERC1967Proxy( + address(addresslistVotingBase), + abi.encodeWithSelector( + AddresslistVoting.initialize.selector, + _dao, + votingSettings, + members + ) + ); + + // Prepare permissions + PermissionLib.MultiTargetPermission[] + memory permissions = new PermissionLib.MultiTargetPermission[](4); + + // Set permissions to be granted. + // Grant the list of permissions of the plugin to the DAO. + permissions[0] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Grant, + plugin, + _dao, + PermissionLib.NO_CONDITION, + addresslistVotingBase.UPDATE_ADDRESSES_PERMISSION_ID() + ); + + permissions[1] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Grant, + plugin, + _dao, + PermissionLib.NO_CONDITION, + addresslistVotingBase.UPDATE_VOTING_SETTINGS_PERMISSION_ID() + ); + + permissions[2] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Grant, + plugin, + _dao, + PermissionLib.NO_CONDITION, + addresslistVotingBase.UPGRADE_PLUGIN_PERMISSION_ID() + ); + + // Grant `EXECUTE_PERMISSION` of the DAO to the plugin. + permissions[3] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Grant, + _dao, + plugin, + PermissionLib.NO_CONDITION, + DAO(payable(_dao)).EXECUTE_PERMISSION_ID() + ); + + preparedSetupData.permissions = permissions; + } + + /// @inheritdoc IPluginSetup + function prepareUninstallation( + address _dao, + SetupPayload calldata _payload + ) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) { + // Prepare permissions + permissions = new PermissionLib.MultiTargetPermission[](4); + + // Set permissions to be Revoked. + permissions[0] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Revoke, + _payload.plugin, + _dao, + PermissionLib.NO_CONDITION, + addresslistVotingBase.UPDATE_ADDRESSES_PERMISSION_ID() + ); + + permissions[1] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Revoke, + _payload.plugin, + _dao, + PermissionLib.NO_CONDITION, + addresslistVotingBase.UPDATE_VOTING_SETTINGS_PERMISSION_ID() + ); + + permissions[2] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Revoke, + _payload.plugin, + _dao, + PermissionLib.NO_CONDITION, + addresslistVotingBase.UPGRADE_PLUGIN_PERMISSION_ID() + ); + + permissions[3] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Revoke, + _dao, + _payload.plugin, + PermissionLib.NO_CONDITION, + DAO(payable(_dao)).EXECUTE_PERMISSION_ID() + ); + } + + /// @inheritdoc IPluginSetup + function implementation() external view returns (address) { + return address(addresslistVotingBase); + } +} diff --git a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/build-metadata.json b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/build-metadata.json new file mode 100644 index 000000000..e746b71aa --- /dev/null +++ b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/build-metadata.json @@ -0,0 +1,12 @@ +{ + "ui": "", + "change": "", + "pluginSetupABI": { + "prepareInstallation": [ + "tuple(uint8 votingMode, uint64 supportThreshold, uint64 minParticipation, uint64 minDuration, uint256 minProposerVotingPower) votingSettings", + "address[] members" + ], + "prepareUpdate": [""], + "prepareUninstallation": [""] + } +} diff --git a/packages/contracts/src/plugins/governance/majority-voting/token/build-metadata.json b/packages/contracts/src/plugins/governance/majority-voting/token/build-metadata.json index 0f451e2bc..ee68a93d2 100644 --- a/packages/contracts/src/plugins/governance/majority-voting/token/build-metadata.json +++ b/packages/contracts/src/plugins/governance/majority-voting/token/build-metadata.json @@ -7,7 +7,7 @@ "tuple(address addr, string name, string symbol) tokenSettings", "tuple(address[] receivers, uint256[] amounts) mintSettings" ], - "prepareUpdate": [""], - "prepareUninstallation": [""] + "prepareUpdate": [], + "prepareUninstallation": [] } } diff --git a/packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVoting.sol b/packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVoting.sol new file mode 100644 index 000000000..7b6c6089d --- /dev/null +++ b/packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVoting.sol @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.17; + +import {IVotesUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol"; +import {SafeCastUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; + +import {IMembership} from "../../../../core/plugin/membership/IMembership.sol"; +import {IDAO} from "../../../../core/dao/IDAO.sol"; +import {RATIO_BASE, _applyRatioCeiled} from "../../../utils/Ratio.sol"; +import {MajorityVotingBase} from "../MajorityVotingBase.sol"; +import {IMajorityVoting} from "../IMajorityVoting.sol"; + +/// @title TokenVoting +/// @author Aragon Association - 2021-2023 +/// @notice The majority voting implementation using an [OpenZeppelin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) compatible governance token. +/// @dev This contract inherits from `MajorityVotingBase` and implements the `IMajorityVoting` interface. +contract TokenVoting is IMembership, MajorityVotingBase { + using SafeCastUpgradeable for uint256; + + /// @notice The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract. + bytes4 internal constant TOKEN_VOTING_INTERFACE_ID = + this.initialize.selector ^ this.getVotingToken.selector; + + /// @notice An [OpenZeppelin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) compatible contract referencing the token being used for voting. + IVotesUpgradeable private votingToken; + + /// @notice Thrown if the voting power is zero + error NoVotingPower(); + + /// @notice Initializes the component. + /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). + /// @param _dao The IDAO interface of the associated DAO. + /// @param _votingSettings The voting settings. + /// @param _token The [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token used for voting. + function initialize( + IDAO _dao, + VotingSettings calldata _votingSettings, + IVotesUpgradeable _token + ) external initializer { + __MajorityVotingBase_init(_dao, _votingSettings); + + votingToken = _token; + + emit MembershipContractAnnounced({definingContract: address(_token)}); + } + + /// @notice Checks if this or the parent contract supports an interface by its ID. + /// @param _interfaceId The ID of the interface. + /// @return Returns `true` if the interface is supported. + function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { + return + _interfaceId == TOKEN_VOTING_INTERFACE_ID || + _interfaceId == type(IMembership).interfaceId || + super.supportsInterface(_interfaceId); + } + + /// @notice getter function for the voting token. + /// @dev public function also useful for registering interfaceId and for distinguishing from majority voting interface. + /// @return The token used for voting. + function getVotingToken() public view returns (IVotesUpgradeable) { + return votingToken; + } + + /// @inheritdoc MajorityVotingBase + function totalVotingPower(uint256 _blockNumber) public view override returns (uint256) { + return votingToken.getPastTotalSupply(_blockNumber); + } + + /// @inheritdoc MajorityVotingBase + function createProposal( + bytes calldata _metadata, + IDAO.Action[] calldata _actions, + uint256 _allowFailureMap, + uint64 _startDate, + uint64 _endDate, + VoteOption _voteOption, + bool _tryEarlyExecution + ) external override returns (uint256 proposalId) { + uint256 snapshotBlock; + unchecked { + snapshotBlock = block.number - 1; + } + + uint256 totalVotingPower_ = totalVotingPower(snapshotBlock); + + if (totalVotingPower_ == 0) { + revert NoVotingPower(); + } + + if (votingToken.getPastVotes(_msgSender(), snapshotBlock) < minProposerVotingPower()) { + revert ProposalCreationForbidden(_msgSender()); + } + + proposalId = _createProposal({ + _creator: _msgSender(), + _metadata: _metadata, + _startDate: _startDate, + _endDate: _endDate, + _actions: _actions, + _allowFailureMap: _allowFailureMap + }); + + // Store proposal related information + Proposal storage proposal_ = proposals[proposalId]; + + (proposal_.parameters.startDate, proposal_.parameters.endDate) = _validateProposalDates( + _startDate, + _endDate + ); + proposal_.parameters.snapshotBlock = snapshotBlock.toUint64(); + proposal_.parameters.votingMode = votingMode(); + proposal_.parameters.supportThreshold = supportThreshold(); + proposal_.parameters.minVotingPower = _applyRatioCeiled( + totalVotingPower_, + minParticipation() + ); + + // Reduce costs + if (_allowFailureMap != 0) { + proposal_.allowFailureMap = _allowFailureMap; + } + + for (uint256 i; i < _actions.length; ) { + proposal_.actions.push(_actions[i]); + unchecked { + ++i; + } + } + + if (_voteOption != VoteOption.None) { + vote(proposalId, _voteOption, _tryEarlyExecution); + } + } + + /// @inheritdoc IMembership + function isMember(address _account) external view returns (bool) { + /// whatever condition + return votingToken.getVotes(_account) > 0; + } + + /// @inheritdoc MajorityVotingBase + function _vote( + uint256 _proposalId, + VoteOption _voteOption, + address _voter, + bool _tryEarlyExecution + ) internal override { + Proposal storage proposal_ = proposals[_proposalId]; + + // This could re-enter, though we can assume the governance token is not malicious + uint256 votingPower = votingToken.getPastVotes(_voter, proposal_.parameters.snapshotBlock); + VoteOption state = proposal_.voters[_voter]; + + // If voter had previously voted, decrease count + if (state == VoteOption.Yes) { + proposal_.tally.yes = proposal_.tally.yes - votingPower; + } else if (state == VoteOption.No) { + proposal_.tally.no = proposal_.tally.no - votingPower; + } else if (state == VoteOption.Abstain) { + proposal_.tally.abstain = proposal_.tally.abstain - votingPower; + } + + // write the updated/new vote for the voter. + if (_voteOption == VoteOption.Yes) { + proposal_.tally.yes = proposal_.tally.yes + votingPower; + } else if (_voteOption == VoteOption.No) { + proposal_.tally.no = proposal_.tally.no + votingPower; + } else if (_voteOption == VoteOption.Abstain) { + proposal_.tally.abstain = proposal_.tally.abstain + votingPower; + } + + proposal_.voters[_voter] = _voteOption; + + emit VoteCast({ + proposalId: _proposalId, + voter: _voter, + voteOption: _voteOption, + votingPower: votingPower + }); + + if (_tryEarlyExecution && _canExecute(_proposalId)) { + _execute(_proposalId); + } + } + + /// @inheritdoc MajorityVotingBase + function _canVote( + uint256 _proposalId, + address _account, + VoteOption _voteOption + ) internal view override returns (bool) { + Proposal storage proposal_ = proposals[_proposalId]; + + // The proposal vote hasn't started or has already ended. + if (!_isProposalOpen(proposal_)) { + return false; + } + + // The voter votes `None` which is not allowed. + if (_voteOption == VoteOption.None) { + return false; + } + + // The voter has no voting power. + if (votingToken.getPastVotes(_account, proposal_.parameters.snapshotBlock) == 0) { + return false; + } + + // The voter has already voted but vote replacment is not allowed. + if ( + proposal_.voters[_account] != VoteOption.None && + proposal_.parameters.votingMode != VotingMode.VoteReplacement + ) { + return false; + } + + return true; + } + + /// @dev This empty reserved space is put in place to allow future versions to add new + /// variables without shifting down storage in the inheritance chain. + /// https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps + uint256[49] private __gap; +} diff --git a/packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVotingSetup.sol b/packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVotingSetup.sol new file mode 100644 index 000000000..74616e4b1 --- /dev/null +++ b/packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVotingSetup.sol @@ -0,0 +1,282 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.17; + +import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; +import {Address} from "@openzeppelin/contracts/utils/Address.sol"; +import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; +import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import {IVotesUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol"; + +import {IDAO_v1_0_0} from "../../../../core/dao/legacy/IDAO_v1_0_0.sol"; +import {DAO_v1_0_0} from "../../../../../core/dao/DAO_v1_0_0.sol"; +import {PermissionLib} from "../../../../../core/permission/PermissionLib.sol"; +import {PluginSetup, IPluginSetup} from "../../../../../framework/plugin/setup/PluginSetup.sol"; +import {GovernanceERC20} from "../../../../token/ERC20/governance/GovernanceERC20.sol"; +import {GovernanceWrappedERC20} from "../../../../token/ERC20/governance/GovernanceWrappedERC20.sol"; +import {IGovernanceWrappedERC20} from "../../../../token/ERC20/governance/IGovernanceWrappedERC20.sol"; +import {MajorityVotingBase} from "../MajorityVotingBase.sol"; +import {TokenVoting} from "./TokenVoting.sol"; + +/// @title TokenVotingSetup +/// @author Aragon Association - 2022-2023 +/// @notice The setup contract of the `TokenVoting` plugin. +contract TokenVotingSetup_R1B1 is PluginSetup { + using Address for address; + using Clones for address; + using ERC165Checker for address; + + /// @notice The address of the `TokenVoting` base contract. + TokenVoting private immutable tokenVotingBase; + + /// @notice The address of the `GovernanceERC20` base contract. + address public immutable governanceERC20Base; + + /// @notice The address of the `GovernanceWrappedERC20` base contract. + address public immutable governanceWrappedERC20Base; + + /// @notice The token settings struct. + /// @param addr The token address. If this is `address(0)`, a new `GovernanceERC20` token is deployed. If not, the existing token is wrapped as an `GovernanceWrappedERC20`. + /// @param name The token name. This parameter is only relevant if the token address is `address(0)`. + /// @param name The token symbol. This parameter is only relevant if the token address is `address(0)`. + struct TokenSettings { + address addr; + string name; + string symbol; + } + + /// @notice Thrown if token address is passed which is not a token. + /// @param token The token address + error TokenNotContract(address token); + + /// @notice Thrown if token address is not ERC20. + /// @param token The token address + error TokenNotERC20(address token); + + /// @notice Thrown if passed helpers array is of wrong length. + /// @param length The array length of passed helpers. + error WrongHelpersArrayLength(uint256 length); + + /// @notice The contract constructor, that deploys the bases. + constructor() { + governanceERC20Base = address( + new GovernanceERC20( + IDAO(address(0)), + "", + "", + GovernanceERC20.MintSettings(new address[](0), new uint256[](0)) + ) + ); + governanceWrappedERC20Base = address( + new GovernanceWrappedERC20(IERC20Upgradeable(address(0)), "", "") + ); + tokenVotingBase = new TokenVoting(); + } + + /// @inheritdoc IPluginSetup + function prepareInstallation( + address _dao, + bytes calldata _data + ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { + // Decode `_data` to extract the params needed for deploying and initializing `TokenVoting` plugin, + // and the required helpers + ( + MajorityVotingBase.VotingSettings memory votingSettings, + TokenSettings memory tokenSettings, + // only used for GovernanceERC20(token is not passed) + GovernanceERC20.MintSettings memory mintSettings + ) = abi.decode( + _data, + (MajorityVotingBase.VotingSettings, TokenSettings, GovernanceERC20.MintSettings) + ); + + address token = tokenSettings.addr; + + // Prepare helpers. + address[] memory helpers = new address[](1); + + if (token != address(0)) { + if (!token.isContract()) { + revert TokenNotContract(token); + } + + if (!_isERC20(token)) { + revert TokenNotERC20(token); + } + + // [0] = IERC20Upgradeable, [1] = IVotesUpgradeable, [2] = IGovernanceWrappedERC20 + bool[] memory supportedIds = _getTokenInterfaceIds(token); + + if ( + // If token supports none of them + // it's simply ERC20 which gets checked by _isERC20 + // Currently, not a satisfiable check. + (!supportedIds[0] && !supportedIds[1] && !supportedIds[2]) || + // If token supports IERC20, but neither + // IVotes nor IGovernanceWrappedERC20, it needs wrapping. + (supportedIds[0] && !supportedIds[1] && !supportedIds[2]) + ) { + token = governanceWrappedERC20Base.clone(); + // User already has a token. We need to wrap it in + // GovernanceWrappedERC20 in order to make the token + // include governance functionality. + GovernanceWrappedERC20(token).initialize( + IERC20Upgradeable(tokenSettings.addr), + tokenSettings.name, + tokenSettings.symbol + ); + } + } else { + // Clone a `GovernanceERC20`. + token = governanceERC20Base.clone(); + GovernanceERC20(token).initialize( + IDAO(_dao), + tokenSettings.name, + tokenSettings.symbol, + mintSettings + ); + } + + helpers[0] = token; + + // Prepare and deploy plugin proxy. + plugin = createERC1967Proxy( + address(tokenVotingBase), + abi.encodeWithSelector(TokenVoting.initialize.selector, _dao, votingSettings, token) + ); + + // Prepare permissions + PermissionLib.MultiTargetPermission[] + memory permissions = new PermissionLib.MultiTargetPermission[]( + tokenSettings.addr != address(0) ? 3 : 4 + ); + + // Set plugin permissions to be granted. + // Grant the list of permissions of the plugin to the DAO. + permissions[0] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Grant, + plugin, + _dao, + PermissionLib.NO_CONDITION, + tokenVotingBase.UPDATE_VOTING_SETTINGS_PERMISSION_ID() + ); + + permissions[1] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Grant, + plugin, + _dao, + PermissionLib.NO_CONDITION, + tokenVotingBase.UPGRADE_PLUGIN_PERMISSION_ID() + ); + + // Grant `EXECUTE_PERMISSION` of the DAO to the plugin. + permissions[2] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Grant, + _dao, + plugin, + PermissionLib.NO_CONDITION, + DAO(payable(_dao)).EXECUTE_PERMISSION_ID() + ); + + if (tokenSettings.addr == address(0)) { + bytes32 tokenMintPermission = GovernanceERC20(token).MINT_PERMISSION_ID(); + + permissions[3] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Grant, + token, + _dao, + PermissionLib.NO_CONDITION, + tokenMintPermission + ); + } + + preparedSetupData.helpers = helpers; + preparedSetupData.permissions = permissions; + } + + /// @inheritdoc IPluginSetup + function prepareUninstallation( + address _dao, + SetupPayload calldata _payload + ) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) { + // Prepare permissions. + uint256 helperLength = _payload.currentHelpers.length; + if (helperLength != 1) { + revert WrongHelpersArrayLength({length: helperLength}); + } + + // token can be either GovernanceERC20, GovernanceWrappedERC20, or IVotesUpgradeable, which + // does not follow the GovernanceERC20 and GovernanceWrappedERC20 standard. + address token = _payload.currentHelpers[0]; + + bool[] memory supportedIds = _getTokenInterfaceIds(token); + + bool isGovernanceERC20 = supportedIds[0] && supportedIds[1] && !supportedIds[2]; + + permissions = new PermissionLib.MultiTargetPermission[](isGovernanceERC20 ? 4 : 3); + + // Set permissions to be Revoked. + permissions[0] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Revoke, + _payload.plugin, + _dao, + PermissionLib.NO_CONDITION, + tokenVotingBase.UPDATE_VOTING_SETTINGS_PERMISSION_ID() + ); + + permissions[1] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Revoke, + _payload.plugin, + _dao, + PermissionLib.NO_CONDITION, + tokenVotingBase.UPGRADE_PLUGIN_PERMISSION_ID() + ); + + permissions[2] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Revoke, + _dao, + _payload.plugin, + PermissionLib.NO_CONDITION, + DAO(payable(_dao)).EXECUTE_PERMISSION_ID() + ); + + // Revocation of permission is necessary only if the deployed token is GovernanceERC20, + // as GovernanceWrapped does not possess this permission. Only return the following + // if it's type of GovernanceERC20, otherwise revoking this permission wouldn't have any effect. + if (isGovernanceERC20) { + permissions[3] = PermissionLib.MultiTargetPermission( + PermissionLib.Operation.Revoke, + token, + _dao, + PermissionLib.NO_CONDITION, + GovernanceERC20(token).MINT_PERMISSION_ID() + ); + } + } + + /// @inheritdoc IPluginSetup + function implementation() external view virtual override returns (address) { + return address(tokenVotingBase); + } + + /// @notice Retrieves the interface identifiers supported by the token contract. + /// @dev It is crucial to verify if the provided token address represents a valid contract before using the below. + /// @param token The token address + function _getTokenInterfaceIds(address token) private view returns (bool[] memory) { + bytes4[] memory interfaceIds = new bytes4[](3); + interfaceIds[0] = type(IERC20Upgradeable).interfaceId; + interfaceIds[1] = type(IVotesUpgradeable).interfaceId; + interfaceIds[2] = type(IGovernanceWrappedERC20).interfaceId; + return token.getSupportedInterfaces(interfaceIds); + } + + /// @notice Unsatisfiably determines if the contract is an ERC20 token. + /// @dev It's important to first check whether token is a contract prior to this call. + /// @param token The token address + function _isERC20(address token) private view returns (bool) { + (bool success, bytes memory data) = token.staticcall( + abi.encodeWithSelector(IERC20Upgradeable.balanceOf.selector, address(this)) + ); + return success && data.length == 0x20; + } +} diff --git a/packages/contracts/src/plugins/governance/majority-voting/token/build1/build-metadata.json b/packages/contracts/src/plugins/governance/majority-voting/token/build1/build-metadata.json new file mode 100644 index 000000000..0f451e2bc --- /dev/null +++ b/packages/contracts/src/plugins/governance/majority-voting/token/build1/build-metadata.json @@ -0,0 +1,13 @@ +{ + "ui": "", + "change": "", + "pluginSetupABI": { + "prepareInstallation": [ + "tuple(uint8 votingMode, uint64 supportThreshold, uint64 minParticipation, uint64 minDuration, uint256 minProposerVotingPower) votingSettings", + "tuple(address addr, string name, string symbol) tokenSettings", + "tuple(address[] receivers, uint256[] amounts) mintSettings" + ], + "prepareUpdate": [""], + "prepareUninstallation": [""] + } +} From f437dbc32e0f0c6b816d82295c4a353385ac2b19 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 8 May 2023 09:45:29 +0200 Subject: [PATCH 060/112] doc: clarified the origin of the implementation slot --- packages/contracts/test/test-utils/uups-upgradeable.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/contracts/test/test-utils/uups-upgradeable.ts b/packages/contracts/test/test-utils/uups-upgradeable.ts index ca4ec843f..5cb6ef254 100644 --- a/packages/contracts/test/test-utils/uups-upgradeable.ts +++ b/packages/contracts/test/test-utils/uups-upgradeable.ts @@ -4,8 +4,9 @@ import {Contract} from 'ethers'; import {defaultAbiCoder} from 'ethers/lib/utils'; import {ethers} from 'hardhat'; +// See https://eips.ethereum.org/EIPS/eip-1967 export const IMPLEMENTATION_SLOT = - '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc'; + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc'; // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) /// Used as a common test suite to test upgradeability of the contracts. /// Presumes that `upgrade` object is set on `this` inside the actual test file. From 168b55b750ef84bc7cf11440de86689f8a84ea52 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 8 May 2023 10:04:24 +0200 Subject: [PATCH 061/112] fix: versioning --- .../{DAO_v1_3_0-alpha.sol => DAO_v1_2_0.sol} | 30 +++++++++---------- ...{IDAO_v1_3_0_alpha.sol => IDAO_v1_2_0.sol} | 4 +-- packages/contracts/test/upgrade/dao.ts | 14 ++++----- 3 files changed, 24 insertions(+), 24 deletions(-) rename packages/contracts/src/core/dao/legacy/{DAO_v1_3_0-alpha.sol => DAO_v1_2_0.sol} (96%) rename packages/contracts/src/core/dao/legacy/{IDAO_v1_3_0_alpha.sol => IDAO_v1_2_0.sol} (98%) diff --git a/packages/contracts/src/core/dao/legacy/DAO_v1_3_0-alpha.sol b/packages/contracts/src/core/dao/legacy/DAO_v1_2_0.sol similarity index 96% rename from packages/contracts/src/core/dao/legacy/DAO_v1_3_0-alpha.sol rename to packages/contracts/src/core/dao/legacy/DAO_v1_2_0.sol index ce174bb1f..8476a84df 100644 --- a/packages/contracts/src/core/dao/legacy/DAO_v1_3_0-alpha.sol +++ b/packages/contracts/src/core/dao/legacy/DAO_v1_2_0.sol @@ -17,18 +17,18 @@ import {PermissionManager} from "../../permission/PermissionManager.sol"; import {CallbackHandler} from "../../utils/CallbackHandler.sol"; import {hasBit, flipBit} from "../../utils/BitMap.sol"; import {IEIP4824} from "../IEIP4824.sol"; -import {IDAO_v1_3_0_alpha} from "./IDAO_v1_3_0_alpha.sol"; +import {IDAO_v1_2_0} from "./IDAO_v1_2_0.sol"; -/// @title DAO v1.3.0-alpha (mumbai pre-release) +/// @title DAO v1.2.0 /// @author Aragon Association - 2021-2023 /// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. /// @dev Public API of the Aragon DAO framework. -contract DAO_v1_3_0_alpha is +contract DAO_v1_2_0 is IEIP4824, Initializable, IERC1271, ERC165StorageUpgradeable, - IDAO_v1_3_0_alpha, + IDAO_v1_2_0, UUPSUpgradeable, PermissionManager, CallbackHandler @@ -135,7 +135,7 @@ contract DAO_v1_3_0_alpha is ) external initializer { _reentrancyStatus = _NOT_ENTERED; - _registerInterface(type(IDAO_v1_3_0_alpha).interfaceId); + _registerInterface(type(IDAO_v1_2_0).interfaceId); _registerInterface(type(IERC1271).interfaceId); _registerInterface(type(IEIP4824).interfaceId); _registerTokenInterfaces(); @@ -163,19 +163,19 @@ contract DAO_v1_3_0_alpha is /// @dev The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {} - /// @inheritdoc IDAO_v1_3_0_alpha + /// @inheritdoc IDAO_v1_2_0 function setTrustedForwarder( address _newTrustedForwarder ) external override auth(SET_TRUSTED_FORWARDER_PERMISSION_ID) { _setTrustedForwarder(_newTrustedForwarder); } - /// @inheritdoc IDAO_v1_3_0_alpha + /// @inheritdoc IDAO_v1_2_0 function getTrustedForwarder() external view virtual override returns (address) { return trustedForwarder; } - /// @inheritdoc IDAO_v1_3_0_alpha + /// @inheritdoc IDAO_v1_2_0 function hasPermission( address _where, address _who, @@ -185,14 +185,14 @@ contract DAO_v1_3_0_alpha is return isGranted(_where, _who, _permissionId, _data); } - /// @inheritdoc IDAO_v1_3_0_alpha + /// @inheritdoc IDAO_v1_2_0 function setMetadata( bytes calldata _metadata ) external override auth(SET_METADATA_PERMISSION_ID) { _setMetadata(_metadata); } - /// @inheritdoc IDAO_v1_3_0_alpha + /// @inheritdoc IDAO_v1_2_0 function execute( bytes32 _callId, Action[] calldata _actions, @@ -260,7 +260,7 @@ contract DAO_v1_3_0_alpha is }); } - /// @inheritdoc IDAO_v1_3_0_alpha + /// @inheritdoc IDAO_v1_2_0 function deposit( address _token, uint256 _amount, @@ -281,7 +281,7 @@ contract DAO_v1_3_0_alpha is emit Deposited(msg.sender, _token, _amount, _reference); } - /// @inheritdoc IDAO_v1_3_0_alpha + /// @inheritdoc IDAO_v1_2_0 function setSignatureValidator( address _signatureValidator ) external override auth(SET_SIGNATURE_VALIDATOR_PERMISSION_ID) { @@ -290,11 +290,11 @@ contract DAO_v1_3_0_alpha is emit SignatureValidatorSet({signatureValidator: _signatureValidator}); } - /// @inheritdoc IDAO_v1_3_0_alpha + /// @inheritdoc IDAO_v1_2_0 function isValidSignature( bytes32 _hash, bytes memory _signature - ) external view override(IDAO_v1_3_0_alpha, IERC1271) returns (bytes4) { + ) external view override(IDAO_v1_2_0, IERC1271) returns (bytes4) { if (address(signatureValidator) == address(0)) { // Return the invalid magic number return bytes4(0); @@ -351,7 +351,7 @@ contract DAO_v1_3_0_alpha is ); } - /// @inheritdoc IDAO_v1_3_0_alpha + /// @inheritdoc IDAO_v1_2_0 function registerStandardCallback( bytes4 _interfaceId, bytes4 _callbackSelector, diff --git a/packages/contracts/src/core/dao/legacy/IDAO_v1_3_0_alpha.sol b/packages/contracts/src/core/dao/legacy/IDAO_v1_2_0.sol similarity index 98% rename from packages/contracts/src/core/dao/legacy/IDAO_v1_3_0_alpha.sol rename to packages/contracts/src/core/dao/legacy/IDAO_v1_2_0.sol index 6a9cec9cc..6085c598e 100644 --- a/packages/contracts/src/core/dao/legacy/IDAO_v1_3_0_alpha.sol +++ b/packages/contracts/src/core/dao/legacy/IDAO_v1_2_0.sol @@ -2,10 +2,10 @@ pragma solidity ^0.8.8; -/// @title IDAO v1.3.0-alpha (mumbai pre-release) +/// @title IDAO v1.2.0 /// @author Aragon Association - 2022-2023 /// @notice The interface required for DAOs within the Aragon App DAO framework. -interface IDAO_v1_3_0_alpha { +interface IDAO_v1_2_0 { /// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call. /// @param to The address to call. /// @param value The native token value to be sent with the call. diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 7077b4fc5..eadfc2189 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -6,8 +6,8 @@ import { DAO__factory, DAOV101, DAOV101__factory, - DAOV130Alpha, - DAOV130Alpha__factory, + DAOV120, + DAOV120__factory, } from '../../typechain'; import {daoExampleURI} from '../test-utils/dao'; @@ -18,7 +18,7 @@ import {readImplementationValueFromSlot} from '../../utils/storage'; let signers: SignerWithAddress[]; let Dao_v1_0_1: DAOV101__factory; -let Dao_v1_3_0_alpha: DAOV130Alpha__factory; +let Dao_v1_2_0: DAOV120__factory; let DaoCurrent: DAO__factory; const DUMMY_METADATA = ethers.utils.hexlify( @@ -29,7 +29,7 @@ describe('DAO Upgrade', function () { before(async function () { signers = await ethers.getSigners(); Dao_v1_0_1 = new DAOV101__factory(signers[0]); - Dao_v1_3_0_alpha = new DAOV130Alpha__factory(signers[0]); + Dao_v1_2_0 = new DAOV120__factory(signers[0]); DaoCurrent = new DAO__factory(signers[0]); // 1.3.0 }); @@ -79,8 +79,8 @@ describe('DAO Upgrade', function () { expect(await proxy.callStatic.daoURI()).to.equal(daoExampleURI); }); - it('upgrades v1.3.0-alpha (mumbai pre-release) to v1.3.0', async () => { - const proxy = await deployWithProxy(Dao_v1_3_0_alpha); + it('upgrades v1.2.0 to v1.3.0', async () => { + const proxy = await deployWithProxy(Dao_v1_2_0); await proxy.initialize( DUMMY_METADATA, signers[0].address, @@ -116,7 +116,7 @@ describe('DAO Upgrade', function () { // Check the emitted implementation. const emittedImplementation = ( - await findEventTopicLog(upgradeTx, Dao_v1_3_0_alpha.interface, 'Upgraded') + await findEventTopicLog(upgradeTx, Dao_v1_2_0.interface, 'Upgraded') ).args.implementation; expect(emittedImplementation).to.equal(newImplementation.address); From dbe21345ea8987092a6e68da49282b5a6f7bdd7c Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 8 May 2023 10:20:51 +0200 Subject: [PATCH 062/112] fix: move files --- .../dao/legacy => test/legacy/core/dao}/DAO_v1_0_1.sol | 8 ++++---- .../dao/legacy => test/legacy/core/dao}/DAO_v1_2_0.sol | 8 ++++---- .../dao/legacy => test/legacy/core/dao}/IDAO_v1_0_1.sol | 0 .../dao/legacy => test/legacy/core/dao}/IDAO_v1_2_0.sol | 0 4 files changed, 8 insertions(+), 8 deletions(-) rename packages/contracts/src/{core/dao/legacy => test/legacy/core/dao}/DAO_v1_0_1.sol (97%) rename packages/contracts/src/{core/dao/legacy => test/legacy/core/dao}/DAO_v1_2_0.sol (98%) rename packages/contracts/src/{core/dao/legacy => test/legacy/core/dao}/IDAO_v1_0_1.sol (100%) rename packages/contracts/src/{core/dao/legacy => test/legacy/core/dao}/IDAO_v1_2_0.sol (100%) diff --git a/packages/contracts/src/core/dao/legacy/DAO_v1_0_1.sol b/packages/contracts/src/test/legacy/core/dao/DAO_v1_0_1.sol similarity index 97% rename from packages/contracts/src/core/dao/legacy/DAO_v1_0_1.sol rename to packages/contracts/src/test/legacy/core/dao/DAO_v1_0_1.sol index fcdfc7dde..d871b9b59 100644 --- a/packages/contracts/src/core/dao/legacy/DAO_v1_0_1.sol +++ b/packages/contracts/src/test/legacy/core/dao/DAO_v1_0_1.sol @@ -13,10 +13,10 @@ import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgrad import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts/interfaces/IERC1271.sol"; -import {PermissionManager} from "../../permission/PermissionManager.sol"; -import {CallbackHandler} from "../../utils/CallbackHandler.sol"; -import {hasBit, flipBit} from "../../utils/BitMap.sol"; -import {IEIP4824} from "../IEIP4824.sol"; +import {PermissionManager} from "../../../../core/permission/PermissionManager.sol"; +import {CallbackHandler} from "../../../../core/utils/CallbackHandler.sol"; +import {hasBit, flipBit} from "../../../../core/utils/BitMap.sol"; +import {IEIP4824} from "../../../../core/dao/IEIP4824.sol"; import {IDAO_v1_0_1} from "./IDAO_v1_0_1.sol"; /// @title DAO v1.0.1 diff --git a/packages/contracts/src/core/dao/legacy/DAO_v1_2_0.sol b/packages/contracts/src/test/legacy/core/dao/DAO_v1_2_0.sol similarity index 98% rename from packages/contracts/src/core/dao/legacy/DAO_v1_2_0.sol rename to packages/contracts/src/test/legacy/core/dao/DAO_v1_2_0.sol index 8476a84df..5adcbbe10 100644 --- a/packages/contracts/src/core/dao/legacy/DAO_v1_2_0.sol +++ b/packages/contracts/src/test/legacy/core/dao/DAO_v1_2_0.sol @@ -13,10 +13,10 @@ import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgrad import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts/interfaces/IERC1271.sol"; -import {PermissionManager} from "../../permission/PermissionManager.sol"; -import {CallbackHandler} from "../../utils/CallbackHandler.sol"; -import {hasBit, flipBit} from "../../utils/BitMap.sol"; -import {IEIP4824} from "../IEIP4824.sol"; +import {PermissionManager} from "../../../../core/permission/PermissionManager.sol"; +import {CallbackHandler} from "../../../../core/utils/CallbackHandler.sol"; +import {hasBit, flipBit} from "../../../../core/utils/BitMap.sol"; +import {IEIP4824} from "../../../../core/dao/IEIP4824.sol"; import {IDAO_v1_2_0} from "./IDAO_v1_2_0.sol"; /// @title DAO v1.2.0 diff --git a/packages/contracts/src/core/dao/legacy/IDAO_v1_0_1.sol b/packages/contracts/src/test/legacy/core/dao/IDAO_v1_0_1.sol similarity index 100% rename from packages/contracts/src/core/dao/legacy/IDAO_v1_0_1.sol rename to packages/contracts/src/test/legacy/core/dao/IDAO_v1_0_1.sol diff --git a/packages/contracts/src/core/dao/legacy/IDAO_v1_2_0.sol b/packages/contracts/src/test/legacy/core/dao/IDAO_v1_2_0.sol similarity index 100% rename from packages/contracts/src/core/dao/legacy/IDAO_v1_2_0.sol rename to packages/contracts/src/test/legacy/core/dao/IDAO_v1_2_0.sol From 5e209e3681b64c0e2f8a509211507cd2860a9cd9 Mon Sep 17 00:00:00 2001 From: Michael Heuer <20623991+Michael-A-Heuer@users.noreply.github.com> Date: Mon, 8 May 2023 10:25:44 +0200 Subject: [PATCH 063/112] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jør∂¡ <4456749+brickpop@users.noreply.github.com> --- packages/contracts/utils/storage.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/contracts/utils/storage.ts b/packages/contracts/utils/storage.ts index 983342026..08ab5daec 100644 --- a/packages/contracts/utils/storage.ts +++ b/packages/contracts/utils/storage.ts @@ -3,24 +3,23 @@ import {defaultAbiCoder} from 'ethers/lib/utils'; import {IMPLEMENTATION_SLOT} from '../test/test-utils/uups-upgradeable'; -export async function readImplementationValuesFromSlot( +export function readImplementationValuesFromSlot( contractAddresses: string[] ): Promise { - const implementationValues: string[] = await Promise.all( - contractAddresses.map(async contractAddress => { - return readImplementationValueFromSlot(contractAddress); - }) + return Promise.all( + contractAddresses.map(contractAddress => + readImplementationValueFromSlot(contractAddress) + ) ); - - return implementationValues; } -export async function readImplementationValueFromSlot( +export function readImplementationValueFromSlot( contractAddress: string ): Promise { - const encoded = await ethers.provider.getStorageAt( + return ethers.provider.getStorageAt( contractAddress, IMPLEMENTATION_SLOT + ).then((encoded) => + defaultAbiCoder.decode(['address'], encoded)[0] ); - return defaultAbiCoder.decode(['address'], encoded)[0]; } From 6cbc32e078900a979bdfafce9aafff247c549e4c Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 8 May 2023 10:27:15 +0200 Subject: [PATCH 064/112] chore: formatting --- packages/contracts/utils/storage.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/contracts/utils/storage.ts b/packages/contracts/utils/storage.ts index 08ab5daec..d1f0af135 100644 --- a/packages/contracts/utils/storage.ts +++ b/packages/contracts/utils/storage.ts @@ -16,10 +16,7 @@ export function readImplementationValuesFromSlot( export function readImplementationValueFromSlot( contractAddress: string ): Promise { - return ethers.provider.getStorageAt( - contractAddress, - IMPLEMENTATION_SLOT - ).then((encoded) => - defaultAbiCoder.decode(['address'], encoded)[0] - ); + return ethers.provider + .getStorageAt(contractAddress, IMPLEMENTATION_SLOT) + .then(encoded => defaultAbiCoder.decode(['address'], encoded)[0]); } From 1b86fd055d8cc3d72d299894975c67b0e524eb3e Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 8 May 2023 10:32:23 +0200 Subject: [PATCH 065/112] chore: remove NatSpec version number from osx files --- packages/contracts/src/core/dao/IDAO.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/src/core/dao/IDAO.sol b/packages/contracts/src/core/dao/IDAO.sol index 81e44e270..e50fad31e 100644 --- a/packages/contracts/src/core/dao/IDAO.sol +++ b/packages/contracts/src/core/dao/IDAO.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.8; -/// @title IDAO v1.1.0 +/// @title IDAO /// @author Aragon Association - 2022-2023 /// @notice The interface required for DAOs within the Aragon App DAO framework. interface IDAO { From 9b6a514af80df2c082ecf2a7aea2f6eac2ef278a Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 8 May 2023 10:55:58 +0200 Subject: [PATCH 066/112] feat: added more tests --- packages/contracts/test/upgrade/dao.ts | 277 +++++++++++++++++-------- 1 file changed, 191 insertions(+), 86 deletions(-) diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index eadfc2189..5267db00c 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -3,6 +3,7 @@ import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import { + DAO, DAO__factory, DAOV101, DAOV101__factory, @@ -21,6 +22,15 @@ let Dao_v1_0_1: DAOV101__factory; let Dao_v1_2_0: DAOV120__factory; let DaoCurrent: DAO__factory; +let daoV101Proxy: DAOV101; +let daoV120Proxy: DAOV120; + +let daoV101Implementation: string; +let daoV120Implementation: string; +let daoCurrentImplementaion: DAO; + +const EMPTY_DATA = '0x'; + const DUMMY_METADATA = ethers.utils.hexlify( ethers.utils.toUtf8Bytes('0x123456789') ); @@ -32,95 +42,190 @@ describe('DAO Upgrade', function () { Dao_v1_2_0 = new DAOV120__factory(signers[0]); DaoCurrent = new DAO__factory(signers[0]); // 1.3.0 + + // Deploy the v1.3.0 implementation + daoCurrentImplementaion = await DaoCurrent.deploy(); }); - it('upgrades v1.0.1 to v1.3.0', async () => { - const proxy = await deployWithProxy(Dao_v1_0_1); - await proxy.initialize( - DUMMY_METADATA, - signers[0].address, - ethers.constants.AddressZero, - daoExampleURI - ); - - // Store the current implementation - const implementationBeforeUpgrade = await readImplementationValueFromSlot( - proxy.address - ); - - proxy.grant( - proxy.address, - signers[0].address, - UPGRADE_PERMISSIONS.UPGRADE_DAO_PERMISSION_ID - ); - - // Deploy the new implementation - const newImplementation = await DaoCurrent.deploy(); - - // Upgrade to the new implementation - const upgradeTx = await proxy.upgradeTo(newImplementation.address); - - // Check the stored implementation. - const implementationAfterUpgrade = await readImplementationValueFromSlot( - proxy.address - ); - expect(implementationAfterUpgrade).to.equal(newImplementation.address); - expect(implementationAfterUpgrade).to.not.equal( - implementationBeforeUpgrade - ); - - // Check the emitted implementation. - const emittedImplementation = ( - await findEventTopicLog(upgradeTx, Dao_v1_0_1.interface, 'Upgraded') - ).args.implementation; - expect(emittedImplementation).to.equal(newImplementation.address); - - // Check that storage is not corrupted. - expect(await proxy.callStatic.daoURI()).to.equal(daoExampleURI); + context(`v1.0.1 to v1.3.0`, function () { + beforeEach(async function () { + daoV101Proxy = await deployWithProxy(Dao_v1_0_1); + await daoV101Proxy.initialize( + DUMMY_METADATA, + signers[0].address, + ethers.constants.AddressZero, + daoExampleURI + ); + + // Store the v1.0.1 implementation + daoV101Implementation = await readImplementationValueFromSlot( + daoV101Proxy.address + ); + + // Grant the upgrade permission + await daoV101Proxy.grant( + daoV101Proxy.address, + signers[0].address, + UPGRADE_PERMISSIONS.UPGRADE_DAO_PERMISSION_ID + ); + }); + + it('does not corrupt the DAO storage', async () => { + // Upgrade to the new implementation + const upgradeTx = await daoV101Proxy.upgradeTo( + daoCurrentImplementaion.address + ); + + // Check the stored implementation. + const implementationAfterUpgrade = await readImplementationValueFromSlot( + daoV101Proxy.address + ); + expect(implementationAfterUpgrade).to.equal( + daoCurrentImplementaion.address + ); + expect(implementationAfterUpgrade).to.not.equal(daoV101Implementation); + + // Check the emitted implementation. + const emittedImplementation = ( + await findEventTopicLog(upgradeTx, Dao_v1_0_1.interface, 'Upgraded') + ).args.implementation; + expect(emittedImplementation).to.equal(daoCurrentImplementaion.address); + + // Check that storage is not corrupted. + expect(await daoV101Proxy.callStatic.daoURI()).to.equal(daoExampleURI); + }); + + it('does not corrupt permissions', async () => { + await daoV101Proxy.grant( + daoV101Proxy.address, + signers[0].address, + ethers.utils.id('EXECUTE_PERMISSION') + ); + await daoV101Proxy.grant( + daoV101Proxy.address, + signers[0].address, + ethers.utils.id('ROOT_PERMISSION') + ); + + // Upgrade to the new implementation + await daoV101Proxy.upgradeTo(daoCurrentImplementaion.address); + + // Check the stored implementation. + const implementationAfterUpgrade = await readImplementationValueFromSlot( + daoV101Proxy.address + ); + expect(implementationAfterUpgrade).to.equal( + daoCurrentImplementaion.address + ); + expect(implementationAfterUpgrade).to.not.equal(daoV101Implementation); + + expect( + await daoV101Proxy.hasPermission( + daoV101Proxy.address, + signers[0].address, + ethers.utils.id('EXECUTE_PERMISSION'), + EMPTY_DATA + ) + ).to.be.true; + expect( + await daoV101Proxy.hasPermission( + daoV101Proxy.address, + signers[0].address, + ethers.utils.id('ROOT_PERMISSION'), + EMPTY_DATA + ) + ).to.be.true; + }); }); - it('upgrades v1.2.0 to v1.3.0', async () => { - const proxy = await deployWithProxy(Dao_v1_2_0); - await proxy.initialize( - DUMMY_METADATA, - signers[0].address, - ethers.constants.AddressZero, - daoExampleURI - ); - - // Store the current implementation - const implementationBeforeUpgrade = await readImplementationValueFromSlot( - proxy.address - ); - - proxy.grant( - proxy.address, - signers[0].address, - UPGRADE_PERMISSIONS.UPGRADE_DAO_PERMISSION_ID - ); - - // Deploy the new implementation - const newImplementation = await DaoCurrent.deploy(); - - // Upgrade to the new implementation - const upgradeTx = await proxy.upgradeTo(newImplementation.address); - - // Check the stored implementation. - const implementationAfterUpgrade = await readImplementationValueFromSlot( - proxy.address - ); - expect(implementationAfterUpgrade).to.equal(newImplementation.address); - expect(implementationAfterUpgrade).to.not.equal( - implementationBeforeUpgrade - ); - - // Check the emitted implementation. - const emittedImplementation = ( - await findEventTopicLog(upgradeTx, Dao_v1_2_0.interface, 'Upgraded') - ).args.implementation; - expect(emittedImplementation).to.equal(newImplementation.address); - - // Check that storage is not corrupted. - expect(await proxy.callStatic.daoURI()).to.equal(daoExampleURI); + context(`v1.2.0 to v1.3.0`, function () { + beforeEach(async function () { + daoV120Proxy = await deployWithProxy(Dao_v1_2_0); + await daoV120Proxy.initialize( + DUMMY_METADATA, + signers[0].address, + ethers.constants.AddressZero, + daoExampleURI + ); + + // Store the v1.2.0 implementation + daoV120Implementation = await readImplementationValueFromSlot( + daoV120Proxy.address + ); + + // Grant the upgrade permission + await daoV120Proxy.grant( + daoV120Proxy.address, + signers[0].address, + UPGRADE_PERMISSIONS.UPGRADE_DAO_PERMISSION_ID + ); + }); + + it('does not corrupt the DAO storage', async () => { + // Upgrade to the new implementation + const upgradeTx = await daoV120Proxy.upgradeTo( + daoCurrentImplementaion.address + ); + + // Check the stored implementation. + const implementationAfterUpgrade = await readImplementationValueFromSlot( + daoV120Proxy.address + ); + expect(implementationAfterUpgrade).to.equal( + daoCurrentImplementaion.address + ); + expect(implementationAfterUpgrade).to.not.equal(daoV120Implementation); + + // Check the emitted implementation. + const emittedImplementation = ( + await findEventTopicLog(upgradeTx, Dao_v1_2_0.interface, 'Upgraded') + ).args.implementation; + expect(emittedImplementation).to.equal(daoCurrentImplementaion.address); + + // Check that storage is not corrupted. + expect(await daoV120Proxy.callStatic.daoURI()).to.equal(daoExampleURI); + }); + + it('does not corrupt permissions', async () => { + await daoV120Proxy.grant( + daoV120Proxy.address, + signers[0].address, + ethers.utils.id('EXECUTE_PERMISSION') + ); + await daoV120Proxy.grant( + daoV120Proxy.address, + signers[0].address, + ethers.utils.id('ROOT_PERMISSION') + ); + + // Upgrade to the new implementation + await daoV120Proxy.upgradeTo(daoCurrentImplementaion.address); + + // Check the stored implementation. + const implementationAfterUpgrade = await readImplementationValueFromSlot( + daoV120Proxy.address + ); + expect(implementationAfterUpgrade).to.equal( + daoCurrentImplementaion.address + ); + expect(implementationAfterUpgrade).to.not.equal(daoV120Implementation); + + expect( + await daoV120Proxy.hasPermission( + daoV120Proxy.address, + signers[0].address, + ethers.utils.id('EXECUTE_PERMISSION'), + EMPTY_DATA + ) + ).to.be.true; + expect( + await daoV120Proxy.hasPermission( + daoV120Proxy.address, + signers[0].address, + ethers.utils.id('ROOT_PERMISSION'), + EMPTY_DATA + ) + ).to.be.true; + }); }); }); From c9c04f87c1b43cb2cf2509000d98be8110bf2ece Mon Sep 17 00:00:00 2001 From: Michael Heuer <20623991+Michael-A-Heuer@users.noreply.github.com> Date: Wed, 10 May 2023 10:57:03 +0200 Subject: [PATCH 067/112] Applied review suggestion Co-authored-by: Rekard0 <5880388+Rekard0@users.noreply.github.com> --- packages/contracts/test/core/dao/dao.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index dc75f7a68..1d06e0ca9 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -311,7 +311,7 @@ describe('DAO', function () { // Create an action array with an normal action and an reentrant action. const actions = [data.succeedAction, reentrantAction]; - // Expect the second, reentrant action to fail. + // Expect the execution of the reentrant action (second action) to fail. await expect(dao.execute(ZERO_BYTES32, actions, 0)) .to.be.revertedWithCustomError(dao, 'ActionFailed') .withArgs(1); From 706de67488707188d62983864c05cbde8505485b Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 10 May 2023 11:36:08 +0200 Subject: [PATCH 068/112] feat: added test checking that execution is still possible after the upgrade --- packages/contracts/test/upgrade/dao.ts | 139 ++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 2 deletions(-) diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 5267db00c..322e0e946 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -11,7 +11,7 @@ import { DAOV120__factory, } from '../../typechain'; -import {daoExampleURI} from '../test-utils/dao'; +import {daoExampleURI, ZERO_BYTES32} from '../test-utils/dao'; import {deployWithProxy} from '../test-utils/proxy'; import {UPGRADE_PERMISSIONS} from '../test-utils/permissions'; import {findEventTopicLog} from '../../utils/event'; @@ -35,7 +35,10 @@ const DUMMY_METADATA = ethers.utils.hexlify( ethers.utils.toUtf8Bytes('0x123456789') ); -describe('DAO Upgrade', function () { +const FORWARDER_1 = `0x${'1'.repeat(40)}`; +const FORWARDER_2 = `0x${'2'.repeat(40)}`; + +describe.only('DAO Upgrade', function () { before(async function () { signers = await ethers.getSigners(); Dao_v1_0_1 = new DAOV101__factory(signers[0]); @@ -136,6 +139,72 @@ describe('DAO Upgrade', function () { ) ).to.be.true; }); + + it('executes actions after the upgrade', async () => { + await daoV101Proxy.grant( + daoV101Proxy.address, + signers[0].address, + ethers.utils.id('EXECUTE_PERMISSION') + ); + + // We use the `setTrustedForwarder` to test execution and must give permission to the DAO (executor) to call it. + await daoV101Proxy.grant( + daoV101Proxy.address, + daoV101Proxy.address, + ethers.utils.id('SET_TRUSTED_FORWARDER_PERMISSION') + ); + + // Create an action to set forwarder1 + const forwarderChangeAction1 = { + to: daoV101Proxy.address, + data: daoV101Proxy.interface.encodeFunctionData('setTrustedForwarder', [ + FORWARDER_1, + ]), + value: 0, + }; + + // Execute and check in the event that the forwarder1 has been set. + await expect( + daoV101Proxy.execute(ZERO_BYTES32, [forwarderChangeAction1], 0) + ) + .to.emit(daoV101Proxy, 'TrustedForwarderSet') + .withArgs(FORWARDER_1); + + // Check that the storage variable now forwarder 1. + expect(await daoV101Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); + + // Upgrade to the new implementation + await daoV101Proxy.upgradeTo(daoCurrentImplementaion.address); + + // Check that the stored implementatio has changed. + const implementationAfterUpgrade = await readImplementationValueFromSlot( + daoV101Proxy.address + ); + expect(implementationAfterUpgrade).to.equal( + daoCurrentImplementaion.address + ); + expect(implementationAfterUpgrade).to.not.equal(daoV101Implementation); + + // Check that the old forwarder is still unchanged. + expect(await daoV101Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); + + // Create an action to change the forwarder to a new address. + const testAction = { + to: daoV101Proxy.address, + data: daoV101Proxy.interface.encodeFunctionData('setTrustedForwarder', [ + FORWARDER_2, + ]), + value: 0, + }; + + // Execute and check in the event that the forwarder1 has been set. + await expect(daoV101Proxy.execute(ZERO_BYTES32, [testAction], 0)) + .to.emit(daoV101Proxy, 'TrustedForwarderSet') + .withArgs(FORWARDER_2); + + // Check that the storage variable is now forwarder 2. + expect(await daoV101Proxy.getTrustedForwarder()).to.equal(FORWARDER_2); + }); }); context(`v1.2.0 to v1.3.0`, function () { @@ -227,5 +296,71 @@ describe('DAO Upgrade', function () { ) ).to.be.true; }); + + it('executes actions after the upgrade', async () => { + await daoV120Proxy.grant( + daoV120Proxy.address, + signers[0].address, + ethers.utils.id('EXECUTE_PERMISSION') + ); + + // We use the `setTrustedForwarder` to test execution and must give permission to the DAO (executor) to call it. + await daoV120Proxy.grant( + daoV120Proxy.address, + daoV120Proxy.address, + ethers.utils.id('SET_TRUSTED_FORWARDER_PERMISSION') + ); + + // Create an action to set forwarder1 + const forwarderChangeAction1 = { + to: daoV120Proxy.address, + data: daoV120Proxy.interface.encodeFunctionData('setTrustedForwarder', [ + FORWARDER_1, + ]), + value: 0, + }; + + // Execute and check in the event that the forwarder1 has been set. + await expect( + daoV120Proxy.execute(ZERO_BYTES32, [forwarderChangeAction1], 0) + ) + .to.emit(daoV120Proxy, 'TrustedForwarderSet') + .withArgs(FORWARDER_1); + + // Check that the storage variable now forwarder 1. + expect(await daoV120Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); + + // Upgrade to the new implementation + await daoV120Proxy.upgradeTo(daoCurrentImplementaion.address); + + // Check that the stored implementatio has changed. + const implementationAfterUpgrade = await readImplementationValueFromSlot( + daoV120Proxy.address + ); + expect(implementationAfterUpgrade).to.equal( + daoCurrentImplementaion.address + ); + expect(implementationAfterUpgrade).to.not.equal(daoV101Implementation); + + // Check that the old forwarder is still unchanged. + expect(await daoV120Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); + + // Create an action to change the forwarder to a new address. + const testAction = { + to: daoV120Proxy.address, + data: daoV120Proxy.interface.encodeFunctionData('setTrustedForwarder', [ + FORWARDER_2, + ]), + value: 0, + }; + + // Execute and check in the event that the forwarder1 has been set. + await expect(daoV120Proxy.execute(ZERO_BYTES32, [testAction], 0)) + .to.emit(daoV120Proxy, 'TrustedForwarderSet') + .withArgs(FORWARDER_2); + + // Check that the storage variable is now forwarder 2. + expect(await daoV120Proxy.getTrustedForwarder()).to.equal(FORWARDER_2); + }); }); }); From 9c80df23124163eca8c8da1788feb5eb226b327c Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 10 May 2023 12:12:26 +0200 Subject: [PATCH 069/112] Improved comments --- packages/contracts/src/core/dao/DAO.sol | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 909b44bc4..438f8ac33 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -60,7 +60,10 @@ contract DAO is /// @notice The internal constant storing the maximal action array length. uint256 internal constant MAX_ACTIONS = 256; + /// @notice The first out of two values to which the `_reentrancyStatus` state variable (used by the `nonReentrant` modifier) can be set inidicating that a function was not entered. uint256 private constant _NOT_ENTERED = 1; + + /// @notice The second out of two values to which the `_reentrancyStatus` state variable (used by the `nonReentrant` modifier) can be set inidicating that a function was entered. uint256 private constant _ENTERED = 2; /// @notice The [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. @@ -73,6 +76,7 @@ contract DAO is string private _daoURI; /// @notice The state variable for the reentrancy guard of the `execute` function. + /// @dev The variable can of value `_NOT_ENTERED = 1` or `_ENTERED = 2` in usage and shoud be initialized to `_NOT_ENTERED`. However, leaving it uninitialized (with a default value of 0) does not pose a risk since the variable will be set to `_NOT_ENTERED` after the first usage. uint256 private _reentrancyStatus; /// @notice Thrown if a call is reentrant. @@ -100,8 +104,8 @@ contract DAO is /// @param daoURI The new URI. event NewURI(string daoURI); - /// @notice A modifier to protect the `execute()` function against reentrancy. - /// @dev If this is used multiple times, private `_beforeNonReentrant()` and `_afterNonReentrant()` functions should be created to prevent code duplication. + /// @notice A modifier to protect a function from calling itself, directly or indirectly (reentrancy). + /// @dev Currently, this modifier is only applied to the `execute()` function. If this is used multiple times, private `_beforeNonReentrant()` and `_afterNonReentrant()` functions should be created to prevent code duplication. modifier nonReentrant() { if (_reentrancyStatus == _ENTERED) { revert ReentrantCall(); From 0cabf6b8d6064d2e4e5bfbd04a3c3506e46d31b1 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 10 May 2023 13:28:48 +0200 Subject: [PATCH 070/112] feat: initialize _rentrancyStatus --- packages/contracts/src/core/dao/DAO.sol | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 438f8ac33..de4538b27 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -136,7 +136,7 @@ contract DAO is address _initialOwner, address _trustedForwarder, string calldata daoURI_ - ) external initializer { + ) external reinitializer(2) { _reentrancyStatus = _NOT_ENTERED; _registerInterface(type(IDAO).interfaceId); @@ -150,6 +150,10 @@ contract DAO is __PermissionManager_init(_initialOwner); } + function initializeFromV1_0_0() external reinitializer(2) { + _reentrancyStatus = _NOT_ENTERED; + } + /// @inheritdoc PermissionManager function isPermissionRestrictedForAnyAddr( bytes32 _permissionId From 9599e3878f2c489d272fabb992b31469d0be1f6e Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 10 May 2023 13:29:08 +0200 Subject: [PATCH 071/112] doc: clarify comments --- packages/contracts/src/core/dao/DAO.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index de4538b27..0bcdbccd7 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -76,7 +76,7 @@ contract DAO is string private _daoURI; /// @notice The state variable for the reentrancy guard of the `execute` function. - /// @dev The variable can of value `_NOT_ENTERED = 1` or `_ENTERED = 2` in usage and shoud be initialized to `_NOT_ENTERED`. However, leaving it uninitialized (with a default value of 0) does not pose a risk since the variable will be set to `_NOT_ENTERED` after the first usage. + /// @dev The variable can of value `_NOT_ENTERED = 1` or `_ENTERED = 2` in usage and shoud be initialized with `_NOT_ENTERED`. uint256 private _reentrancyStatus; /// @notice Thrown if a call is reentrant. @@ -150,6 +150,7 @@ contract DAO is __PermissionManager_init(_initialOwner); } + /// @notice Initializes the DAO after the upgrade from v1.0.0 by setting the newly added reentrancy variable to `_NOT_ENTERED`. function initializeFromV1_0_0() external reinitializer(2) { _reentrancyStatus = _NOT_ENTERED; } From 0dee3366d7be6a1d919e2ddf4663b77bf3c9e37b Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 10 May 2023 16:26:24 +0200 Subject: [PATCH 072/112] fix: change version number --- .../dao/{DAO_v1_0_1.sol => DAO_v1_0_0.sol} | 30 +++++++++---------- .../dao/{IDAO_v1_0_1.sol => IDAO_v1_0_0.sol} | 4 +-- packages/contracts/test/upgrade/dao.ts | 12 ++++---- 3 files changed, 23 insertions(+), 23 deletions(-) rename packages/contracts/src/test/legacy/core/dao/{DAO_v1_0_1.sol => DAO_v1_0_0.sol} (96%) rename packages/contracts/src/test/legacy/core/dao/{IDAO_v1_0_1.sol => IDAO_v1_0_0.sol} (99%) diff --git a/packages/contracts/src/test/legacy/core/dao/DAO_v1_0_1.sol b/packages/contracts/src/test/legacy/core/dao/DAO_v1_0_0.sol similarity index 96% rename from packages/contracts/src/test/legacy/core/dao/DAO_v1_0_1.sol rename to packages/contracts/src/test/legacy/core/dao/DAO_v1_0_0.sol index d871b9b59..86335dd78 100644 --- a/packages/contracts/src/test/legacy/core/dao/DAO_v1_0_1.sol +++ b/packages/contracts/src/test/legacy/core/dao/DAO_v1_0_0.sol @@ -17,18 +17,18 @@ import {PermissionManager} from "../../../../core/permission/PermissionManager.s import {CallbackHandler} from "../../../../core/utils/CallbackHandler.sol"; import {hasBit, flipBit} from "../../../../core/utils/BitMap.sol"; import {IEIP4824} from "../../../../core/dao/IEIP4824.sol"; -import {IDAO_v1_0_1} from "./IDAO_v1_0_1.sol"; +import {IDAO_v1_0_0} from "./IDAO_v1_0_0.sol"; -/// @title DAO v1.0.1 +/// @title DAO v1.0.0 /// @author Aragon Association - 2021-2023 /// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. /// @dev Public API of the Aragon DAO framework. -contract DAO_v1_0_1 is +contract DAO_v1_0_0 is IEIP4824, Initializable, IERC1271, ERC165StorageUpgradeable, - IDAO_v1_0_1, + IDAO_v1_0_0, UUPSUpgradeable, PermissionManager, CallbackHandler @@ -107,7 +107,7 @@ contract DAO_v1_0_1 is address _trustedForwarder, string calldata daoURI_ ) external initializer { - _registerInterface(type(IDAO_v1_0_1).interfaceId); + _registerInterface(type(IDAO_v1_0_0).interfaceId); _registerInterface(type(IERC1271).interfaceId); _registerInterface(type(IEIP4824).interfaceId); _registerTokenInterfaces(); @@ -135,19 +135,19 @@ contract DAO_v1_0_1 is /// @dev The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {} - /// @inheritdoc IDAO_v1_0_1 + /// @inheritdoc IDAO_v1_0_0 function setTrustedForwarder( address _newTrustedForwarder ) external override auth(SET_TRUSTED_FORWARDER_PERMISSION_ID) { _setTrustedForwarder(_newTrustedForwarder); } - /// @inheritdoc IDAO_v1_0_1 + /// @inheritdoc IDAO_v1_0_0 function getTrustedForwarder() external view virtual override returns (address) { return trustedForwarder; } - /// @inheritdoc IDAO_v1_0_1 + /// @inheritdoc IDAO_v1_0_0 function hasPermission( address _where, address _who, @@ -157,14 +157,14 @@ contract DAO_v1_0_1 is return isGranted(_where, _who, _permissionId, _data); } - /// @inheritdoc IDAO_v1_0_1 + /// @inheritdoc IDAO_v1_0_0 function setMetadata( bytes calldata _metadata ) external override auth(SET_METADATA_PERMISSION_ID) { _setMetadata(_metadata); } - /// @inheritdoc IDAO_v1_0_1 + /// @inheritdoc IDAO_v1_0_0 function execute( bytes32 _callId, Action[] calldata _actions, @@ -214,7 +214,7 @@ contract DAO_v1_0_1 is }); } - /// @inheritdoc IDAO_v1_0_1 + /// @inheritdoc IDAO_v1_0_0 function deposit( address _token, uint256 _amount, @@ -235,7 +235,7 @@ contract DAO_v1_0_1 is emit Deposited(msg.sender, _token, _amount, _reference); } - /// @inheritdoc IDAO_v1_0_1 + /// @inheritdoc IDAO_v1_0_0 function setSignatureValidator( address _signatureValidator ) external override auth(SET_SIGNATURE_VALIDATOR_PERMISSION_ID) { @@ -244,11 +244,11 @@ contract DAO_v1_0_1 is emit SignatureValidatorSet({signatureValidator: _signatureValidator}); } - /// @inheritdoc IDAO_v1_0_1 + /// @inheritdoc IDAO_v1_0_0 function isValidSignature( bytes32 _hash, bytes memory _signature - ) external view override(IDAO_v1_0_1, IERC1271) returns (bytes4) { + ) external view override(IDAO_v1_0_0, IERC1271) returns (bytes4) { if (address(signatureValidator) == address(0)) { // Return the invalid magic number return bytes4(0); @@ -305,7 +305,7 @@ contract DAO_v1_0_1 is ); } - /// @inheritdoc IDAO_v1_0_1 + /// @inheritdoc IDAO_v1_0_0 function registerStandardCallback( bytes4 _interfaceId, bytes4 _callbackSelector, diff --git a/packages/contracts/src/test/legacy/core/dao/IDAO_v1_0_1.sol b/packages/contracts/src/test/legacy/core/dao/IDAO_v1_0_0.sol similarity index 99% rename from packages/contracts/src/test/legacy/core/dao/IDAO_v1_0_1.sol rename to packages/contracts/src/test/legacy/core/dao/IDAO_v1_0_0.sol index 7c135603e..f7318726b 100644 --- a/packages/contracts/src/test/legacy/core/dao/IDAO_v1_0_1.sol +++ b/packages/contracts/src/test/legacy/core/dao/IDAO_v1_0_0.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.17; -/// @title IDAO v1.0.1 +/// @title IDAO v1.0.0 /// @author Aragon Association - 2022-2023 /// @notice The interface required for DAOs within the Aragon App DAO framework. -interface IDAO_v1_0_1 { +interface IDAO_v1_0_0 { /// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call. /// @param to The address to call. /// @param value The native token value to be sent with the call. diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 322e0e946..4d4282905 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -18,7 +18,7 @@ import {findEventTopicLog} from '../../utils/event'; import {readImplementationValueFromSlot} from '../../utils/storage'; let signers: SignerWithAddress[]; -let Dao_v1_0_1: DAOV101__factory; +let Dao_v1_0_0: DAOV101__factory; let Dao_v1_2_0: DAOV120__factory; let DaoCurrent: DAO__factory; @@ -41,7 +41,7 @@ const FORWARDER_2 = `0x${'2'.repeat(40)}`; describe.only('DAO Upgrade', function () { before(async function () { signers = await ethers.getSigners(); - Dao_v1_0_1 = new DAOV101__factory(signers[0]); + Dao_v1_0_0 = new DAOV101__factory(signers[0]); Dao_v1_2_0 = new DAOV120__factory(signers[0]); DaoCurrent = new DAO__factory(signers[0]); // 1.3.0 @@ -50,9 +50,9 @@ describe.only('DAO Upgrade', function () { daoCurrentImplementaion = await DaoCurrent.deploy(); }); - context(`v1.0.1 to v1.3.0`, function () { + context(`v1.0.0 to v1.3.0`, function () { beforeEach(async function () { - daoV101Proxy = await deployWithProxy(Dao_v1_0_1); + daoV101Proxy = await deployWithProxy(Dao_v1_0_0); await daoV101Proxy.initialize( DUMMY_METADATA, signers[0].address, @@ -60,7 +60,7 @@ describe.only('DAO Upgrade', function () { daoExampleURI ); - // Store the v1.0.1 implementation + // Store the v1.0.0 implementation daoV101Implementation = await readImplementationValueFromSlot( daoV101Proxy.address ); @@ -90,7 +90,7 @@ describe.only('DAO Upgrade', function () { // Check the emitted implementation. const emittedImplementation = ( - await findEventTopicLog(upgradeTx, Dao_v1_0_1.interface, 'Upgraded') + await findEventTopicLog(upgradeTx, Dao_v1_0_0.interface, 'Upgraded') ).args.implementation; expect(emittedImplementation).to.equal(daoCurrentImplementaion.address); From 4e9e628e87d41458a2bd512ed82abde6cc2b258a Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 10 May 2023 16:57:17 +0200 Subject: [PATCH 073/112] fix: use upgradeToAndCall and correct versions --- packages/contracts/src/core/dao/DAO.sol | 1 + packages/contracts/test/upgrade/dao.ts | 126 ++++++++++++++---------- 2 files changed, 75 insertions(+), 52 deletions(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 0bcdbccd7..6ea23479f 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -123,6 +123,7 @@ contract DAO is } /// @notice Initializes the DAO by + /// - setting the reentrancy status variable to `_NOT_ENTERED` /// - registering the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID /// - setting the trusted forwarder for meta transactions /// - giving the `ROOT_PERMISSION_ID` permission to the initial owner (that should be revoked and transferred to the DAO after setup). diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 4d4282905..319951dfc 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -1,12 +1,13 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; +//import {upgrades} from 'hardhat'; import { DAO, DAO__factory, - DAOV101, - DAOV101__factory, + DAOV100, + DAOV100__factory, DAOV120, DAOV120__factory, } from '../../typechain'; @@ -18,11 +19,11 @@ import {findEventTopicLog} from '../../utils/event'; import {readImplementationValueFromSlot} from '../../utils/storage'; let signers: SignerWithAddress[]; -let Dao_v1_0_0: DAOV101__factory; +let Dao_v1_0_0: DAOV100__factory; let Dao_v1_2_0: DAOV120__factory; let DaoCurrent: DAO__factory; -let daoV101Proxy: DAOV101; +let daoV100Proxy: DAOV100; let daoV120Proxy: DAOV120; let daoV101Implementation: string; @@ -38,22 +39,29 @@ const DUMMY_METADATA = ethers.utils.hexlify( const FORWARDER_1 = `0x${'1'.repeat(40)}`; const FORWARDER_2 = `0x${'2'.repeat(40)}`; +let initializeFromV1_0_0_calldata: string; + describe.only('DAO Upgrade', function () { before(async function () { signers = await ethers.getSigners(); - Dao_v1_0_0 = new DAOV101__factory(signers[0]); + Dao_v1_0_0 = new DAOV100__factory(signers[0]); Dao_v1_2_0 = new DAOV120__factory(signers[0]); DaoCurrent = new DAO__factory(signers[0]); // 1.3.0 + initializeFromV1_0_0_calldata = DaoCurrent.interface.encodeFunctionData( + 'initializeFromV1_0_0', + [] + ); + // Deploy the v1.3.0 implementation daoCurrentImplementaion = await DaoCurrent.deploy(); }); context(`v1.0.0 to v1.3.0`, function () { beforeEach(async function () { - daoV101Proxy = await deployWithProxy(Dao_v1_0_0); - await daoV101Proxy.initialize( + daoV100Proxy = await deployWithProxy(Dao_v1_0_0); + await daoV100Proxy.initialize( DUMMY_METADATA, signers[0].address, ethers.constants.AddressZero, @@ -62,26 +70,27 @@ describe.only('DAO Upgrade', function () { // Store the v1.0.0 implementation daoV101Implementation = await readImplementationValueFromSlot( - daoV101Proxy.address + daoV100Proxy.address ); // Grant the upgrade permission - await daoV101Proxy.grant( - daoV101Proxy.address, + await daoV100Proxy.grant( + daoV100Proxy.address, signers[0].address, UPGRADE_PERMISSIONS.UPGRADE_DAO_PERMISSION_ID ); }); it('does not corrupt the DAO storage', async () => { - // Upgrade to the new implementation - const upgradeTx = await daoV101Proxy.upgradeTo( - daoCurrentImplementaion.address + // Upgrade and call initializeFromV1_0_0 + const upgradeTx = await daoV100Proxy.upgradeToAndCall( + daoCurrentImplementaion.address, + initializeFromV1_0_0_calldata ); // Check the stored implementation. const implementationAfterUpgrade = await readImplementationValueFromSlot( - daoV101Proxy.address + daoV100Proxy.address ); expect(implementationAfterUpgrade).to.equal( daoCurrentImplementaion.address @@ -95,27 +104,30 @@ describe.only('DAO Upgrade', function () { expect(emittedImplementation).to.equal(daoCurrentImplementaion.address); // Check that storage is not corrupted. - expect(await daoV101Proxy.callStatic.daoURI()).to.equal(daoExampleURI); + expect(await daoV100Proxy.callStatic.daoURI()).to.equal(daoExampleURI); }); it('does not corrupt permissions', async () => { - await daoV101Proxy.grant( - daoV101Proxy.address, + await daoV100Proxy.grant( + daoV100Proxy.address, signers[0].address, ethers.utils.id('EXECUTE_PERMISSION') ); - await daoV101Proxy.grant( - daoV101Proxy.address, + await daoV100Proxy.grant( + daoV100Proxy.address, signers[0].address, ethers.utils.id('ROOT_PERMISSION') ); - // Upgrade to the new implementation - await daoV101Proxy.upgradeTo(daoCurrentImplementaion.address); + // Upgrade and call initializeFromV1_0_0 + await daoV100Proxy.upgradeToAndCall( + daoCurrentImplementaion.address, + initializeFromV1_0_0_calldata + ); // Check the stored implementation. const implementationAfterUpgrade = await readImplementationValueFromSlot( - daoV101Proxy.address + daoV100Proxy.address ); expect(implementationAfterUpgrade).to.equal( daoCurrentImplementaion.address @@ -123,16 +135,16 @@ describe.only('DAO Upgrade', function () { expect(implementationAfterUpgrade).to.not.equal(daoV101Implementation); expect( - await daoV101Proxy.hasPermission( - daoV101Proxy.address, + await daoV100Proxy.hasPermission( + daoV100Proxy.address, signers[0].address, ethers.utils.id('EXECUTE_PERMISSION'), EMPTY_DATA ) ).to.be.true; expect( - await daoV101Proxy.hasPermission( - daoV101Proxy.address, + await daoV100Proxy.hasPermission( + daoV100Proxy.address, signers[0].address, ethers.utils.id('ROOT_PERMISSION'), EMPTY_DATA @@ -141,23 +153,23 @@ describe.only('DAO Upgrade', function () { }); it('executes actions after the upgrade', async () => { - await daoV101Proxy.grant( - daoV101Proxy.address, + await daoV100Proxy.grant( + daoV100Proxy.address, signers[0].address, ethers.utils.id('EXECUTE_PERMISSION') ); // We use the `setTrustedForwarder` to test execution and must give permission to the DAO (executor) to call it. - await daoV101Proxy.grant( - daoV101Proxy.address, - daoV101Proxy.address, + await daoV100Proxy.grant( + daoV100Proxy.address, + daoV100Proxy.address, ethers.utils.id('SET_TRUSTED_FORWARDER_PERMISSION') ); // Create an action to set forwarder1 const forwarderChangeAction1 = { - to: daoV101Proxy.address, - data: daoV101Proxy.interface.encodeFunctionData('setTrustedForwarder', [ + to: daoV100Proxy.address, + data: daoV100Proxy.interface.encodeFunctionData('setTrustedForwarder', [ FORWARDER_1, ]), value: 0, @@ -165,20 +177,23 @@ describe.only('DAO Upgrade', function () { // Execute and check in the event that the forwarder1 has been set. await expect( - daoV101Proxy.execute(ZERO_BYTES32, [forwarderChangeAction1], 0) + daoV100Proxy.execute(ZERO_BYTES32, [forwarderChangeAction1], 0) ) - .to.emit(daoV101Proxy, 'TrustedForwarderSet') + .to.emit(daoV100Proxy, 'TrustedForwarderSet') .withArgs(FORWARDER_1); // Check that the storage variable now forwarder 1. - expect(await daoV101Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); + expect(await daoV100Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); - // Upgrade to the new implementation - await daoV101Proxy.upgradeTo(daoCurrentImplementaion.address); + // Upgrade and call initializeFromV1_0_0 + await daoV100Proxy.upgradeToAndCall( + daoCurrentImplementaion.address, + initializeFromV1_0_0_calldata + ); // Check that the stored implementatio has changed. const implementationAfterUpgrade = await readImplementationValueFromSlot( - daoV101Proxy.address + daoV100Proxy.address ); expect(implementationAfterUpgrade).to.equal( daoCurrentImplementaion.address @@ -186,24 +201,24 @@ describe.only('DAO Upgrade', function () { expect(implementationAfterUpgrade).to.not.equal(daoV101Implementation); // Check that the old forwarder is still unchanged. - expect(await daoV101Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); + expect(await daoV100Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); // Create an action to change the forwarder to a new address. const testAction = { - to: daoV101Proxy.address, - data: daoV101Proxy.interface.encodeFunctionData('setTrustedForwarder', [ + to: daoV100Proxy.address, + data: daoV100Proxy.interface.encodeFunctionData('setTrustedForwarder', [ FORWARDER_2, ]), value: 0, }; // Execute and check in the event that the forwarder1 has been set. - await expect(daoV101Proxy.execute(ZERO_BYTES32, [testAction], 0)) - .to.emit(daoV101Proxy, 'TrustedForwarderSet') + await expect(daoV100Proxy.execute(ZERO_BYTES32, [testAction], 0)) + .to.emit(daoV100Proxy, 'TrustedForwarderSet') .withArgs(FORWARDER_2); // Check that the storage variable is now forwarder 2. - expect(await daoV101Proxy.getTrustedForwarder()).to.equal(FORWARDER_2); + expect(await daoV100Proxy.getTrustedForwarder()).to.equal(FORWARDER_2); }); }); @@ -231,9 +246,10 @@ describe.only('DAO Upgrade', function () { }); it('does not corrupt the DAO storage', async () => { - // Upgrade to the new implementation - const upgradeTx = await daoV120Proxy.upgradeTo( - daoCurrentImplementaion.address + // Upgrade and call initializeFromV1_0_0 + const upgradeTx = await daoV120Proxy.upgradeToAndCall( + daoCurrentImplementaion.address, + initializeFromV1_0_0_calldata ); // Check the stored implementation. @@ -267,8 +283,11 @@ describe.only('DAO Upgrade', function () { ethers.utils.id('ROOT_PERMISSION') ); - // Upgrade to the new implementation - await daoV120Proxy.upgradeTo(daoCurrentImplementaion.address); + // Upgrade and call initializeFromV1_0_0 + await daoV120Proxy.upgradeToAndCall( + daoCurrentImplementaion.address, + initializeFromV1_0_0_calldata + ); // Check the stored implementation. const implementationAfterUpgrade = await readImplementationValueFromSlot( @@ -330,8 +349,11 @@ describe.only('DAO Upgrade', function () { // Check that the storage variable now forwarder 1. expect(await daoV120Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); - // Upgrade to the new implementation - await daoV120Proxy.upgradeTo(daoCurrentImplementaion.address); + // Upgrade and call initializeFromV1_0_0 + await daoV120Proxy.upgradeToAndCall( + daoCurrentImplementaion.address, + initializeFromV1_0_0_calldata + ); // Check that the stored implementatio has changed. const implementationAfterUpgrade = await readImplementationValueFromSlot( From 6c814d2240ee07ffffd79c8996aacc041fb8abc2 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 10 May 2023 18:27:03 +0200 Subject: [PATCH 074/112] feat: added initializeUpgradeFrom function and tests --- packages/contracts/src/core/dao/DAO.sol | 19 +++++++++-- packages/contracts/test/core/dao/dao.ts | 27 +++++++++++++++ packages/contracts/test/upgrade/dao.ts | 45 ++++++++++++++----------- 3 files changed, 68 insertions(+), 23 deletions(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 6ea23479f..f8731cf4f 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -95,6 +95,9 @@ contract DAO is /// @notice Thrown if the deposit amount is zero. error ZeroAmount(); + /// @notice Thrown if an upgrade is not supported from a specific protocol version . + error ProtocolVersionUpgradeNotSupported(uint8[3] protocolVersion); + /// @notice Thrown if there is a mismatch between the expected and actually deposited amount of native tokens. /// @param expected The expected native token amount. /// @param actual The actual native token amount deposited. @@ -151,9 +154,19 @@ contract DAO is __PermissionManager_init(_initialOwner); } - /// @notice Initializes the DAO after the upgrade from v1.0.0 by setting the newly added reentrancy variable to `_NOT_ENTERED`. - function initializeFromV1_0_0() external reinitializer(2) { - _reentrancyStatus = _NOT_ENTERED; + /// @notice Initializes the DAO after an upgrade from a previous version. + /// @param previousProtocolVersion The protocol version number of the previous DAO implementation contract this upgrade is transitioning from. + function initializeUpgradeFrom( + uint8[3] calldata previousProtocolVersion + ) external reinitializer(2) { + if (previousProtocolVersion[0] != 1) { + revert ProtocolVersionUpgradeNotSupported(previousProtocolVersion); + } + + // All version before v1.3.0 must initialize the newly added `_reentrancyStatus`. + if (previousProtocolVersion[1] < 3) { + _reentrancyStatus = _NOT_ENTERED; + } } /// @inheritdoc PermissionManager diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 1d06e0ca9..213279a7d 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -41,6 +41,9 @@ const dummyMetadata1 = '0x0001'; const dummyMetadata2 = '0x0002'; const MAX_ACTIONS = 256; +const OZ_INITIALIZED_SLOT_POSITION = 0; +const REENTRANCY_STATUS_SLOT_POSITION = 304; + const EVENTS = { MetadataSet: 'MetadataSet', TrustedForwarderSet: 'TrustedForwarderSet', @@ -190,6 +193,30 @@ describe('DAO', function () { await dao.supportsInterface(TOKEN_INTERFACE_IDS.erc1155InterfaceId) ).to.equal(true); }); + + it('sets OZs `_initialized` at storage slot [0] to 2', async () => { + expect( + ethers.BigNumber.from( + await ethers.provider.getStorageAt( + dao.address, + OZ_INITIALIZED_SLOT_POSITION, + 'latest' + ) + ).toNumber() + ).to.equal(2); + }); + + it('sets the `_reentrancyStatus` at storage slot [304] to `_NOT_ENTERED = 1`', async () => { + expect( + ethers.BigNumber.from( + await ethers.provider.getStorageAt( + dao.address, + REENTRANCY_STATUS_SLOT_POSITION, + 'latest' + ) + ).toNumber() + ).to.equal(1); + }); }); describe('setTrustedForwarder:', async () => { diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 319951dfc..37ca63589 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -39,9 +39,7 @@ const DUMMY_METADATA = ethers.utils.hexlify( const FORWARDER_1 = `0x${'1'.repeat(40)}`; const FORWARDER_2 = `0x${'2'.repeat(40)}`; -let initializeFromV1_0_0_calldata: string; - -describe.only('DAO Upgrade', function () { +describe('DAO Upgrade', function () { before(async function () { signers = await ethers.getSigners(); Dao_v1_0_0 = new DAOV100__factory(signers[0]); @@ -49,11 +47,6 @@ describe.only('DAO Upgrade', function () { DaoCurrent = new DAO__factory(signers[0]); // 1.3.0 - initializeFromV1_0_0_calldata = DaoCurrent.interface.encodeFunctionData( - 'initializeFromV1_0_0', - [] - ); - // Deploy the v1.3.0 implementation daoCurrentImplementaion = await DaoCurrent.deploy(); }); @@ -82,10 +75,12 @@ describe.only('DAO Upgrade', function () { }); it('does not corrupt the DAO storage', async () => { - // Upgrade and call initializeFromV1_0_0 + // Upgrade and call `initializeUpgradeFrom`. const upgradeTx = await daoV100Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - initializeFromV1_0_0_calldata + DaoCurrent.interface.encodeFunctionData('initializeUpgradeFrom', [ + [1, 0, 0], + ]) ); // Check the stored implementation. @@ -119,10 +114,12 @@ describe.only('DAO Upgrade', function () { ethers.utils.id('ROOT_PERMISSION') ); - // Upgrade and call initializeFromV1_0_0 + // Upgrade and call `initializeUpgradeFrom`. await daoV100Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - initializeFromV1_0_0_calldata + DaoCurrent.interface.encodeFunctionData('initializeUpgradeFrom', [ + [1, 0, 0], + ]) ); // Check the stored implementation. @@ -185,10 +182,12 @@ describe.only('DAO Upgrade', function () { // Check that the storage variable now forwarder 1. expect(await daoV100Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); - // Upgrade and call initializeFromV1_0_0 + // Upgrade and call `initializeUpgradeFrom`. await daoV100Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - initializeFromV1_0_0_calldata + DaoCurrent.interface.encodeFunctionData('initializeUpgradeFrom', [ + [1, 0, 0], + ]) ); // Check that the stored implementatio has changed. @@ -246,10 +245,12 @@ describe.only('DAO Upgrade', function () { }); it('does not corrupt the DAO storage', async () => { - // Upgrade and call initializeFromV1_0_0 + // Upgrade and call `initializeUpgradeFrom`. const upgradeTx = await daoV120Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - initializeFromV1_0_0_calldata + DaoCurrent.interface.encodeFunctionData('initializeUpgradeFrom', [ + [1, 2, 0], + ]) ); // Check the stored implementation. @@ -283,10 +284,12 @@ describe.only('DAO Upgrade', function () { ethers.utils.id('ROOT_PERMISSION') ); - // Upgrade and call initializeFromV1_0_0 + // Upgrade and call `initializeUpgradeFrom`. await daoV120Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - initializeFromV1_0_0_calldata + DaoCurrent.interface.encodeFunctionData('initializeUpgradeFrom', [ + [1, 2, 0], + ]) ); // Check the stored implementation. @@ -349,10 +352,12 @@ describe.only('DAO Upgrade', function () { // Check that the storage variable now forwarder 1. expect(await daoV120Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); - // Upgrade and call initializeFromV1_0_0 + // Upgrade and call `initializeUpgradeFrom`. await daoV120Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - initializeFromV1_0_0_calldata + DaoCurrent.interface.encodeFunctionData('initializeUpgradeFrom', [ + [1, 2, 0], + ]) ); // Check that the stored implementatio has changed. From f8ca50c7b4d8593605f43bca630ae5e6cd27681a Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 10 May 2023 18:43:08 +0200 Subject: [PATCH 075/112] feat: improved function and added more tests --- packages/contracts/src/core/dao/DAO.sol | 8 ++-- packages/contracts/test/core/dao/dao.ts | 62 ++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index f8731cf4f..8a27ba52e 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -95,14 +95,14 @@ contract DAO is /// @notice Thrown if the deposit amount is zero. error ZeroAmount(); - /// @notice Thrown if an upgrade is not supported from a specific protocol version . - error ProtocolVersionUpgradeNotSupported(uint8[3] protocolVersion); - /// @notice Thrown if there is a mismatch between the expected and actually deposited amount of native tokens. /// @param expected The expected native token amount. /// @param actual The actual native token amount deposited. error NativeTokenDepositAmountMismatch(uint256 expected, uint256 actual); + /// @notice Thrown if an upgrade is not supported from a specific protocol version . + error ProtocolVersionUpgradeNotSupported(uint8[3] protocolVersion); + /// @notice Emitted when a new DAO URI is set. /// @param daoURI The new URI. event NewURI(string daoURI); @@ -159,7 +159,7 @@ contract DAO is function initializeUpgradeFrom( uint8[3] calldata previousProtocolVersion ) external reinitializer(2) { - if (previousProtocolVersion[0] != 1) { + if (previousProtocolVersion[0] != 1 || previousProtocolVersion[1] >= 3) { revert ProtocolVersionUpgradeNotSupported(previousProtocolVersion); } diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 213279a7d..325c65360 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -9,6 +9,7 @@ import { TestERC721, IERC1271__factory, GasConsumer__factory, + DAO__factory, } from '../../../typechain'; import {findEvent, DAO_EVENTS} from '../../../utils/event'; import {flipBit} from '../../test-utils/bitmap'; @@ -78,13 +79,14 @@ describe('DAO', function () { let signers: SignerWithAddress[]; let ownerAddress: string; let dao: DAO; + let DAO: DAO__factory; beforeEach(async function () { signers = await ethers.getSigners(); ownerAddress = await signers[0].getAddress(); - const DAO = await ethers.getContractFactory('DAO'); - dao = await deployWithProxy(DAO); + DAO = new DAO__factory(signers[0]); + dao = await deployWithProxy(DAO); await dao.initialize( dummyMetadata1, ownerAddress, @@ -199,8 +201,7 @@ describe('DAO', function () { ethers.BigNumber.from( await ethers.provider.getStorageAt( dao.address, - OZ_INITIALIZED_SLOT_POSITION, - 'latest' + OZ_INITIALIZED_SLOT_POSITION ) ).toNumber() ).to.equal(2); @@ -211,14 +212,63 @@ describe('DAO', function () { ethers.BigNumber.from( await ethers.provider.getStorageAt( dao.address, - REENTRANCY_STATUS_SLOT_POSITION, - 'latest' + REENTRANCY_STATUS_SLOT_POSITION ) ).toNumber() ).to.equal(1); }); }); + describe('initializeUpgradeFrom', async () => { + it('reverts if trying to release from a previous major release', async () => { + const testDao = await deployWithProxy(DAO); + + await expect(testDao.initializeUpgradeFrom([0, 1, 0])) + .to.be.revertedWithCustomError( + dao, + 'ProtocolVersionUpgradeNotSupported' + ) + .withArgs([0, 1, 0]); + }); + + it('initializes upgrades for versions < 1.3.0', async () => { + // Create an unitialized DAO. + const uninitializedDao = await deployWithProxy(DAO); + + // Expect the contract to be uninitialized with `_initialized = 0`. + expect( + ethers.BigNumber.from( + await ethers.provider.getStorageAt( + uninitializedDao.address, + OZ_INITIALIZED_SLOT_POSITION + ) + ).toNumber() + ).to.equal(0); + + // Call `initializeUpgradeFrom` with the previous version 1.3.0 which is not supported. + await expect(uninitializedDao.initializeUpgradeFrom([1, 3, 0])) + .to.be.revertedWithCustomError( + dao, + 'ProtocolVersionUpgradeNotSupported' + ) + .withArgs([1, 3, 0]); + + // Call `initializeUpgradeFrom` with the previous version 1.2.0. + await expect(uninitializedDao.initializeUpgradeFrom([1, 2, 0])).to.not.be + .reverted; + + // Expect the contract to be initialized with `_initialized = 2` + expect( + ethers.BigNumber.from( + await ethers.provider.getStorageAt( + uninitializedDao.address, + OZ_INITIALIZED_SLOT_POSITION + ) + ).toNumber() + ).to.equal(2); + }); + }); + describe('setTrustedForwarder:', async () => { it('reverts if the sender lacks the required permissionId', async () => { await dao.revoke( From f8876fd8176c28c1d267bbf61fd21808717e859a Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Thu, 11 May 2023 11:03:58 +0200 Subject: [PATCH 076/112] WIP --- .../src/test/legacy/core/dao/DAO_v1_0_0.sol | 340 --------------- .../src/test/legacy/core/dao/DAO_v1_2_0.sol | 386 ------------------ .../src/test/legacy/core/dao/IDAO_v1_0_0.sol | 136 ------ .../src/test/legacy/core/dao/IDAO_v1_2_0.sol | 138 ------- packages/contracts/test/upgrade/dao.ts | 2 +- 5 files changed, 1 insertion(+), 1001 deletions(-) delete mode 100644 packages/contracts/src/test/legacy/core/dao/DAO_v1_0_0.sol delete mode 100644 packages/contracts/src/test/legacy/core/dao/DAO_v1_2_0.sol delete mode 100644 packages/contracts/src/test/legacy/core/dao/IDAO_v1_0_0.sol delete mode 100644 packages/contracts/src/test/legacy/core/dao/IDAO_v1_2_0.sol diff --git a/packages/contracts/src/test/legacy/core/dao/DAO_v1_0_0.sol b/packages/contracts/src/test/legacy/core/dao/DAO_v1_0_0.sol deleted file mode 100644 index 86335dd78..000000000 --- a/packages/contracts/src/test/legacy/core/dao/DAO_v1_0_0.sol +++ /dev/null @@ -1,340 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity 0.8.17; - -import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165StorageUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; -import "@openzeppelin/contracts/interfaces/IERC1271.sol"; - -import {PermissionManager} from "../../../../core/permission/PermissionManager.sol"; -import {CallbackHandler} from "../../../../core/utils/CallbackHandler.sol"; -import {hasBit, flipBit} from "../../../../core/utils/BitMap.sol"; -import {IEIP4824} from "../../../../core/dao/IEIP4824.sol"; -import {IDAO_v1_0_0} from "./IDAO_v1_0_0.sol"; - -/// @title DAO v1.0.0 -/// @author Aragon Association - 2021-2023 -/// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. -/// @dev Public API of the Aragon DAO framework. -contract DAO_v1_0_0 is - IEIP4824, - Initializable, - IERC1271, - ERC165StorageUpgradeable, - IDAO_v1_0_0, - UUPSUpgradeable, - PermissionManager, - CallbackHandler -{ - using SafeERC20Upgradeable for IERC20Upgradeable; - using AddressUpgradeable for address; - - /// @notice The ID of the permission required to call the `execute` function. - bytes32 public constant EXECUTE_PERMISSION_ID = keccak256("EXECUTE_PERMISSION"); - - /// @notice The ID of the permission required to call the `_authorizeUpgrade` function. - bytes32 public constant UPGRADE_DAO_PERMISSION_ID = keccak256("UPGRADE_DAO_PERMISSION"); - - /// @notice The ID of the permission required to call the `setMetadata` function. - bytes32 public constant SET_METADATA_PERMISSION_ID = keccak256("SET_METADATA_PERMISSION"); - - /// @notice The ID of the permission required to call the `setTrustedForwarder` function. - bytes32 public constant SET_TRUSTED_FORWARDER_PERMISSION_ID = - keccak256("SET_TRUSTED_FORWARDER_PERMISSION"); - - /// @notice The ID of the permission required to call the `setSignatureValidator` function. - bytes32 public constant SET_SIGNATURE_VALIDATOR_PERMISSION_ID = - keccak256("SET_SIGNATURE_VALIDATOR_PERMISSION"); - - /// @notice The ID of the permission required to call the `registerStandardCallback` function. - bytes32 public constant REGISTER_STANDARD_CALLBACK_PERMISSION_ID = - keccak256("REGISTER_STANDARD_CALLBACK_PERMISSION"); - - /// @notice The internal constant storing the maximal action array length. - uint256 internal constant MAX_ACTIONS = 256; - - /// @notice The [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. - IERC1271 public signatureValidator; - - /// @notice The address of the trusted forwarder verifying meta transactions. - address private trustedForwarder; - - /// @notice The [EIP-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO uri. - string private _daoURI; - - /// @notice Thrown if the action array length is larger than `MAX_ACTIONS`. - error TooManyActions(); - - /// @notice Thrown if action execution has failed. - /// @param index The index of the action in the action array that failed. - error ActionFailed(uint256 index); - - /// @notice Thrown if the deposit amount is zero. - error ZeroAmount(); - - /// @notice Thrown if there is a mismatch between the expected and actually deposited amount of native tokens. - /// @param expected The expected native token amount. - /// @param actual The actual native token amount deposited. - error NativeTokenDepositAmountMismatch(uint256 expected, uint256 actual); - - /// @notice Emitted when a new DAO uri is set. - /// @param daoURI The new uri. - event NewURI(string daoURI); - - /// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized. - constructor() { - _disableInitializers(); - } - - /// @notice Initializes the DAO by - /// - registering the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID - /// - setting the trusted forwarder for meta transactions - /// - giving the `ROOT_PERMISSION_ID` permission to the initial owner (that should be revoked and transferred to the DAO after setup). - /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). - /// @param _metadata IPFS hash that points to all the metadata (logo, description, tags, etc.) of a DAO. - /// @param _initialOwner The initial owner of the DAO having the `ROOT_PERMISSION_ID` permission. - /// @param _trustedForwarder The trusted forwarder responsible for verifying meta transactions. - function initialize( - bytes calldata _metadata, - address _initialOwner, - address _trustedForwarder, - string calldata daoURI_ - ) external initializer { - _registerInterface(type(IDAO_v1_0_0).interfaceId); - _registerInterface(type(IERC1271).interfaceId); - _registerInterface(type(IEIP4824).interfaceId); - _registerTokenInterfaces(); - - _setMetadata(_metadata); - _setTrustedForwarder(_trustedForwarder); - _setDaoURI(daoURI_); - __PermissionManager_init(_initialOwner); - } - - /// @inheritdoc PermissionManager - function isPermissionRestrictedForAnyAddr( - bytes32 _permissionId - ) internal pure override returns (bool) { - return - _permissionId == EXECUTE_PERMISSION_ID || - _permissionId == UPGRADE_DAO_PERMISSION_ID || - _permissionId == SET_METADATA_PERMISSION_ID || - _permissionId == SET_TRUSTED_FORWARDER_PERMISSION_ID || - _permissionId == SET_SIGNATURE_VALIDATOR_PERMISSION_ID || - _permissionId == REGISTER_STANDARD_CALLBACK_PERMISSION_ID; - } - - /// @notice Internal method authorizing the upgrade of the contract via the [upgradeabilty mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). - /// @dev The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. - function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {} - - /// @inheritdoc IDAO_v1_0_0 - function setTrustedForwarder( - address _newTrustedForwarder - ) external override auth(SET_TRUSTED_FORWARDER_PERMISSION_ID) { - _setTrustedForwarder(_newTrustedForwarder); - } - - /// @inheritdoc IDAO_v1_0_0 - function getTrustedForwarder() external view virtual override returns (address) { - return trustedForwarder; - } - - /// @inheritdoc IDAO_v1_0_0 - function hasPermission( - address _where, - address _who, - bytes32 _permissionId, - bytes memory _data - ) external view override returns (bool) { - return isGranted(_where, _who, _permissionId, _data); - } - - /// @inheritdoc IDAO_v1_0_0 - function setMetadata( - bytes calldata _metadata - ) external override auth(SET_METADATA_PERMISSION_ID) { - _setMetadata(_metadata); - } - - /// @inheritdoc IDAO_v1_0_0 - function execute( - bytes32 _callId, - Action[] calldata _actions, - uint256 _allowFailureMap - ) - external - override - auth(EXECUTE_PERMISSION_ID) - returns (bytes[] memory execResults, uint256 failureMap) - { - if (_actions.length > MAX_ACTIONS) { - revert TooManyActions(); - } - - execResults = new bytes[](_actions.length); - - for (uint256 i = 0; i < _actions.length; ) { - address to = _actions[i].to; - (bool success, bytes memory response) = to.call{value: _actions[i].value}( - _actions[i].data - ); - - if (!success) { - // If the call failed and wasn't allowed in allowFailureMap, revert. - if (!hasBit(_allowFailureMap, uint8(i))) { - revert ActionFailed(i); - } - - // If the call failed, but was allowed in allowFailureMap, store that - // this specific action has actually failed. - failureMap = flipBit(failureMap, uint8(i)); - } - - execResults[i] = response; - - unchecked { - ++i; - } - } - - emit Executed({ - actor: msg.sender, - callId: _callId, - actions: _actions, - failureMap: failureMap, - execResults: execResults - }); - } - - /// @inheritdoc IDAO_v1_0_0 - function deposit( - address _token, - uint256 _amount, - string calldata _reference - ) external payable override { - if (_amount == 0) revert ZeroAmount(); - - if (_token == address(0)) { - if (msg.value != _amount) - revert NativeTokenDepositAmountMismatch({expected: _amount, actual: msg.value}); - } else { - if (msg.value != 0) - revert NativeTokenDepositAmountMismatch({expected: 0, actual: msg.value}); - - IERC20Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _amount); - } - - emit Deposited(msg.sender, _token, _amount, _reference); - } - - /// @inheritdoc IDAO_v1_0_0 - function setSignatureValidator( - address _signatureValidator - ) external override auth(SET_SIGNATURE_VALIDATOR_PERMISSION_ID) { - signatureValidator = IERC1271(_signatureValidator); - - emit SignatureValidatorSet({signatureValidator: _signatureValidator}); - } - - /// @inheritdoc IDAO_v1_0_0 - function isValidSignature( - bytes32 _hash, - bytes memory _signature - ) external view override(IDAO_v1_0_0, IERC1271) returns (bytes4) { - if (address(signatureValidator) == address(0)) { - // Return the invalid magic number - return bytes4(0); - } - // Forward the call to the set signature validator contract - return signatureValidator.isValidSignature(_hash, _signature); - } - - /// @notice Emits the `NativeTokenDeposited` event to track native token deposits that weren't made via the deposit method. - /// @dev This call is bound by the gas limitations for `send`/`transfer` calls introduced by EIP-2929. - /// Gas cost increases in future hard forks might break this function. As an alternative, EIP-2930-type transactions using access lists can be employed. - receive() external payable { - emit NativeTokenDeposited(msg.sender, msg.value); - } - - /// @notice Fallback to handle future versions of the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) standard. - /// @param _input An alias being equivalent to `msg.data`. This feature of the fallback function was introduced with the [solidity compiler version 0.7.6](https://github.com/ethereum/solidity/releases/tag/v0.7.6) - /// @return The magic number registered for the function selector triggering the fallback. - fallback(bytes calldata _input) external returns (bytes memory) { - bytes4 magicNumber = _handleCallback(msg.sig, _input); - return abi.encode(magicNumber); - } - - /// @notice Emits the MetadataSet event if new metadata is set. - /// @param _metadata Hash of the IPFS metadata object. - function _setMetadata(bytes calldata _metadata) internal { - emit MetadataSet(_metadata); - } - - /// @notice Sets the trusted forwarder on the DAO and emits the associated event. - /// @param _trustedForwarder The trusted forwarder address. - function _setTrustedForwarder(address _trustedForwarder) internal { - trustedForwarder = _trustedForwarder; - - emit TrustedForwarderSet(_trustedForwarder); - } - - /// @notice Registers the ERC721/ERC1155 interfaces and callbacks. - function _registerTokenInterfaces() private { - _registerInterface(type(IERC721ReceiverUpgradeable).interfaceId); - _registerInterface(type(IERC1155ReceiverUpgradeable).interfaceId); - - _registerCallback( - IERC721ReceiverUpgradeable.onERC721Received.selector, - IERC721ReceiverUpgradeable.onERC721Received.selector - ); - _registerCallback( - IERC1155ReceiverUpgradeable.onERC1155Received.selector, - IERC1155ReceiverUpgradeable.onERC1155Received.selector - ); - _registerCallback( - IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector, - IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector - ); - } - - /// @inheritdoc IDAO_v1_0_0 - function registerStandardCallback( - bytes4 _interfaceId, - bytes4 _callbackSelector, - bytes4 _magicNumber - ) external override auth(REGISTER_STANDARD_CALLBACK_PERMISSION_ID) { - _registerInterface(_interfaceId); - _registerCallback(_callbackSelector, _magicNumber); - emit StandardCallbackRegistered(_interfaceId, _callbackSelector, _magicNumber); - } - - /// @inheritdoc IEIP4824 - function daoURI() external view returns (string memory) { - return _daoURI; - } - - /// @notice Updates the set DAO uri to a new value. - /// @param newDaoURI The new DAO uri to be set. - function setDaoURI(string calldata newDaoURI) external auth(SET_METADATA_PERMISSION_ID) { - _setDaoURI(newDaoURI); - } - - /// @notice Sets the new DAO uri and emits the associated event. - /// @param daoURI_ The new DAO uri. - function _setDaoURI(string calldata daoURI_) internal { - _daoURI = daoURI_; - - emit NewURI(daoURI_); - } - - /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). - uint256[47] private __gap; -} diff --git a/packages/contracts/src/test/legacy/core/dao/DAO_v1_2_0.sol b/packages/contracts/src/test/legacy/core/dao/DAO_v1_2_0.sol deleted file mode 100644 index 5adcbbe10..000000000 --- a/packages/contracts/src/test/legacy/core/dao/DAO_v1_2_0.sol +++ /dev/null @@ -1,386 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity 0.8.17; - -import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165StorageUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; -import "@openzeppelin/contracts/interfaces/IERC1271.sol"; - -import {PermissionManager} from "../../../../core/permission/PermissionManager.sol"; -import {CallbackHandler} from "../../../../core/utils/CallbackHandler.sol"; -import {hasBit, flipBit} from "../../../../core/utils/BitMap.sol"; -import {IEIP4824} from "../../../../core/dao/IEIP4824.sol"; -import {IDAO_v1_2_0} from "./IDAO_v1_2_0.sol"; - -/// @title DAO v1.2.0 -/// @author Aragon Association - 2021-2023 -/// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. -/// @dev Public API of the Aragon DAO framework. -contract DAO_v1_2_0 is - IEIP4824, - Initializable, - IERC1271, - ERC165StorageUpgradeable, - IDAO_v1_2_0, - UUPSUpgradeable, - PermissionManager, - CallbackHandler -{ - using SafeERC20Upgradeable for IERC20Upgradeable; - using AddressUpgradeable for address; - - /// @notice The ID of the permission required to call the `execute` function. - bytes32 public constant EXECUTE_PERMISSION_ID = keccak256("EXECUTE_PERMISSION"); - - /// @notice The ID of the permission required to call the `_authorizeUpgrade` function. - bytes32 public constant UPGRADE_DAO_PERMISSION_ID = keccak256("UPGRADE_DAO_PERMISSION"); - - /// @notice The ID of the permission required to call the `setMetadata` function. - bytes32 public constant SET_METADATA_PERMISSION_ID = keccak256("SET_METADATA_PERMISSION"); - - /// @notice The ID of the permission required to call the `setTrustedForwarder` function. - bytes32 public constant SET_TRUSTED_FORWARDER_PERMISSION_ID = - keccak256("SET_TRUSTED_FORWARDER_PERMISSION"); - - /// @notice The ID of the permission required to call the `setSignatureValidator` function. - bytes32 public constant SET_SIGNATURE_VALIDATOR_PERMISSION_ID = - keccak256("SET_SIGNATURE_VALIDATOR_PERMISSION"); - - /// @notice The ID of the permission required to call the `registerStandardCallback` function. - bytes32 public constant REGISTER_STANDARD_CALLBACK_PERMISSION_ID = - keccak256("REGISTER_STANDARD_CALLBACK_PERMISSION"); - - /// @notice The internal constant storing the maximal action array length. - uint256 internal constant MAX_ACTIONS = 256; - - uint256 private constant _NOT_ENTERED = 1; - uint256 private constant _ENTERED = 2; - - /// @notice The [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. - IERC1271 public signatureValidator; - - /// @notice The address of the trusted forwarder verifying meta transactions. - address private trustedForwarder; - - /// @notice The [EIP-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO URI. - string private _daoURI; - - /// @notice The state variable for the reentrancy guard of the `execute` function. - uint256 private _reentrancyStatus; - - /// @notice Thrown if a call is reentrant. - error ReentrantCall(); - - /// @notice Thrown if the action array length is larger than `MAX_ACTIONS`. - error TooManyActions(); - - /// @notice Thrown if action execution has failed. - /// @param index The index of the action in the action array that failed. - error ActionFailed(uint256 index); - - /// @notice Thrown if an action has insufficent gas left. - error InsufficientGas(); - - /// @notice Thrown if the deposit amount is zero. - error ZeroAmount(); - - /// @notice Thrown if there is a mismatch between the expected and actually deposited amount of native tokens. - /// @param expected The expected native token amount. - /// @param actual The actual native token amount deposited. - error NativeTokenDepositAmountMismatch(uint256 expected, uint256 actual); - - /// @notice Emitted when a new DAO URI is set. - /// @param daoURI The new URI. - event NewURI(string daoURI); - - /// @notice A modifier to protect the `execute()` function against reentrancy. - /// @dev If this is used multiple times, private `_beforeNonReentrant()` and `_afterNonReentrant()` functions should be created to prevent code duplication. - modifier nonReentrant() { - if (_reentrancyStatus == _ENTERED) { - revert ReentrantCall(); - } - _reentrancyStatus = _ENTERED; - - _; - - _reentrancyStatus = _NOT_ENTERED; - } - - /// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized. - constructor() { - _disableInitializers(); - } - - /// @notice Initializes the DAO by - /// - registering the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID - /// - setting the trusted forwarder for meta transactions - /// - giving the `ROOT_PERMISSION_ID` permission to the initial owner (that should be revoked and transferred to the DAO after setup). - /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). - /// @param _metadata IPFS hash that points to all the metadata (logo, description, tags, etc.) of a DAO. - /// @param _initialOwner The initial owner of the DAO having the `ROOT_PERMISSION_ID` permission. - /// @param _trustedForwarder The trusted forwarder responsible for verifying meta transactions. - /// @param daoURI_ The DAO URI required to support [ERC-4824](https://eips.ethereum.org/EIPS/eip-4824). - function initialize( - bytes calldata _metadata, - address _initialOwner, - address _trustedForwarder, - string calldata daoURI_ - ) external initializer { - _reentrancyStatus = _NOT_ENTERED; - - _registerInterface(type(IDAO_v1_2_0).interfaceId); - _registerInterface(type(IERC1271).interfaceId); - _registerInterface(type(IEIP4824).interfaceId); - _registerTokenInterfaces(); - - _setMetadata(_metadata); - _setTrustedForwarder(_trustedForwarder); - _setDaoURI(daoURI_); - __PermissionManager_init(_initialOwner); - } - - /// @inheritdoc PermissionManager - function isPermissionRestrictedForAnyAddr( - bytes32 _permissionId - ) internal pure override returns (bool) { - return - _permissionId == EXECUTE_PERMISSION_ID || - _permissionId == UPGRADE_DAO_PERMISSION_ID || - _permissionId == SET_METADATA_PERMISSION_ID || - _permissionId == SET_TRUSTED_FORWARDER_PERMISSION_ID || - _permissionId == SET_SIGNATURE_VALIDATOR_PERMISSION_ID || - _permissionId == REGISTER_STANDARD_CALLBACK_PERMISSION_ID; - } - - /// @notice Internal method authorizing the upgrade of the contract via the [upgradeability mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). - /// @dev The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. - function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {} - - /// @inheritdoc IDAO_v1_2_0 - function setTrustedForwarder( - address _newTrustedForwarder - ) external override auth(SET_TRUSTED_FORWARDER_PERMISSION_ID) { - _setTrustedForwarder(_newTrustedForwarder); - } - - /// @inheritdoc IDAO_v1_2_0 - function getTrustedForwarder() external view virtual override returns (address) { - return trustedForwarder; - } - - /// @inheritdoc IDAO_v1_2_0 - function hasPermission( - address _where, - address _who, - bytes32 _permissionId, - bytes memory _data - ) external view override returns (bool) { - return isGranted(_where, _who, _permissionId, _data); - } - - /// @inheritdoc IDAO_v1_2_0 - function setMetadata( - bytes calldata _metadata - ) external override auth(SET_METADATA_PERMISSION_ID) { - _setMetadata(_metadata); - } - - /// @inheritdoc IDAO_v1_2_0 - function execute( - bytes32 _callId, - Action[] calldata _actions, - uint256 _allowFailureMap - ) - external - override - nonReentrant - auth(EXECUTE_PERMISSION_ID) - returns (bytes[] memory execResults, uint256 failureMap) - { - // Check that the action array length is within bounds. - if (_actions.length > MAX_ACTIONS) { - revert TooManyActions(); - } - - execResults = new bytes[](_actions.length); - - uint256 gasBefore; - uint256 gasAfter; - - for (uint256 i = 0; i < _actions.length; ) { - gasBefore = gasleft(); - - (bool success, bytes memory result) = _actions[i].to.call{value: _actions[i].value}( - _actions[i].data - ); - gasAfter = gasleft(); - - // Check if failure is allowed - if (!hasBit(_allowFailureMap, uint8(i))) { - // Check if the call failed. - if (!success) { - revert ActionFailed(i); - } - } else { - // Check if the call failed. - if (!success) { - // Make sure that the action call did not fail because 63/64 of `gasleft()` was insufficient to execute the external call `.to.call` (see [ERC-150](https://eips.ethereum.org/EIPS/eip-150)). - // In specific scenarios, i.e. proposal execution where the last action in the action array is allowed to fail, the account calling `execute` could force-fail this action by setting a gas limit - // where 63/64 is insufficient causing the `.to.call` to fail, but where the remaining 1/64 gas are sufficient to successfully finish the `execute` call. - if (gasAfter < gasBefore / 64) { - revert InsufficientGas(); - } - - // Store that this action failed. - failureMap = flipBit(failureMap, uint8(i)); - } - } - - execResults[i] = result; - - unchecked { - ++i; - } - } - - emit Executed({ - actor: msg.sender, - callId: _callId, - actions: _actions, - allowFailureMap: _allowFailureMap, - failureMap: failureMap, - execResults: execResults - }); - } - - /// @inheritdoc IDAO_v1_2_0 - function deposit( - address _token, - uint256 _amount, - string calldata _reference - ) external payable override { - if (_amount == 0) revert ZeroAmount(); - - if (_token == address(0)) { - if (msg.value != _amount) - revert NativeTokenDepositAmountMismatch({expected: _amount, actual: msg.value}); - } else { - if (msg.value != 0) - revert NativeTokenDepositAmountMismatch({expected: 0, actual: msg.value}); - - IERC20Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _amount); - } - - emit Deposited(msg.sender, _token, _amount, _reference); - } - - /// @inheritdoc IDAO_v1_2_0 - function setSignatureValidator( - address _signatureValidator - ) external override auth(SET_SIGNATURE_VALIDATOR_PERMISSION_ID) { - signatureValidator = IERC1271(_signatureValidator); - - emit SignatureValidatorSet({signatureValidator: _signatureValidator}); - } - - /// @inheritdoc IDAO_v1_2_0 - function isValidSignature( - bytes32 _hash, - bytes memory _signature - ) external view override(IDAO_v1_2_0, IERC1271) returns (bytes4) { - if (address(signatureValidator) == address(0)) { - // Return the invalid magic number - return bytes4(0); - } - // Forward the call to the set signature validator contract - return signatureValidator.isValidSignature(_hash, _signature); - } - - /// @notice Emits the `NativeTokenDeposited` event to track native token deposits that weren't made via the deposit method. - /// @dev This call is bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929). - /// Gas cost increases in future hard forks might break this function. As an alternative, [ERC-2930](https://eips.ethereum.org/EIPS/eip-2930)-type transactions using access lists can be employed. - receive() external payable { - emit NativeTokenDeposited(msg.sender, msg.value); - } - - /// @notice Fallback to handle future versions of the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) standard. - /// @param _input An alias being equivalent to `msg.data`. This feature of the fallback function was introduced with the [solidity compiler version 0.7.6](https://github.com/ethereum/solidity/releases/tag/v0.7.6) - /// @return The magic number registered for the function selector triggering the fallback. - fallback(bytes calldata _input) external returns (bytes memory) { - bytes4 magicNumber = _handleCallback(msg.sig, _input); - return abi.encode(magicNumber); - } - - /// @notice Emits the MetadataSet event if new metadata is set. - /// @param _metadata Hash of the IPFS metadata object. - function _setMetadata(bytes calldata _metadata) internal { - emit MetadataSet(_metadata); - } - - /// @notice Sets the trusted forwarder on the DAO and emits the associated event. - /// @param _trustedForwarder The trusted forwarder address. - function _setTrustedForwarder(address _trustedForwarder) internal { - trustedForwarder = _trustedForwarder; - - emit TrustedForwarderSet(_trustedForwarder); - } - - /// @notice Registers the [ERC-721](https://eips.ethereum.org/EIPS/eip-721) and [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) interfaces and callbacks. - function _registerTokenInterfaces() private { - _registerInterface(type(IERC721ReceiverUpgradeable).interfaceId); - _registerInterface(type(IERC1155ReceiverUpgradeable).interfaceId); - - _registerCallback( - IERC721ReceiverUpgradeable.onERC721Received.selector, - IERC721ReceiverUpgradeable.onERC721Received.selector - ); - _registerCallback( - IERC1155ReceiverUpgradeable.onERC1155Received.selector, - IERC1155ReceiverUpgradeable.onERC1155Received.selector - ); - _registerCallback( - IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector, - IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector - ); - } - - /// @inheritdoc IDAO_v1_2_0 - function registerStandardCallback( - bytes4 _interfaceId, - bytes4 _callbackSelector, - bytes4 _magicNumber - ) external override auth(REGISTER_STANDARD_CALLBACK_PERMISSION_ID) { - _registerInterface(_interfaceId); - _registerCallback(_callbackSelector, _magicNumber); - emit StandardCallbackRegistered(_interfaceId, _callbackSelector, _magicNumber); - } - - /// @inheritdoc IEIP4824 - function daoURI() external view returns (string memory) { - return _daoURI; - } - - /// @notice Updates the set DAO URI to a new value. - /// @param newDaoURI The new DAO URI to be set. - function setDaoURI(string calldata newDaoURI) external auth(SET_METADATA_PERMISSION_ID) { - _setDaoURI(newDaoURI); - } - - /// @notice Sets the new [ERC-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO URI and emits the associated event. - /// @param daoURI_ The new DAO URI. - function _setDaoURI(string calldata daoURI_) internal { - _daoURI = daoURI_; - - emit NewURI(daoURI_); - } - - /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). - uint256[46] private __gap; -} diff --git a/packages/contracts/src/test/legacy/core/dao/IDAO_v1_0_0.sol b/packages/contracts/src/test/legacy/core/dao/IDAO_v1_0_0.sol deleted file mode 100644 index f7318726b..000000000 --- a/packages/contracts/src/test/legacy/core/dao/IDAO_v1_0_0.sol +++ /dev/null @@ -1,136 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity 0.8.17; - -/// @title IDAO v1.0.0 -/// @author Aragon Association - 2022-2023 -/// @notice The interface required for DAOs within the Aragon App DAO framework. -interface IDAO_v1_0_0 { - /// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call. - /// @param to The address to call. - /// @param value The native token value to be sent with the call. - /// @param data The bytes-encoded function selector and calldata for the call. - struct Action { - address to; - uint256 value; - bytes data; - } - - /// @notice Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process. - /// @param _where The address of the contract. - /// @param _who The address of a EOA or contract to give the permissions. - /// @param _permissionId The permission identifier. - /// @param _data The optional data passed to the `PermissionCondition` registered. - /// @return Returns true if the address has permission, false if not. - function hasPermission( - address _where, - address _who, - bytes32 _permissionId, - bytes memory _data - ) external view returns (bool); - - /// @notice Updates the DAO metadata (e.g., an IPFS hash). - /// @param _metadata The IPFS hash of the new metadata object. - function setMetadata(bytes calldata _metadata) external; - - /// @notice Emitted when the DAO metadata is updated. - /// @param metadata The IPFS hash of the new metadata object. - event MetadataSet(bytes metadata); - - /// @notice Executes a list of actions. If no failure map is provided, one failing action results in the entire excution to be reverted. If a non-zero failure map is provided, allowed actions can fail without the remaining actions being reverted. - /// @param _callId The ID of the call. The definition of the value of `callId` is up to the calling contract and can be used, e.g., as a nonce. - /// @param _actions The array of actions. - /// @param _allowFailureMap A bitmap allowing execution to succeed, even if individual actions might revert. If the bit at index `i` is 1, the execution succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. - /// @return The array of results obtained from the executed actions in `bytes`. - /// @return The constructed failureMap which contains which actions have actually failed. - function execute( - bytes32 _callId, - Action[] memory _actions, - uint256 _allowFailureMap - ) external returns (bytes[] memory, uint256); - - /// @notice Emitted when a proposal is executed. - /// @param actor The address of the caller. - /// @param callId The ID of the call. - /// @param actions The array of actions executed. - /// @param failureMap The failure map encoding which actions have failed. - /// @param execResults The array with the results of the executed actions. - /// @dev The value of `callId` is defined by the component/contract calling the execute function. A `Plugin` implementation can use it, for example, as a nonce. - event Executed( - address indexed actor, - bytes32 callId, - Action[] actions, - uint256 failureMap, - bytes[] execResults - ); - - /// @notice Emitted when a standard callback is registered. - /// @param interfaceId The ID of the interface. - /// @param callbackSelector The selector of the callback function. - /// @param magicNumber The magic number to be registered for the callback function selector. - event StandardCallbackRegistered( - bytes4 interfaceId, - bytes4 callbackSelector, - bytes4 magicNumber - ); - - /// @notice Deposits (native) tokens to the DAO contract with a reference string. - /// @param _token The address of the token or address(0) in case of the native token. - /// @param _amount The amount of tokens to deposit. - /// @param _reference The reference describing the deposit reason. - function deposit(address _token, uint256 _amount, string calldata _reference) external payable; - - /// @notice Emitted when a token deposit has been made to the DAO. - /// @param sender The address of the sender. - /// @param token The address of the deposited token. - /// @param amount The amount of tokens deposited. - /// @param _reference The reference describing the deposit reason. - event Deposited( - address indexed sender, - address indexed token, - uint256 amount, - string _reference - ); - - /// @notice Emitted when a native token deposit has been made to the DAO. - /// @dev This event is intended to be emitted in the `receive` function and is therefore bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929). - /// @param sender The address of the sender. - /// @param amount The amount of native tokens deposited. - event NativeTokenDeposited(address sender, uint256 amount); - - /// @notice Setter for the trusted forwarder verifying the meta transaction. - /// @param _trustedForwarder The trusted forwarder address. - function setTrustedForwarder(address _trustedForwarder) external; - - /// @notice Getter for the trusted forwarder verifying the meta transaction. - /// @return The trusted forwarder address. - function getTrustedForwarder() external view returns (address); - - /// @notice Emitted when a new TrustedForwarder is set on the DAO. - /// @param forwarder the new forwarder address. - event TrustedForwarderSet(address forwarder); - - /// @notice Setter for the [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. - /// @param _signatureValidator The address of the signature validator. - function setSignatureValidator(address _signatureValidator) external; - - /// @notice Emitted when the signature validator address is updated. - /// @param signatureValidator The address of the signature validator. - event SignatureValidatorSet(address signatureValidator); - - /// @notice Checks whether a signature is valid for the provided hash by forwarding the call to the set [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. - /// @param _hash The hash of the data to be signed. - /// @param _signature The signature byte array associated with `_hash`. - /// @return Returns the `bytes4` magic value `0x1626ba7e` if the signature is valid. - function isValidSignature(bytes32 _hash, bytes memory _signature) external returns (bytes4); - - /// @notice Registers an ERC standard having a callback by registering its [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID and callback function signature. - /// @param _interfaceId The ID of the interface. - /// @param _callbackSelector The selector of the callback function. - /// @param _magicNumber The magic number to be registered for the function signature. - function registerStandardCallback( - bytes4 _interfaceId, - bytes4 _callbackSelector, - bytes4 _magicNumber - ) external; -} diff --git a/packages/contracts/src/test/legacy/core/dao/IDAO_v1_2_0.sol b/packages/contracts/src/test/legacy/core/dao/IDAO_v1_2_0.sol deleted file mode 100644 index 6085c598e..000000000 --- a/packages/contracts/src/test/legacy/core/dao/IDAO_v1_2_0.sol +++ /dev/null @@ -1,138 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity ^0.8.8; - -/// @title IDAO v1.2.0 -/// @author Aragon Association - 2022-2023 -/// @notice The interface required for DAOs within the Aragon App DAO framework. -interface IDAO_v1_2_0 { - /// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call. - /// @param to The address to call. - /// @param value The native token value to be sent with the call. - /// @param data The bytes-encoded function selector and calldata for the call. - struct Action { - address to; - uint256 value; - bytes data; - } - - /// @notice Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process. - /// @param _where The address of the contract. - /// @param _who The address of a EOA or contract to give the permissions. - /// @param _permissionId The permission identifier. - /// @param _data The optional data passed to the `PermissionCondition` registered. - /// @return Returns true if the address has permission, false if not. - function hasPermission( - address _where, - address _who, - bytes32 _permissionId, - bytes memory _data - ) external view returns (bool); - - /// @notice Updates the DAO metadata (e.g., an IPFS hash). - /// @param _metadata The IPFS hash of the new metadata object. - function setMetadata(bytes calldata _metadata) external; - - /// @notice Emitted when the DAO metadata is updated. - /// @param metadata The IPFS hash of the new metadata object. - event MetadataSet(bytes metadata); - - /// @notice Executes a list of actions. If a zero allow-failure map is provided, a failing action reverts the entire execution. If a non-zero allow-failure map is provided, allowed actions can fail without the entire call being reverted. - /// @param _callId The ID of the call. The definition of the value of `callId` is up to the calling contract and can be used, e.g., as a nonce. - /// @param _actions The array of actions. - /// @param _allowFailureMap A bitmap allowing execution to succeed, even if individual actions might revert. If the bit at index `i` is 1, the execution succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. - /// @return The array of results obtained from the executed actions in `bytes`. - /// @return The resulting failure map containing the actions have actually failed. - function execute( - bytes32 _callId, - Action[] memory _actions, - uint256 _allowFailureMap - ) external returns (bytes[] memory, uint256); - - /// @notice Emitted when a proposal is executed. - /// @param actor The address of the caller. - /// @param callId The ID of the call. - /// @param actions The array of actions executed. - /// @param allowFailureMap The allow failure map encoding which actions are allowed to fail. - /// @param failureMap The failure map encoding which actions have failed. - /// @param execResults The array with the results of the executed actions. - /// @dev The value of `callId` is defined by the component/contract calling the execute function. A `Plugin` implementation can use it, for example, as a nonce. - event Executed( - address indexed actor, - bytes32 callId, - Action[] actions, - uint256 allowFailureMap, - uint256 failureMap, - bytes[] execResults - ); - - /// @notice Emitted when a standard callback is registered. - /// @param interfaceId The ID of the interface. - /// @param callbackSelector The selector of the callback function. - /// @param magicNumber The magic number to be registered for the callback function selector. - event StandardCallbackRegistered( - bytes4 interfaceId, - bytes4 callbackSelector, - bytes4 magicNumber - ); - - /// @notice Deposits (native) tokens to the DAO contract with a reference string. - /// @param _token The address of the token or address(0) in case of the native token. - /// @param _amount The amount of tokens to deposit. - /// @param _reference The reference describing the deposit reason. - function deposit(address _token, uint256 _amount, string calldata _reference) external payable; - - /// @notice Emitted when a token deposit has been made to the DAO. - /// @param sender The address of the sender. - /// @param token The address of the deposited token. - /// @param amount The amount of tokens deposited. - /// @param _reference The reference describing the deposit reason. - event Deposited( - address indexed sender, - address indexed token, - uint256 amount, - string _reference - ); - - /// @notice Emitted when a native token deposit has been made to the DAO. - /// @dev This event is intended to be emitted in the `receive` function and is therefore bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929). - /// @param sender The address of the sender. - /// @param amount The amount of native tokens deposited. - event NativeTokenDeposited(address sender, uint256 amount); - - /// @notice Setter for the trusted forwarder verifying the meta transaction. - /// @param _trustedForwarder The trusted forwarder address. - function setTrustedForwarder(address _trustedForwarder) external; - - /// @notice Getter for the trusted forwarder verifying the meta transaction. - /// @return The trusted forwarder address. - function getTrustedForwarder() external view returns (address); - - /// @notice Emitted when a new TrustedForwarder is set on the DAO. - /// @param forwarder the new forwarder address. - event TrustedForwarderSet(address forwarder); - - /// @notice Setter for the [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. - /// @param _signatureValidator The address of the signature validator. - function setSignatureValidator(address _signatureValidator) external; - - /// @notice Emitted when the signature validator address is updated. - /// @param signatureValidator The address of the signature validator. - event SignatureValidatorSet(address signatureValidator); - - /// @notice Checks whether a signature is valid for the provided hash by forwarding the call to the set [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. - /// @param _hash The hash of the data to be signed. - /// @param _signature The signature byte array associated with `_hash`. - /// @return Returns the `bytes4` magic value `0x1626ba7e` if the signature is valid. - function isValidSignature(bytes32 _hash, bytes memory _signature) external returns (bytes4); - - /// @notice Registers an ERC standard having a callback by registering its [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID and callback function signature. - /// @param _interfaceId The ID of the interface. - /// @param _callbackSelector The selector of the callback function. - /// @param _magicNumber The magic number to be registered for the function signature. - function registerStandardCallback( - bytes4 _interfaceId, - bytes4 _callbackSelector, - bytes4 _magicNumber - ) external; -} diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 37ca63589..67640bddf 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -1,7 +1,7 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; -//import {upgrades} from 'hardhat'; +import {v1_2_0_active_contracts} from '../../../contracts-versions/ import { DAO, From 4c2573eb43174e7cdd2aa1d33c18ccf7d099f0b7 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Thu, 11 May 2023 12:30:07 +0200 Subject: [PATCH 077/112] fix: tests --- packages/contracts/src/test/Migration.sol | 6 +++ packages/contracts/test/core/dao/dao.ts | 4 +- packages/contracts/test/upgrade/dao.ts | 50 +++++++++++++---------- 3 files changed, 37 insertions(+), 23 deletions(-) create mode 100644 packages/contracts/src/test/Migration.sol diff --git a/packages/contracts/src/test/Migration.sol b/packages/contracts/src/test/Migration.sol new file mode 100644 index 000000000..0cbdef673 --- /dev/null +++ b/packages/contracts/src/test/Migration.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.17; + +import {DAO as DAO_v1_0_0} from "@aragon/osx-versions/versions/v1_0_0/contracts/core/dao/DAO.sol"; +import {DAO as DAO_v1_2_0} from "@aragon/osx-versions/versions/v1_2_0/contracts/core/dao/DAO.sol"; diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 325c65360..3152b9af4 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -221,9 +221,9 @@ describe('DAO', function () { describe('initializeUpgradeFrom', async () => { it('reverts if trying to release from a previous major release', async () => { - const testDao = await deployWithProxy(DAO); + const uninitializedDao = await deployWithProxy(DAO); - await expect(testDao.initializeUpgradeFrom([0, 1, 0])) + await expect(uninitializedDao.initializeUpgradeFrom([0, 1, 0])) .to.be.revertedWithCustomError( dao, 'ProtocolVersionUpgradeNotSupported' diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 67640bddf..a01458e58 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -1,34 +1,29 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; -import {v1_2_0_active_contracts} from '../../../contracts-versions/ -import { - DAO, - DAO__factory, - DAOV100, - DAOV100__factory, - DAOV120, - DAOV120__factory, -} from '../../typechain'; +import DAO100 from '../../artifacts/@aragon/osx-versions/versions/v1_0_0/contracts/core/dao/DAO.sol/DAO.json'; +import DAO120 from '../../artifacts/@aragon/osx-versions/versions/v1_2_0/contracts/core/dao/DAO.sol/DAO.json'; +import DAOCurrent from '../../artifacts/src/core/dao/DAO.sol/DAO.json'; import {daoExampleURI, ZERO_BYTES32} from '../test-utils/dao'; import {deployWithProxy} from '../test-utils/proxy'; import {UPGRADE_PERMISSIONS} from '../test-utils/permissions'; import {findEventTopicLog} from '../../utils/event'; import {readImplementationValueFromSlot} from '../../utils/storage'; +import {Contract, ContractFactory} from 'ethers'; let signers: SignerWithAddress[]; -let Dao_v1_0_0: DAOV100__factory; -let Dao_v1_2_0: DAOV120__factory; -let DaoCurrent: DAO__factory; +let Dao_v1_0_0: ContractFactory; +let Dao_v1_2_0: ContractFactory; +let DaoCurrent: ContractFactory; //DAO__factory; -let daoV100Proxy: DAOV100; -let daoV120Proxy: DAOV120; +let daoV100Proxy: Contract; +let daoV120Proxy: Contract; let daoV101Implementation: string; let daoV120Implementation: string; -let daoCurrentImplementaion: DAO; +let daoCurrentImplementaion: Contract; const EMPTY_DATA = '0x'; @@ -42,10 +37,23 @@ const FORWARDER_2 = `0x${'2'.repeat(40)}`; describe('DAO Upgrade', function () { before(async function () { signers = await ethers.getSigners(); - Dao_v1_0_0 = new DAOV100__factory(signers[0]); - Dao_v1_2_0 = new DAOV120__factory(signers[0]); - - DaoCurrent = new DAO__factory(signers[0]); // 1.3.0 + Dao_v1_0_0 = new ContractFactory( + new ethers.utils.Interface(DAO100.abi), + DAO100.bytecode, + signers[0] + ); + Dao_v1_2_0 = new ContractFactory( + new ethers.utils.Interface(DAO120.abi), + DAO100.bytecode, + signers[0] + ); + + DaoCurrent = new ContractFactory( + new ethers.utils.Interface(DAOCurrent.abi), + DAOCurrent.bytecode, + signers[0] + ); + //DaoCurrent = new DAO__factory(signers[0]); // 1.3.0 // Deploy the v1.3.0 implementation daoCurrentImplementaion = await DaoCurrent.deploy(); @@ -53,7 +61,7 @@ describe('DAO Upgrade', function () { context(`v1.0.0 to v1.3.0`, function () { beforeEach(async function () { - daoV100Proxy = await deployWithProxy(Dao_v1_0_0); + daoV100Proxy = await deployWithProxy(Dao_v1_0_0); await daoV100Proxy.initialize( DUMMY_METADATA, signers[0].address, @@ -223,7 +231,7 @@ describe('DAO Upgrade', function () { context(`v1.2.0 to v1.3.0`, function () { beforeEach(async function () { - daoV120Proxy = await deployWithProxy(Dao_v1_2_0); + daoV120Proxy = await deployWithProxy(Dao_v1_2_0); await daoV120Proxy.initialize( DUMMY_METADATA, signers[0].address, From ad8fc66545522e6b197877485fd9ecf18e41c444 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Thu, 11 May 2023 16:41:45 +0200 Subject: [PATCH 078/112] fix: finalize tests --- packages/contracts/test/upgrade/dao.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index a01458e58..b71498db7 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -16,7 +16,7 @@ import {Contract, ContractFactory} from 'ethers'; let signers: SignerWithAddress[]; let Dao_v1_0_0: ContractFactory; let Dao_v1_2_0: ContractFactory; -let DaoCurrent: ContractFactory; //DAO__factory; +let DaoCurrent: ContractFactory; let daoV100Proxy: Contract; let daoV120Proxy: Contract; @@ -37,11 +37,14 @@ const FORWARDER_2 = `0x${'2'.repeat(40)}`; describe('DAO Upgrade', function () { before(async function () { signers = await ethers.getSigners(); + + // We don't use the typchain here but directly grab the artifacts. This will be changed in an upcoming PR again. Dao_v1_0_0 = new ContractFactory( new ethers.utils.Interface(DAO100.abi), DAO100.bytecode, signers[0] ); + Dao_v1_2_0 = new ContractFactory( new ethers.utils.Interface(DAO120.abi), DAO100.bytecode, @@ -53,7 +56,6 @@ describe('DAO Upgrade', function () { DAOCurrent.bytecode, signers[0] ); - //DaoCurrent = new DAO__factory(signers[0]); // 1.3.0 // Deploy the v1.3.0 implementation daoCurrentImplementaion = await DaoCurrent.deploy(); From ca9a176b946130dad72701ac3ca2cc640926b714 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Thu, 11 May 2023 17:14:24 +0200 Subject: [PATCH 079/112] fix typechain and add a script --- packages/contracts/hardhat.config.ts | 1 - packages/contracts/package.json | 5 ++-- .../contracts/scripts/generate-typechain.ts | 27 +++++++++++++++++++ .../src/test/osx-versions/Migration.sol | 6 +++++ 4 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 packages/contracts/scripts/generate-typechain.ts create mode 100644 packages/contracts/src/test/osx-versions/Migration.sol diff --git a/packages/contracts/hardhat.config.ts b/packages/contracts/hardhat.config.ts index 60690670e..a09fa80c1 100644 --- a/packages/contracts/hardhat.config.ts +++ b/packages/contracts/hardhat.config.ts @@ -6,7 +6,6 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; import {extendEnvironment, HardhatUserConfig} from 'hardhat/config'; import '@nomicfoundation/hardhat-chai-matchers'; import '@nomiclabs/hardhat-etherscan'; -import '@typechain/hardhat'; import 'hardhat-deploy'; import 'hardhat-gas-reporter'; import '@openzeppelin/hardhat-upgrades'; diff --git a/packages/contracts/package.json b/packages/contracts/package.json index e029beb02..b2fb4488b 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -12,11 +12,12 @@ "dist" ], "scripts": { + "typechain": "find ./artifacts -name '*.json' -type f -not -path './artifacts/@aragon/*' -not -path './artifacts/build-info/*' | grep -v '.dbg.json' | xargs typechain --target=ethers-v5 --out-dir ./typechain", + "typechain:osx-versions": "ts-node scripts/generate-typechain.ts", "test": "hardhat test", - "build": "hardhat compile", + "build": "hardhat compile && yarn typechain && yarn typechain:osx-versions", "build:npm": "rollup --config rollup.config.ts", "build:contracts-versions": "cd ../contracts-versions && yarn build", - "postinstall": "yarn build:contracts-versions", "coverage": "hardhat coverage --solcoverjs ./.solcover.js", "flatten": "hardhat flatten", "analyze": "mythx analyze", diff --git a/packages/contracts/scripts/generate-typechain.ts b/packages/contracts/scripts/generate-typechain.ts new file mode 100644 index 000000000..f28af738d --- /dev/null +++ b/packages/contracts/scripts/generate-typechain.ts @@ -0,0 +1,27 @@ +import {exec} from 'child_process'; +import path from 'path'; +import fs from 'fs'; +import util from 'util'; + +const execPromise = util.promisify(exec); + +async function generateTypechain(src: string, dest: string): Promise { + const {stdout} = await execPromise( + `find "${src}" -name '*.json' -type f ! -name '*.dbg.json'` + ); + const jsonFiles = stdout.trim().split('\n'); + + for (const file of jsonFiles) { + const relativePath = path.relative(src, path.dirname(file)); + const outputDir = path.join(dest, relativePath); + fs.mkdirSync(outputDir, {recursive: true}); + await execPromise( + `typechain --target ethers-v5 --out-dir "${outputDir}" "${file}"` + ); + } +} + +generateTypechain( + './artifacts/@aragon/osx-versions/versions/', + './typechain/osx-versions' +); diff --git a/packages/contracts/src/test/osx-versions/Migration.sol b/packages/contracts/src/test/osx-versions/Migration.sol new file mode 100644 index 000000000..0cbdef673 --- /dev/null +++ b/packages/contracts/src/test/osx-versions/Migration.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity 0.8.17; + +import {DAO as DAO_v1_0_0} from "@aragon/osx-versions/versions/v1_0_0/contracts/core/dao/DAO.sol"; +import {DAO as DAO_v1_2_0} from "@aragon/osx-versions/versions/v1_2_0/contracts/core/dao/DAO.sol"; From f689e6ce2d0ab95f29343a192dd0d13b6d5a789b Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Thu, 11 May 2023 17:15:26 +0200 Subject: [PATCH 080/112] fix: typo --- packages/contracts/src/core/dao/DAO.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 8a27ba52e..5c69e0b14 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -163,7 +163,7 @@ contract DAO is revert ProtocolVersionUpgradeNotSupported(previousProtocolVersion); } - // All version before v1.3.0 must initialize the newly added `_reentrancyStatus`. + // All versions before v1.3.0 must initialize the newly added `_reentrancyStatus`. if (previousProtocolVersion[1] < 3) { _reentrancyStatus = _NOT_ENTERED; } From 9303b42ed9db53cb249fae8b3baef699a1c16268 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 12 May 2023 10:00:01 +0200 Subject: [PATCH 081/112] feat: improve initializeUpgradeFrom --- packages/contracts/src/core/dao/DAO.sol | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 5c69e0b14..96118a145 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -155,16 +155,14 @@ contract DAO is } /// @notice Initializes the DAO after an upgrade from a previous version. - /// @param previousProtocolVersion The protocol version number of the previous DAO implementation contract this upgrade is transitioning from. - function initializeUpgradeFrom( - uint8[3] calldata previousProtocolVersion - ) external reinitializer(2) { - if (previousProtocolVersion[0] != 1 || previousProtocolVersion[1] >= 3) { - revert ProtocolVersionUpgradeNotSupported(previousProtocolVersion); + /// @param _protocolVersion The protocol version number of the previous DAO implementation contract this upgrade is transitioning from. + function initializeUpgradeFrom(uint8[3] calldata _protocolVersion) external reinitializer(2) { + if (_protocolVersion[0] != 1 || _protocolVersion[1] >= 3) { + revert ProtocolVersionUpgradeNotSupported(_protocolVersion); } // All versions before v1.3.0 must initialize the newly added `_reentrancyStatus`. - if (previousProtocolVersion[1] < 3) { + if (_protocolVersion[1] < 3) { _reentrancyStatus = _NOT_ENTERED; } } From cf3b2c1fad96c0d4d7c75d5f03c2c06ec8a35528 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 12 May 2023 10:15:41 +0200 Subject: [PATCH 082/112] feat: added _initData parameter --- packages/contracts/src/core/dao/DAO.sol | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 96118a145..812e73cc8 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -156,7 +156,13 @@ contract DAO is /// @notice Initializes the DAO after an upgrade from a previous version. /// @param _protocolVersion The protocol version number of the previous DAO implementation contract this upgrade is transitioning from. - function initializeUpgradeFrom(uint8[3] calldata _protocolVersion) external reinitializer(2) { + /// @param _initData The initialization data to be passed to via `upgradeToAndCall` (see [ERC-1967](https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Upgrade)). + function initializeUpgradeFrom( + uint8[3] calldata _protocolVersion, + bytes calldata _initData + ) external reinitializer(2) { + _initData; // Silences the unused function parameter warning. + if (_protocolVersion[0] != 1 || _protocolVersion[1] >= 3) { revert ProtocolVersionUpgradeNotSupported(_protocolVersion); } From 9cd9e65637257a422fe5b25015bb521a0a3a2ecc Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 12 May 2023 10:33:59 +0200 Subject: [PATCH 083/112] feat: added test --- packages/contracts/test/core/dao/dao.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 3152b9af4..d6f79d2ba 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -220,7 +220,7 @@ describe('DAO', function () { }); describe('initializeUpgradeFrom', async () => { - it('reverts if trying to release from a previous major release', async () => { + it('reverts if trying to upgrade from a previous major release', async () => { const uninitializedDao = await deployWithProxy(DAO); await expect(uninitializedDao.initializeUpgradeFrom([0, 1, 0])) @@ -231,6 +231,17 @@ describe('DAO', function () { .withArgs([0, 1, 0]); }); + it('reverts if trying to upgrade to the same version', async () => { + const uninitializedDao = await deployWithProxy(DAO); + + await expect(uninitializedDao.initializeUpgradeFrom([1, 3, 0])) + .to.be.revertedWithCustomError( + dao, + 'ProtocolVersionUpgradeNotSupported' + ) + .withArgs([1, 3, 0]); + }); + it('initializes upgrades for versions < 1.3.0', async () => { // Create an unitialized DAO. const uninitializedDao = await deployWithProxy(DAO); From 452c958a29cf827de722b05bdb13e7f00d54c228 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 12 May 2023 11:02:56 +0200 Subject: [PATCH 084/112] fix: wrong version number --- packages/contracts/test/upgrade/dao.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index b71498db7..38e7c2b66 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -21,7 +21,7 @@ let DaoCurrent: ContractFactory; let daoV100Proxy: Contract; let daoV120Proxy: Contract; -let daoV101Implementation: string; +let daoV100Implementation: string; let daoV120Implementation: string; let daoCurrentImplementaion: Contract; @@ -72,7 +72,7 @@ describe('DAO Upgrade', function () { ); // Store the v1.0.0 implementation - daoV101Implementation = await readImplementationValueFromSlot( + daoV100Implementation = await readImplementationValueFromSlot( daoV100Proxy.address ); @@ -100,7 +100,7 @@ describe('DAO Upgrade', function () { expect(implementationAfterUpgrade).to.equal( daoCurrentImplementaion.address ); - expect(implementationAfterUpgrade).to.not.equal(daoV101Implementation); + expect(implementationAfterUpgrade).to.not.equal(daoV100Implementation); // Check the emitted implementation. const emittedImplementation = ( @@ -139,7 +139,7 @@ describe('DAO Upgrade', function () { expect(implementationAfterUpgrade).to.equal( daoCurrentImplementaion.address ); - expect(implementationAfterUpgrade).to.not.equal(daoV101Implementation); + expect(implementationAfterUpgrade).to.not.equal(daoV100Implementation); expect( await daoV100Proxy.hasPermission( @@ -207,7 +207,7 @@ describe('DAO Upgrade', function () { expect(implementationAfterUpgrade).to.equal( daoCurrentImplementaion.address ); - expect(implementationAfterUpgrade).to.not.equal(daoV101Implementation); + expect(implementationAfterUpgrade).to.not.equal(daoV100Implementation); // Check that the old forwarder is still unchanged. expect(await daoV100Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); @@ -377,7 +377,7 @@ describe('DAO Upgrade', function () { expect(implementationAfterUpgrade).to.equal( daoCurrentImplementaion.address ); - expect(implementationAfterUpgrade).to.not.equal(daoV101Implementation); + expect(implementationAfterUpgrade).to.not.equal(daoV100Implementation); // Check that the old forwarder is still unchanged. expect(await daoV120Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); From c865dcb023284936b563500807fffab36ab94e73 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Fri, 12 May 2023 12:00:47 +0200 Subject: [PATCH 085/112] WIP --- .../new/00_managing-dao/00_managing-dao.ts | 7 +++++- .../01_managing-dao-permissions.ts | 4 ++- .../00_managing-dao/20_set-dao-permission.ts | 2 +- .../new/00_managing-dao/99_verify_step.ts | 2 +- .../02_ens_subdomain_registrars.ts | 2 +- .../new/20_permissions/00_ens-permissions.ts | 2 +- .../10_dao-registry-permissions.ts | 2 +- .../20_plugin-registrty-permissions.ts | 2 +- .../deploy/new/20_permissions/99_verify.ts | 2 +- .../00_grant-permissions.ts | 2 +- ...0_register-managing-dao-on-dao-registry.ts | 2 +- .../30_install-multisig-on-managing-dao.ts | 2 +- .../40_revoke-permissions.ts | 2 +- .../99_verify_step.ts | 2 +- packages/contracts/test/core/dao/dao.ts | 3 ++- .../plugin/parameter-scoping-condition.ts | 2 +- .../test/core/plugin/shared-plugin.ts | 7 +++--- .../contracts/test/deploy/managing-dao.ts | 6 +++-- .../test/framework/dao/dao-factory.ts | 14 +++++------ .../test/framework/dao/dao-registry.ts | 12 ++++----- .../framework/plugin/plugin-repo-factory.ts | 4 +-- .../framework/plugin/plugin-repo-registry.ts | 25 ++++++++++--------- .../test/framework/plugin/plugin-repo.ts | 14 +++++------ .../plugin/plugin-setup-processor.ts | 4 +-- .../utils/ens/ens-subdomain-registry.ts | 9 +++---- .../utils/interface-based-registry.ts | 2 +- .../test/framework/utils/token-factory.ts | 2 +- .../plugins/governance/admin/admin-setup.ts | 2 +- .../test/plugins/governance/admin/admin.ts | 4 +-- .../addresslist/addresslist-voting-setup.ts | 2 +- .../addresslist/addresslist-voting.ts | 4 +-- .../majority-voting/majority-voting.ts | 3 ++- .../token/token-voting-setup.ts | 2 +- .../majority-voting/token/token-voting.ts | 4 +-- .../governance/multisig/multisig-setup.ts | 8 +++--- .../plugins/governance/multisig/multisig.ts | 4 +-- .../token/distribution/merkle-distributor.ts | 3 +-- .../token/distribution/merkle-minter.ts | 2 +- packages/contracts/test/test-utils/dao.ts | 10 +++++--- packages/contracts/test/test-utils/repo.ts | 19 ++++++++------ .../test/test-utils/uups-upgradeable.ts | 2 +- .../test/token/erc20/governance-erc20.ts | 2 +- 42 files changed, 112 insertions(+), 98 deletions(-) diff --git a/packages/contracts/deploy/new/00_managing-dao/00_managing-dao.ts b/packages/contracts/deploy/new/00_managing-dao/00_managing-dao.ts index c404216a3..42404ed3b 100644 --- a/packages/contracts/deploy/new/00_managing-dao/00_managing-dao.ts +++ b/packages/contracts/deploy/new/00_managing-dao/00_managing-dao.ts @@ -1,5 +1,7 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; -import {DeployFunction} from 'hardhat-deploy/types'; +import {ArtifactData, DeployFunction} from 'hardhat-deploy/types'; + +import daoArtifactJson from '../../../artifacts/src/core/dao/DAO.sol/DAO.json'; /** NOTE: * Create a (Managing DAO) with no Plugin, to be the owner DAO for the framework, temporarily. */ @@ -23,7 +25,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { daoURI: '0x', }; + const daoArtifactData = daoArtifactJson as ArtifactData; + await deploy('DAO', { + contract: daoArtifactData, from: deployer, args: [], log: true, diff --git a/packages/contracts/deploy/new/00_managing-dao/01_managing-dao-permissions.ts b/packages/contracts/deploy/new/00_managing-dao/01_managing-dao-permissions.ts index b2b7172d2..e2acb4f79 100644 --- a/packages/contracts/deploy/new/00_managing-dao/01_managing-dao-permissions.ts +++ b/packages/contracts/deploy/new/00_managing-dao/01_managing-dao-permissions.ts @@ -1,6 +1,8 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; + import {Operation} from '../../../utils/types'; + import {getContractAddress, managePermissions} from '../../helpers'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { @@ -13,7 +15,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Get `DAO` contract. const managingDaoContract = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); diff --git a/packages/contracts/deploy/new/00_managing-dao/20_set-dao-permission.ts b/packages/contracts/deploy/new/00_managing-dao/20_set-dao-permission.ts index 60ba475ba..6621811b8 100644 --- a/packages/contracts/deploy/new/00_managing-dao/20_set-dao-permission.ts +++ b/packages/contracts/deploy/new/00_managing-dao/20_set-dao-permission.ts @@ -17,7 +17,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Get `DAO` contract. const managingDaoContract = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); diff --git a/packages/contracts/deploy/new/00_managing-dao/99_verify_step.ts b/packages/contracts/deploy/new/00_managing-dao/99_verify_step.ts index 103856de9..323948ef7 100644 --- a/packages/contracts/deploy/new/00_managing-dao/99_verify_step.ts +++ b/packages/contracts/deploy/new/00_managing-dao/99_verify_step.ts @@ -18,7 +18,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const managingDAOAddress = await getContractAddress('DAO', hre); // Get `DAO` contract. const managingDaoContract = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); diff --git a/packages/contracts/deploy/new/10_framework/02_ens_subdomain_registrars.ts b/packages/contracts/deploy/new/10_framework/02_ens_subdomain_registrars.ts index 25d63b4b2..c5c939d54 100644 --- a/packages/contracts/deploy/new/10_framework/02_ens_subdomain_registrars.ts +++ b/packages/contracts/deploy/new/10_framework/02_ens_subdomain_registrars.ts @@ -11,7 +11,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); const managingDAO: DAO = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); diff --git a/packages/contracts/deploy/new/20_permissions/00_ens-permissions.ts b/packages/contracts/deploy/new/20_permissions/00_ens-permissions.ts index dd3d2cb08..ce660cde9 100644 --- a/packages/contracts/deploy/new/20_permissions/00_ens-permissions.ts +++ b/packages/contracts/deploy/new/20_permissions/00_ens-permissions.ts @@ -14,7 +14,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Get `DAO` contract. const managingDaoContract = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); diff --git a/packages/contracts/deploy/new/20_permissions/10_dao-registry-permissions.ts b/packages/contracts/deploy/new/20_permissions/10_dao-registry-permissions.ts index 0993e065d..f969ed738 100644 --- a/packages/contracts/deploy/new/20_permissions/10_dao-registry-permissions.ts +++ b/packages/contracts/deploy/new/20_permissions/10_dao-registry-permissions.ts @@ -12,7 +12,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Get `DAO` contract. const managingDaoContract = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); diff --git a/packages/contracts/deploy/new/20_permissions/20_plugin-registrty-permissions.ts b/packages/contracts/deploy/new/20_permissions/20_plugin-registrty-permissions.ts index 5a7beab57..68c13f030 100644 --- a/packages/contracts/deploy/new/20_permissions/20_plugin-registrty-permissions.ts +++ b/packages/contracts/deploy/new/20_permissions/20_plugin-registrty-permissions.ts @@ -12,7 +12,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Get `DAO` contract. const managingDaoContract = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); diff --git a/packages/contracts/deploy/new/20_permissions/99_verify.ts b/packages/contracts/deploy/new/20_permissions/99_verify.ts index 2e3c55503..c4b6d93ef 100644 --- a/packages/contracts/deploy/new/20_permissions/99_verify.ts +++ b/packages/contracts/deploy/new/20_permissions/99_verify.ts @@ -14,7 +14,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Get `DAO` contract. const managingDaoContract = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); diff --git a/packages/contracts/deploy/new/40_finalize-managing-dao/00_grant-permissions.ts b/packages/contracts/deploy/new/40_finalize-managing-dao/00_grant-permissions.ts index daec0ccc5..bd9adf68e 100644 --- a/packages/contracts/deploy/new/40_finalize-managing-dao/00_grant-permissions.ts +++ b/packages/contracts/deploy/new/40_finalize-managing-dao/00_grant-permissions.ts @@ -22,7 +22,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Get `DAO` contract. const managingDaoContract = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); diff --git a/packages/contracts/deploy/new/40_finalize-managing-dao/20_register-managing-dao-on-dao-registry.ts b/packages/contracts/deploy/new/40_finalize-managing-dao/20_register-managing-dao-on-dao-registry.ts index cd90be19b..ddabe1614 100644 --- a/packages/contracts/deploy/new/40_finalize-managing-dao/20_register-managing-dao-on-dao-registry.ts +++ b/packages/contracts/deploy/new/40_finalize-managing-dao/20_register-managing-dao-on-dao-registry.ts @@ -58,7 +58,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Set Metadata for the Managing DAO const managingDaoContract = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); diff --git a/packages/contracts/deploy/new/40_finalize-managing-dao/30_install-multisig-on-managing-dao.ts b/packages/contracts/deploy/new/40_finalize-managing-dao/30_install-multisig-on-managing-dao.ts index bccce020c..70566cd96 100644 --- a/packages/contracts/deploy/new/40_finalize-managing-dao/30_install-multisig-on-managing-dao.ts +++ b/packages/contracts/deploy/new/40_finalize-managing-dao/30_install-multisig-on-managing-dao.ts @@ -42,7 +42,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Get `DAO` contract. const managingDaoContract = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); diff --git a/packages/contracts/deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts b/packages/contracts/deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts index e8c42f7be..388812479 100644 --- a/packages/contracts/deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts +++ b/packages/contracts/deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts @@ -26,7 +26,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Get `DAO` contract. const managingDaoContract = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); diff --git a/packages/contracts/deploy/new/40_finalize-managing-dao/99_verify_step.ts b/packages/contracts/deploy/new/40_finalize-managing-dao/99_verify_step.ts index 18e317f6d..8d960e321 100644 --- a/packages/contracts/deploy/new/40_finalize-managing-dao/99_verify_step.ts +++ b/packages/contracts/deploy/new/40_finalize-managing-dao/99_verify_step.ts @@ -14,7 +14,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const managingDAOAddress = await getContractAddress('DAO', hre); // Get `DAO` contract. const managingDaoContract = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDAOAddress ); // Get `DAORegistry` address. diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index bf3c87485..651bd7aef 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -9,6 +9,7 @@ import { TestERC721, IERC1271__factory, GasConsumer__factory, + DAO__factory, } from '../../../typechain'; import {findEvent, DAO_EVENTS} from '../../../utils/event'; import {flipBit} from '../../test-utils/bitmap'; @@ -80,7 +81,7 @@ describe('DAO', function () { signers = await ethers.getSigners(); ownerAddress = await signers[0].getAddress(); - const DAO = await ethers.getContractFactory('DAO'); + const DAO = new DAO__factory(signers[0]); dao = await deployWithProxy(DAO); await dao.initialize( dummyMetadata1, diff --git a/packages/contracts/test/core/plugin/parameter-scoping-condition.ts b/packages/contracts/test/core/plugin/parameter-scoping-condition.ts index 5400cd5c4..deb167bb9 100644 --- a/packages/contracts/test/core/plugin/parameter-scoping-condition.ts +++ b/packages/contracts/test/core/plugin/parameter-scoping-condition.ts @@ -25,7 +25,7 @@ describe('TestParameterScopingCondition', function () { ownerAddress = await signers[0].getAddress(); // create a DAO - managingDao = await deployNewDAO(ownerAddress); + managingDao = await deployNewDAO(signers[0]); // Deploy the component const TestPlugin = await ethers.getContractFactory('TestPlugin'); diff --git a/packages/contracts/test/core/plugin/shared-plugin.ts b/packages/contracts/test/core/plugin/shared-plugin.ts index dd8775a37..ee2d8374e 100644 --- a/packages/contracts/test/core/plugin/shared-plugin.ts +++ b/packages/contracts/test/core/plugin/shared-plugin.ts @@ -24,10 +24,9 @@ describe('SharedPlugin', function () { ownerAddress = await signers[0].getAddress(); // Deploy the managing DAO and two other DAOs - const DAO = await ethers.getContractFactory('DAO'); - managingDao = await deployNewDAO(ownerAddress); - dao1 = await deployNewDAO(ownerAddress); - dao2 = await deployNewDAO(ownerAddress); + managingDao = await deployNewDAO(signers[0]); + dao1 = await deployNewDAO(signers[0]); + dao2 = await deployNewDAO(signers[0]); // Deploy the `TestSharedPlugin` const TestSharedPlugin = await ethers.getContractFactory( diff --git a/packages/contracts/test/deploy/managing-dao.ts b/packages/contracts/test/deploy/managing-dao.ts index 142d54e63..e6ef08a3e 100644 --- a/packages/contracts/test/deploy/managing-dao.ts +++ b/packages/contracts/test/deploy/managing-dao.ts @@ -12,6 +12,8 @@ import { PluginRepoRegistry, } from '../../typechain'; +import daoArtifactData from '../../artifacts/src/core/dao/DAO.sol/DAO.json'; + async function deployAll() { await deployments.fixture(); } @@ -80,7 +82,7 @@ describe('Managing DAO', function () { // ManagingDAO managingDaoDeployment = await deployments.get('DAO'); managingDao = await ethers.getContractAt( - 'DAO', + 'src/core/dao/DAO.sol:DAO', managingDaoDeployment.address ); @@ -130,7 +132,7 @@ describe('Managing DAO', function () { it('should be able to upgrade `ManagingDAO` itself', async function () { // deploy a new dao implementation. await deployments.deploy('DAOv2', { - contract: 'DAO', + contract: daoArtifactData, from: ownerAddress, args: [], log: true, diff --git a/packages/contracts/test/framework/dao/dao-factory.ts b/packages/contracts/test/framework/dao/dao-factory.ts index 6f62bc991..570ce72cb 100644 --- a/packages/contracts/test/framework/dao/dao-factory.ts +++ b/packages/contracts/test/framework/dao/dao-factory.ts @@ -164,7 +164,7 @@ describe('DAOFactory: ', function () { // @ts-ignore hre, 'DAOFactory', - ['DAORegistry', 'PluginSetupProcessor', 'DAO'] + ['DAORegistry', 'PluginSetupProcessor', 'src/core/dao/DAO.sol:DAO'] ); mergedABI = abi; @@ -173,7 +173,7 @@ describe('DAOFactory: ', function () { beforeEach(async function () { // Managing DAO - managingDao = await deployNewDAO(ownerAddress); + managingDao = await deployNewDAO(signers[0]); // ENS subdomain Registry const ensSubdomainRegistrar = await deployENSSubdomainRegistrar( @@ -292,7 +292,7 @@ describe('DAOFactory: ', function () { it('creates a dao and initializes with correct args', async () => { const dao = await getAnticipatedAddress(daoFactory.address); - const factory = await ethers.getContractFactory('DAO'); + const factory = new DAO__factory(signers[0]); const daoContract = factory.attach(dao); expect(await daoFactory.createDao(daoSettings, [pluginInstallationData])) @@ -361,7 +361,7 @@ describe('DAOFactory: ', function () { ]); const {dao, permissions} = await extractInfoFromCreateDaoTx(tx); - const factory = await ethers.getContractFactory('DAO'); + const factory = new DAO__factory(signers[0]); const daoContract = factory.attach(dao); for (let i = 0; i < permissions.length; i++) { @@ -383,7 +383,7 @@ describe('DAOFactory: ', function () { ]); const {dao} = await extractInfoFromCreateDaoTx(tx); - const factory = await ethers.getContractFactory('DAO'); + const factory = new DAO__factory(signers[0]); const daoContract = factory.attach(dao); await expect(tx) @@ -437,7 +437,7 @@ describe('DAOFactory: ', function () { ]); const {dao} = await extractInfoFromCreateDaoTx(tx); - const factory = await ethers.getContractFactory('DAO'); + const factory = new DAO__factory(signers[0]); const daoContract = factory.attach(dao); // Check that events were emitted. @@ -592,7 +592,7 @@ describe('DAOFactory: ', function () { const adminFactory = await ethers.getContractFactory('Admin'); adminPlugin = adminFactory.attach(event.args.plugin); - const daoFactory = await ethers.getContractFactory('DAO'); + const daoFactory = new DAO__factory(signers[0]); dao = daoFactory.attach(event.args.dao); } }); diff --git a/packages/contracts/test/framework/dao/dao-registry.ts b/packages/contracts/test/framework/dao/dao-registry.ts index e6a18cd14..48475a744 100644 --- a/packages/contracts/test/framework/dao/dao-registry.ts +++ b/packages/contracts/test/framework/dao/dao-registry.ts @@ -39,7 +39,7 @@ describe('DAORegistry', function () { beforeEach(async function () { // Managing DAO - managingDao = await deployNewDAO(ownerAddress); + managingDao = await deployNewDAO(signers[0]); // ENS ensSubdomainRegistrar = await deployENSSubdomainRegistrar( @@ -49,7 +49,7 @@ describe('DAORegistry', function () { ); // Target DAO to be used as an example DAO to be registered - targetDao = await deployNewDAO(ownerAddress); + targetDao = await deployNewDAO(signers[0]); // DAO Registry const Registry = await ethers.getContractFactory('DAORegistry'); @@ -119,7 +119,7 @@ describe('DAORegistry', function () { REGISTER_DAO_PERMISSION_ID ); - const newTargetDao = await deployNewDAO(ownerAddress); + const newTargetDao = await deployNewDAO(signers[0]); await expect( daoRegistry.register(newTargetDao.address, ownerAddress, daoSubdomain) @@ -151,7 +151,7 @@ describe('DAORegistry', function () { // Register the DAO name under the top level domain await daoRegistry.register(targetDao.address, ownerAddress, daoSubdomain); - const newTargetDao = await deployNewDAO(ownerAddress); + const newTargetDao = await deployNewDAO(signers[0]); const otherOwnerAddress = await (await ethers.getSigners())[1].getAddress(); // Try to register the DAO name under the top level domain a second time @@ -173,7 +173,7 @@ describe('DAORegistry', function () { // loop through the ascii table for (let i = 0; i < 127; i++) { - const newTargetDao = await deployNewDAO(ownerAddress); + const newTargetDao = await deployNewDAO(signers[0]); // replace the 10th char in the baseSubdomain const subdomainName = @@ -213,7 +213,7 @@ describe('DAORegistry', function () { // loop through the ascii table for (let i = 0; i < 127; i++) { - const newTargetDao = await deployNewDAO(ownerAddress); + const newTargetDao = await deployNewDAO(signers[0]); // replace the 40th char in the baseSubdomain const subdomainName = diff --git a/packages/contracts/test/framework/plugin/plugin-repo-factory.ts b/packages/contracts/test/framework/plugin/plugin-repo-factory.ts index 6e7b55184..66e584935 100644 --- a/packages/contracts/test/framework/plugin/plugin-repo-factory.ts +++ b/packages/contracts/test/framework/plugin/plugin-repo-factory.ts @@ -68,7 +68,7 @@ describe('PluginRepoFactory: ', function () { beforeEach(async function () { // DAO - managingDao = await deployNewDAO(ownerAddress); + managingDao = await deployNewDAO(signers[0]); // ENS subdomain Registry const ensSubdomainRegistrar = await deployENSSubdomainRegistrar( @@ -232,7 +232,7 @@ describe('PluginRepoFactory: ', function () { it('creates new pluginRepo with correct permissions', async () => { const pluginRepoSubdomain = 'my-plugin-repo'; - const pluginSetupMock = await deployMockPluginSetup(); + const pluginSetupMock = await deployMockPluginSetup(signers[0]); const expectedRepoAddress = await getExpectedRepoAddress( pluginRepoFactory.address ); diff --git a/packages/contracts/test/framework/plugin/plugin-repo-registry.ts b/packages/contracts/test/framework/plugin/plugin-repo-registry.ts index fb1cb06a2..a7457331d 100644 --- a/packages/contracts/test/framework/plugin/plugin-repo-registry.ts +++ b/packages/contracts/test/framework/plugin/plugin-repo-registry.ts @@ -7,6 +7,7 @@ import { PluginRepo, ENSSubdomainRegistrar, PluginRepoRegistry, + PluginRepoRegistry__factory, } from '../../../typechain'; import {deployNewDAO} from '../../test-utils/dao'; import {deployNewPluginRepo} from '../../test-utils/repo'; @@ -46,7 +47,7 @@ describe('PluginRepoRegistry', function () { beforeEach(async function () { // DAO - managingDAO = await deployNewDAO(ownerAddress); + managingDAO = await deployNewDAO(signers[0]); // ENS subdomain Registry ensSubdomainRegistrar = await deployENSSubdomainRegistrar( @@ -56,10 +57,10 @@ describe('PluginRepoRegistry', function () { ); // deploy and initialize PluginRepoRegistry - const PluginRepoRegistry = await ethers.getContractFactory( - 'PluginRepoRegistry' + const PluginRepoRegistry = new PluginRepoRegistry__factory(signers[0]); + pluginRepoRegistry = await deployWithProxy( + PluginRepoRegistry ); - pluginRepoRegistry = await deployWithProxy(PluginRepoRegistry); await pluginRepoRegistry.initialize( managingDAO.address, @@ -67,17 +68,17 @@ describe('PluginRepoRegistry', function () { ); // deploy a pluginRepo and initialize - pluginRepo = await deployNewPluginRepo(ownerAddress); + pluginRepo = await deployNewPluginRepo(signers[0]); - // grant REGISTER_PERMISSION_ID to registrer - managingDAO.grant( + // grant REGISTER_PLUGIN_REPO_PERMISSION_ID to ownerAddress + await managingDAO.grant( pluginRepoRegistry.address, ownerAddress, REGISTER_PLUGIN_REPO_PERMISSION_ID ); - // grant REGISTER_PERMISSION_ID to registrer - managingDAO.grant( + // grant REGISTER_ENS_SUBDOMAIN_PERMISSION_ID to pluginRepoRegistry + await managingDAO.grant( ensSubdomainRegistrar.address, pluginRepoRegistry.address, REGISTER_ENS_SUBDOMAIN_PERMISSION_ID @@ -129,7 +130,7 @@ describe('PluginRepoRegistry', function () { ); // deploy a pluginRepo - const newPluginRepo = await deployNewPluginRepo(ownerAddress); + const newPluginRepo = await deployNewPluginRepo(signers[0]); await expect( pluginRepoRegistry.registerPluginRepo( @@ -187,7 +188,7 @@ describe('PluginRepoRegistry', function () { // loop through the ascii table for (let i = 0; i < 127; i++) { // deploy a pluginRepo and initialize - const newPluginRepo = await deployNewPluginRepo(ownerAddress); + const newPluginRepo = await deployNewPluginRepo(signers[0]); // replace the 10th char in the baseSubdomain const subdomainName = @@ -227,7 +228,7 @@ describe('PluginRepoRegistry', function () { // loop through the ascii table for (let i = 0; i < 127; i++) { // deploy a pluginRepo and initialize - const newPluginRepo = await deployNewPluginRepo(ownerAddress); + const newPluginRepo = await deployNewPluginRepo(signers[0]); // replace the 40th char in the baseSubdomain const subdomainName = diff --git a/packages/contracts/test/framework/plugin/plugin-repo.ts b/packages/contracts/test/framework/plugin/plugin-repo.ts index 74988925d..b16e96810 100644 --- a/packages/contracts/test/framework/plugin/plugin-repo.ts +++ b/packages/contracts/test/framework/plugin/plugin-repo.ts @@ -37,10 +37,10 @@ describe('PluginRepo', function () { beforeEach(async function () { // deploy a pluginRepo and initialize - pluginRepo = await deployNewPluginRepo(ownerAddress); + pluginRepo = await deployNewPluginRepo(signers[0]); // deploy pluging factory mock - pluginSetupMock = await deployMockPluginSetup(); + pluginSetupMock = await deployMockPluginSetup(signers[0]); this.upgrade = { contract: pluginRepo, @@ -163,8 +163,8 @@ describe('PluginRepo', function () { }); it('fails if the same plugin setup exists in another release', async () => { - const pluginSetup_1 = await deployMockPluginSetup(); - const pluginSetup_2 = await deployMockPluginSetup(); + const pluginSetup_1 = await deployMockPluginSetup(signers[0]); + const pluginSetup_2 = await deployMockPluginSetup(signers[0]); // create release 1 await pluginRepo.createVersion( @@ -272,7 +272,7 @@ describe('PluginRepo', function () { // don't repeat the same plugin setup in the 2nd release // otherwise it will revert. - const pluginSetupMock_2 = await deployMockPluginSetup(); + const pluginSetupMock_2 = await deployMockPluginSetup(signers[0]); await expect( pluginRepo.createVersion( @@ -421,8 +421,8 @@ describe('PluginRepo', function () { beforeEach(async () => { pluginSetup_R1_B1 = pluginSetupMock; - pluginSetup_R1_B2 = await deployMockPluginSetup(); - pluginSetup_R2_B1 = await deployMockPluginSetup(); + pluginSetup_R1_B2 = await deployMockPluginSetup(signers[0]); + pluginSetup_R2_B1 = await deployMockPluginSetup(signers[0]); await pluginRepo.createVersion( 1, diff --git a/packages/contracts/test/framework/plugin/plugin-setup-processor.ts b/packages/contracts/test/framework/plugin/plugin-setup-processor.ts index 1d5ba72aa..05d253390 100644 --- a/packages/contracts/test/framework/plugin/plugin-setup-processor.ts +++ b/packages/contracts/test/framework/plugin/plugin-setup-processor.ts @@ -192,7 +192,7 @@ describe('Plugin Setup Processor', function () { setupCV2 = await SetupC2.deploy(); // Deploy yhe managing DAO having permission to manage `PluginSetupProcessor` - managingDao = await deployNewDAO(ownerAddress); + managingDao = await deployNewDAO(signers[0]); // Deploy ENS subdomain Registry const ensSubdomainRegistrar = await deployENSSubdomainRegistrar( @@ -275,7 +275,7 @@ describe('Plugin Setup Processor', function () { beforeEach(async function () { // Target DAO to be used as an example DAO - targetDao = await deployNewDAO(ownerAddress); + targetDao = await deployNewDAO(signers[0]); // Grant await targetDao.grant(targetDao.address, psp.address, ROOT_PERMISSION_ID); diff --git a/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts b/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts index c70974a18..4217a6a6b 100644 --- a/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts +++ b/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts @@ -26,17 +26,16 @@ async function setupENS( ): Promise<[ENSRegistry, PublicResolver, DAO, ENSSubdomainRegistrar]> { const ENSRegistry = await ethers.getContractFactory('ENSRegistry'); const PublicResolver = await ethers.getContractFactory('PublicResolver'); - const DAO = await ethers.getContractFactory('DAO'); const ENSSubdomainRegistrar = await ethers.getContractFactory( 'ENSSubdomainRegistrar' ); // Deploy the ENSRegistry - let ens = await ENSRegistry.connect(owner).deploy(); + const ens = await ENSRegistry.connect(owner).deploy(); await ens.deployed(); // Deploy the Resolver - let resolver = await PublicResolver.connect(owner).deploy( + const resolver = await PublicResolver.connect(owner).deploy( ens.address, ethers.constants.AddressZero ); @@ -44,10 +43,10 @@ async function setupENS( await setupResolver(ens, resolver, owner); // Deploy the managing DAO - let dao = await deployNewDAO(await owner.getAddress()); + const dao = await deployNewDAO(owner); // Deploy the registrar - let registrar = await deployWithProxy( + const registrar = await deployWithProxy( ENSSubdomainRegistrar ); diff --git a/packages/contracts/test/framework/utils/interface-based-registry.ts b/packages/contracts/test/framework/utils/interface-based-registry.ts index 0b92d1576..5cc8a8def 100644 --- a/packages/contracts/test/framework/utils/interface-based-registry.ts +++ b/packages/contracts/test/framework/utils/interface-based-registry.ts @@ -28,7 +28,7 @@ describe('InterfaceBasedRegistry', function () { ownerAddress = await signers[0].getAddress(); // DAO - dao = await deployNewDAO(ownerAddress); + dao = await deployNewDAO(signers[0]); }); beforeEach(async () => { diff --git a/packages/contracts/test/framework/utils/token-factory.ts b/packages/contracts/test/framework/utils/token-factory.ts index 2e9991f8c..74979b0af 100644 --- a/packages/contracts/test/framework/utils/token-factory.ts +++ b/packages/contracts/test/framework/utils/token-factory.ts @@ -85,7 +85,7 @@ describe('Core: TokenFactory', () => { let dao: FakeContract; beforeEach(async () => { - dao = await smock.fake('DAO'); + dao = await smock.fake('src/core/dao/DAO.sol:DAO'); dao.isGranted.returns(true); dao.hasPermission.returns(true); dao.grant.returns(); diff --git a/packages/contracts/test/plugins/governance/admin/admin-setup.ts b/packages/contracts/test/plugins/governance/admin/admin-setup.ts index 7abb5edcc..ddc179435 100644 --- a/packages/contracts/test/plugins/governance/admin/admin-setup.ts +++ b/packages/contracts/test/plugins/governance/admin/admin-setup.ts @@ -29,7 +29,7 @@ describe('AdminSetup', function () { before(async () => { signers = await ethers.getSigners(); ownerAddress = await signers[0].getAddress(); - targetDao = await deployNewDAO(ownerAddress); + targetDao = await deployNewDAO(signers[0]); minimum_data = abiCoder.encode( metadata.pluginSetupABI.prepareInstallation, diff --git a/packages/contracts/test/plugins/governance/admin/admin.ts b/packages/contracts/test/plugins/governance/admin/admin.ts index 9865712d7..0bb23d667 100644 --- a/packages/contracts/test/plugins/governance/admin/admin.ts +++ b/packages/contracts/test/plugins/governance/admin/admin.ts @@ -54,7 +54,7 @@ describe('Admin', function () { // @ts-ignore hre, 'Admin', - ['DAO'] + ['src/core/dao/DAO.sol:DAO'] )); dummyActions = [ @@ -68,7 +68,7 @@ describe('Admin', function () { ethers.utils.toUtf8Bytes('0x123456789') ); - dao = await deployNewDAO(ownerAddress); + dao = await deployNewDAO(signers[0]); const AdminCloneFactory = await ethers.getContractFactory( 'AdminCloneFactory' diff --git a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting-setup.ts b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting-setup.ts index 60d3a056e..ff24ada6c 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting-setup.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting-setup.ts @@ -41,7 +41,7 @@ describe('AddresslistVotingSetup', function () { before(async () => { signers = await ethers.getSigners(); - targetDao = await deployNewDAO(signers[0].address); + targetDao = await deployNewDAO(signers[0]); defaultVotingSettings = { votingMode: VotingMode.EarlyExecution, diff --git a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts index f29f26f55..475847eec 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts @@ -76,7 +76,7 @@ describe('AddresslistVoting', function () { // @ts-ignore hre, 'AddresslistVoting', - ['DAO'] + ['src/core/dao/DAO.sol:DAO'] )); dummyActions = [ @@ -90,7 +90,7 @@ describe('AddresslistVoting', function () { ethers.utils.toUtf8Bytes('0x123456789') ); - dao = await deployNewDAO(signers[0].address); + dao = await deployNewDAO(signers[0]); }); beforeEach(async function () { diff --git a/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts index 90a869dfc..c6b424cf5 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts @@ -9,6 +9,7 @@ import { IPlugin__factory, IProposal__factory, IMajorityVoting__factory, + DAO__factory, } from '../../../../typechain'; import {VOTING_EVENTS} from '../../../../utils/event'; import { @@ -44,7 +45,7 @@ describe('MajorityVotingMock', function () { signers = await ethers.getSigners(); ownerAddress = await signers[0].getAddress(); - const DAO = await ethers.getContractFactory('DAO'); + const DAO = new DAO__factory(signers[0]); dao = await deployWithProxy(DAO); await dao.initialize( '0x', diff --git a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting-setup.ts b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting-setup.ts index 4826341a2..378b64f5c 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting-setup.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting-setup.ts @@ -50,7 +50,7 @@ describe('TokenVotingSetup', function () { before(async () => { signers = await ethers.getSigners(); - targetDao = await deployNewDAO(signers[0].address); + targetDao = await deployNewDAO(signers[0]); defaultVotingSettings = { votingMode: VotingMode.EarlyExecution, diff --git a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts index 378e619a6..d1227e4a7 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts @@ -80,7 +80,7 @@ describe('TokenVoting', function () { // @ts-ignore hre, 'TokenVoting', - ['DAO'] + ['src/core/dao/DAO.sol:DAO'] )); dummyActions = [ @@ -95,7 +95,7 @@ describe('TokenVoting', function () { ethers.utils.toUtf8Bytes('0x123456789') ); - dao = await deployNewDAO(signers[0].address); + dao = await deployNewDAO(signers[0]); }); beforeEach(async function () { diff --git a/packages/contracts/test/plugins/governance/multisig/multisig-setup.ts b/packages/contracts/test/plugins/governance/multisig/multisig-setup.ts index 6a1bc92e0..a99cdcf7e 100644 --- a/packages/contracts/test/plugins/governance/multisig/multisig-setup.ts +++ b/packages/contracts/test/plugins/governance/multisig/multisig-setup.ts @@ -54,7 +54,7 @@ describe('MultisigSetup', function () { before(async () => { signers = await ethers.getSigners(); - targetDao = await deployNewDAO(signers[0].address); + targetDao = await deployNewDAO(signers[0]); defaultMultisigSettings = { onlyListed: true, @@ -341,7 +341,7 @@ describe('MultisigSetup', function () { before(async () => { [owner] = await ethers.getSigners(); - managingDAO = await deployNewDAO(owner.address); + managingDAO = await deployNewDAO(owner); // Create the PluginRepo const pluginRepoFactory = new PluginRepo__factory(owner); @@ -391,7 +391,7 @@ describe('MultisigSetup', function () { let helpers: string[]; before(async () => { - dao = await deployNewDAO(owner.address); + dao = await deployNewDAO(owner); // grant the owner full permission for plugins await dao.applySingleTargetPermissions(psp.address, [ { @@ -517,7 +517,7 @@ describe('MultisigSetup', function () { describe('Release 1 Build 2', () => { before(async () => { - dao = await deployNewDAO(owner.address); + dao = await deployNewDAO(owner); // grant the owner full permission for plugins await dao.applySingleTargetPermissions(psp.address, [ { diff --git a/packages/contracts/test/plugins/governance/multisig/multisig.ts b/packages/contracts/test/plugins/governance/multisig/multisig.ts index 8389becd0..c00385b10 100644 --- a/packages/contracts/test/plugins/governance/multisig/multisig.ts +++ b/packages/contracts/test/plugins/governance/multisig/multisig.ts @@ -85,7 +85,7 @@ describe('Multisig', function () { // @ts-ignore hre, 'Multisig', - ['DAO'] + ['src/core/dao/DAO.sol:DAO'] )); dummyActions = [ @@ -99,7 +99,7 @@ describe('Multisig', function () { ethers.utils.toUtf8Bytes('0x123456789') ); - dao = await deployNewDAO(signers[0].address); + dao = await deployNewDAO(signers[0]); }); beforeEach(async function () { diff --git a/packages/contracts/test/plugins/token/distribution/merkle-distributor.ts b/packages/contracts/test/plugins/token/distribution/merkle-distributor.ts index d3ecc5e41..dc23d46de 100644 --- a/packages/contracts/test/plugins/token/distribution/merkle-distributor.ts +++ b/packages/contracts/test/plugins/token/distribution/merkle-distributor.ts @@ -36,8 +36,7 @@ describe('MerkleDistributor', function () { wallet1 = await signers[1].getAddress(); // create a DAO - const DAO = await ethers.getContractFactory('DAO'); - dao = await deployNewDAO(wallet0); + dao = await deployNewDAO(signers[0]); const TestERC20 = await ethers.getContractFactory('TestERC20'); token = await TestERC20.deploy('FOO', 'FOO', 0); // mint 0 FOO tokens diff --git a/packages/contracts/test/plugins/token/distribution/merkle-minter.ts b/packages/contracts/test/plugins/token/distribution/merkle-minter.ts index 8b37001fc..c26dd915d 100644 --- a/packages/contracts/test/plugins/token/distribution/merkle-minter.ts +++ b/packages/contracts/test/plugins/token/distribution/merkle-minter.ts @@ -51,7 +51,7 @@ describe('MerkleMinter', function () { totalAmount = amount0.add(amount1); // create a DAO - managingDao = await deployNewDAO(ownerAddress); + managingDao = await deployNewDAO(signers[0]); const GovernanceERC20 = await ethers.getContractFactory('GovernanceERC20'); token = await GovernanceERC20.deploy(managingDao.address, 'GOV', 'GOV', { diff --git a/packages/contracts/test/test-utils/dao.ts b/packages/contracts/test/test-utils/dao.ts index ec4d04ee8..cdf0e1fdf 100644 --- a/packages/contracts/test/test-utils/dao.ts +++ b/packages/contracts/test/test-utils/dao.ts @@ -6,8 +6,10 @@ import { TestERC721__factory, GovernanceERC20__factory, TestERC1155__factory, + DAO__factory, } from '../../typechain'; import {deployWithProxy} from './proxy'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; export const ZERO_BYTES32 = '0x0000000000000000000000000000000000000000000000000000000000000000'; @@ -21,13 +23,13 @@ export const TOKEN_INTERFACE_IDS = { erc1155InterfaceId: '0x4e2312e0', }; -export async function deployNewDAO(ownerAddress: string): Promise { - const DAO = await ethers.getContractFactory('DAO'); - let dao = await deployWithProxy(DAO); +export async function deployNewDAO(signer: SignerWithAddress): Promise { + const DAO = new DAO__factory(signer); + const dao = await deployWithProxy(DAO); await dao.initialize( '0x00', - ownerAddress, + signer.address, ethers.constants.AddressZero, daoExampleURI ); diff --git a/packages/contracts/test/test-utils/repo.ts b/packages/contracts/test/test-utils/repo.ts index fd8ac36f9..5d16b2311 100644 --- a/packages/contracts/test/test-utils/repo.ts +++ b/packages/contracts/test/test-utils/repo.ts @@ -5,25 +5,28 @@ import { PluginRepoFactory, PluginRepo, PluginUUPSUpgradeableSetupV1Mock, -} from '../../../typechain'; + PluginRepo__factory, + PluginUUPSUpgradeableSetupV1Mock__factory, +} from '../../typechain'; import {deployWithProxy} from './proxy'; import {getMergedABI} from '../../utils/abi'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; -export async function deployMockPluginSetup(): Promise { - const PluginSetupMock = await ethers.getContractFactory( - 'PluginUUPSUpgradeableSetupV1Mock' - ); +export async function deployMockPluginSetup( + signer: SignerWithAddress +): Promise { + const PluginSetupMock = new PluginUUPSUpgradeableSetupV1Mock__factory(signer); const pluginSetupMockContract = await PluginSetupMock.deploy(); return pluginSetupMockContract; } export async function deployNewPluginRepo( - ownerAddress: any + maintainer: SignerWithAddress ): Promise { - const PluginRepo = await ethers.getContractFactory('PluginRepo'); + const PluginRepo = new PluginRepo__factory(maintainer); const newPluginRepo = await deployWithProxy(PluginRepo); - await newPluginRepo.initialize(ownerAddress); + await newPluginRepo.initialize(maintainer.address); return newPluginRepo; } diff --git a/packages/contracts/test/test-utils/uups-upgradeable.ts b/packages/contracts/test/test-utils/uups-upgradeable.ts index 1a28de61f..2f55b00cb 100644 --- a/packages/contracts/test/test-utils/uups-upgradeable.ts +++ b/packages/contracts/test/test-utils/uups-upgradeable.ts @@ -40,7 +40,7 @@ export function shouldUpgradeCorrectly( const connect = contract.connect(user); const tx1 = connect.upgradeTo(ethers.constants.AddressZero); const tx2 = connect.upgradeToAndCall(ethers.constants.AddressZero, '0x'); - if (upgradeRevertPermissionMessage == 'DaoUnauthorized') { + if (upgradeRevertPermissionMessage === 'DaoUnauthorized') { await expect(tx1) .to.be.revertedWithCustomError( contract, diff --git a/packages/contracts/test/token/erc20/governance-erc20.ts b/packages/contracts/test/token/erc20/governance-erc20.ts index dac310695..6bfa83b89 100644 --- a/packages/contracts/test/token/erc20/governance-erc20.ts +++ b/packages/contracts/test/token/erc20/governance-erc20.ts @@ -38,7 +38,7 @@ describe('GovernanceERC20', function () { before(async () => { signers = await ethers.getSigners(); - dao = await deployNewDAO(signers[0].address); + dao = await deployNewDAO(signers[0]); GovernanceERC20 = await ethers.getContractFactory('GovernanceERC20'); from = signers[0]; From 758bceb6582ceeca44d11a40bb68cb0b1c389bd4 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Fri, 12 May 2023 14:12:16 +0200 Subject: [PATCH 086/112] fix remaining tests --- packages/contracts/hardhat.config.ts | 3 +++ .../utils/interface-based-registry.ts | 4 ++-- .../plugins/governance/multisig/multisig.ts | 21 +++++++++++++------ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/contracts/hardhat.config.ts b/packages/contracts/hardhat.config.ts index a09fa80c1..83796fbbd 100644 --- a/packages/contracts/hardhat.config.ts +++ b/packages/contracts/hardhat.config.ts @@ -105,6 +105,9 @@ const config: HardhatUserConfig = { collapseNewlines: true, exclude: ['test'], }, + mocha: { + timeout: 60000, // 60 seconds // increase the timeout for subdomain validation tests + }, }; export default config; diff --git a/packages/contracts/test/framework/utils/interface-based-registry.ts b/packages/contracts/test/framework/utils/interface-based-registry.ts index 5cc8a8def..1cd518725 100644 --- a/packages/contracts/test/framework/utils/interface-based-registry.ts +++ b/packages/contracts/test/framework/utils/interface-based-registry.ts @@ -47,7 +47,7 @@ describe('InterfaceBasedRegistry', function () { ); // grant REGISTER_PERMISSION_ID to registrer - dao.grant( + await dao.grant( interfaceBasedRegistryMock.address, ownerAddress, REGISTER_PERMISSION_ID @@ -82,7 +82,7 @@ describe('InterfaceBasedRegistry', function () { }); it('fail to register if the sender lacks the required permissionId', async () => { - dao.revoke( + await dao.revoke( interfaceBasedRegistryMock.address, ownerAddress, REGISTER_PERMISSION_ID diff --git a/packages/contracts/test/plugins/governance/multisig/multisig.ts b/packages/contracts/test/plugins/governance/multisig/multisig.ts index c00385b10..7eb396784 100644 --- a/packages/contracts/test/plugins/governance/multisig/multisig.ts +++ b/packages/contracts/test/plugins/governance/multisig/multisig.ts @@ -776,8 +776,13 @@ describe('Multisig', function () { }); it('should revert if startDate is < than now', async () => { - const timeStamp = (await getTime()) + 500; - await setTimeForNextBlock(timeStamp); + // set next block time & mine a block with this time. + const nextBlockTime = (await getTime()) + 500; + await ethers.provider.send('evm_mine', [nextBlockTime]); + // set next block's timestamp + const nextTimeStamp = nextBlockTime + 500; + await setTimeForNextBlock(nextTimeStamp); + await expect( multisig.createProposal( dummyMetadata, @@ -790,12 +795,16 @@ describe('Multisig', function () { ) ) .to.be.revertedWithCustomError(multisig, 'DateOutOfBounds') - .withArgs(timeStamp, 5); + .withArgs(nextTimeStamp, 5); }); it('should revert if endDate is < than startDate', async () => { - const timeStamp = (await getTime()) + 500; - await setTimeForNextBlock(timeStamp); + // set next block time & mine a block with this time. + const nextBlockTime = (await getTime()) + 500; + await ethers.provider.send('evm_mine', [nextBlockTime]); + // set next block's timestamp + const nextTimeStamp = nextBlockTime + 500; + await setTimeForNextBlock(nextTimeStamp); await expect( multisig.createProposal( dummyMetadata, @@ -808,7 +817,7 @@ describe('Multisig', function () { ) ) .to.be.revertedWithCustomError(multisig, 'DateOutOfBounds') - .withArgs(timeStamp, 5); + .withArgs(nextTimeStamp, 5); }); }); From fec63aa99a8da883c73ca21d3e8e8da322a8c748 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Fri, 12 May 2023 14:17:57 +0200 Subject: [PATCH 087/112] fix subgraph --- .github/workflows/subgraph-tests.yml | 8 +++++--- packages/subgraph/package.json | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/subgraph-tests.yml b/.github/workflows/subgraph-tests.yml index 4c5328f4e..a6cf82c2c 100644 --- a/.github/workflows/subgraph-tests.yml +++ b/.github/workflows/subgraph-tests.yml @@ -33,7 +33,7 @@ jobs: - name: Install node uses: actions/setup-node@v3 with: - cache: "yarn" + cache: 'yarn' node-version: 16 - name: Install dependencies run: yarn install --pure-lockfile @@ -52,16 +52,18 @@ jobs: - name: Install node uses: actions/setup-node@v3 with: - cache: "yarn" + cache: 'yarn' node-version: 16 - name: Install dependencies run: yarn + - name: Build contracts-versions + run: yarn run build:contracts-versions - name: Build contracts run: yarn run build:contracts - name: Build manifest run: yarn run manifest env: - NETWORK_NAME: "goerli" + NETWORK_NAME: 'goerli' - name: Build run: yarn run build - name: Run Tests diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json index 06446ebcc..7a9962794 100644 --- a/packages/subgraph/package.json +++ b/packages/subgraph/package.json @@ -7,6 +7,7 @@ "scripts": { "lint": "eslint . --ext .ts", "build:contracts": "cd ../contracts && yarn build", + "build:contracts-versions": "cd ../contracts-versions && yarn build", "manifest": "scripts/build-manifest.sh", "extend:schema": "yarn ts-node tests/schema-extender.ts", "build": "scripts/build-subgraph.sh && yarn extend:schema", From 559a756f880466d32310001b9c67b22574f8e2e1 Mon Sep 17 00:00:00 2001 From: Rekard0 <5880388+Rekard0@users.noreply.github.com> Date: Fri, 12 May 2023 14:26:03 +0200 Subject: [PATCH 088/112] add ref depth --- .github/workflows/subgraph-tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/subgraph-tests.yml b/.github/workflows/subgraph-tests.yml index a6cf82c2c..7593fcd8b 100644 --- a/.github/workflows/subgraph-tests.yml +++ b/.github/workflows/subgraph-tests.yml @@ -49,6 +49,9 @@ jobs: working-directory: ${{env.working-directory}} steps: - uses: actions/checkout@v2 + with: + ref: ${{ github.ref }} + fetch-depth: 0 - name: Install node uses: actions/setup-node@v3 with: From df4a9e3381ee5cb7dbb7a734c77e1bb5f1df2267 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 12 May 2023 15:52:40 +0200 Subject: [PATCH 089/112] fix: replacing getContractFactory and getContractAt by typechain factory calls and added missing awaits --- packages/contracts/deploy/helpers.ts | 50 ++++++++------- .../new/00_managing-dao/00_managing-dao.ts | 12 ++-- .../01_managing-dao-permissions.ts | 17 ++--- .../00_managing-dao/20_set-dao-permission.ts | 8 ++- .../new/00_managing-dao/99_verify_step.ts | 11 ++-- .../new/10_framework/01_ens_subdomains.ts | 27 ++++---- .../02_ens_subdomain_registrars.ts | 29 +++++---- .../new/10_framework/10_dao-registry.ts | 8 +-- .../10_framework/20_plugin-repo-registry.ts | 8 +-- .../new/10_framework/30_repo-factory.ts | 6 +- .../10_framework/31_repo-factory_conclude.ts | 4 +- .../10_framework/40_plugin_setup_processor.ts | 6 +- .../deploy/new/10_framework/50_dao-factory.ts | 6 +- .../10_framework/51_dao-factory-conclude.ts | 4 +- .../new/10_framework/99_verifiy_step.ts | 61 +++++++++--------- .../new/20_permissions/00_ens-permissions.ts | 8 ++- .../10_dao-registry-permissions.ts | 8 ++- .../20_plugin-registrty-permissions.ts | 8 ++- .../deploy/new/20_permissions/99_verify.ts | 9 ++- .../00_addresslist_voting_setup.ts | 6 +- .../01_addresslist_voting_setup_conclude.ts | 5 +- .../00_plugin-setups/10_token_voting_setup.ts | 6 +- .../00_plugin-setups/20_admin_setup.ts | 6 +- .../00_plugin-setups/30_multisig_setup.ts | 6 +- .../00_plugin-setups/40_placeholder_setup.ts | 6 +- .../00_grant-permissions.ts | 7 ++- ...0_register-managing-dao-on-dao-registry.ts | 23 +++---- .../30_install-multisig-on-managing-dao.ts | 19 +++--- .../40_revoke-permissions.ts | 7 ++- .../99_verify_step.ts | 20 +++--- .../test/core/dao/callback-handler.ts | 9 ++- packages/contracts/test/core/dao/dao.ts | 63 ++++++++++--------- .../core/permission/permission-manager.ts | 8 ++- .../plugin/parameter-scoping-condition.ts | 10 +-- .../test/core/plugin/shared-plugin.ts | 36 +++++------ .../contracts/test/deploy/managing-dao.ts | 44 +++++++------ .../test/framework/dao/dao-factory.ts | 33 +++++----- .../test/framework/dao/dao-registry.ts | 9 ++- .../framework/plugin/plugin-repo-factory.ts | 8 ++- .../test/framework/plugin/plugin-repo.ts | 5 +- .../plugin/plugin-setup-processor.ts | 28 +++++---- .../utils/ens/ens-subdomain-registry.ts | 38 ++++++----- .../utils/interface-based-registry.ts | 8 ++- .../test/framework/utils/registry-utils.ts | 12 ++-- .../test/framework/utils/token-factory.ts | 22 ++++--- .../counter-example/counter-plugin-setup.ts | 23 +++---- .../plugins/governance/admin/admin-setup.ts | 12 ++-- .../test/plugins/governance/admin/admin.ts | 5 +- .../addresslist/addresslist-voting-setup.ts | 18 +++--- .../majority-voting/majority-voting.ts | 5 +- .../token/token-voting-setup.ts | 44 +++++++------ .../majority-voting/token/token-voting.ts | 4 +- .../governance/multisig/multisig-setup.ts | 8 +-- .../token/distribution/merkle-distributor.ts | 8 +-- .../token/distribution/merkle-minter.ts | 11 ++-- .../test/plugins/utils/addresslist.ts | 6 +- .../contracts/test/plugins/utils/ratio.ts | 4 +- .../contracts/test/test-utils/conditions.ts | 5 +- packages/contracts/test/test-utils/dao.ts | 3 +- packages/contracts/test/test-utils/ens.ts | 15 ++--- packages/contracts/test/test-utils/repo.ts | 8 +-- .../test/test-utils/uups-upgradeable.ts | 6 +- .../test/token/erc20/governance-erc20.ts | 2 +- .../token/erc20/governance-wrapped-erc20.ts | 10 ++- 64 files changed, 508 insertions(+), 423 deletions(-) diff --git a/packages/contracts/deploy/helpers.ts b/packages/contracts/deploy/helpers.ts index ef64f8fdd..98dbe94d6 100644 --- a/packages/contracts/deploy/helpers.ts +++ b/packages/contracts/deploy/helpers.ts @@ -8,9 +8,10 @@ import {findEvent} from '../utils/event'; import {getMergedABI} from '../utils/abi'; import {Operation} from '../utils/types'; import {VersionTag} from '../test/test-utils/psp/types'; -import {PluginRepo__factory} from '../typechain'; +import {ENSRegistry__factory, PluginRepo__factory} from '../typechain'; import {VersionCreatedEvent} from '../typechain/PluginRepo'; import {PluginRepoRegisteredEvent} from '../typechain/PluginRepoRegistry'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; // TODO: Add support for L2 such as Arbitrum. (https://discuss.ens.domains/t/register-using-layer-2/688) // Make sure you own the ENS set in the {{NETWORK}}_ENS_DOMAIN variable in .env @@ -124,12 +125,12 @@ export async function updateActiveContractsJSON(payload: { export async function detemineDeployerNextAddress( index: number, - deployer: any + deployer: SignerWithAddress ): Promise { const [owner] = await ethers.getSigners(); const nonce = await owner.getTransactionCount(); const futureAddress = ethers.utils.getContractAddress({ - from: deployer, + from: deployer.address, nonce: nonce + index, }); return futureAddress; @@ -140,12 +141,15 @@ export async function createPluginRepo( pluginName: string ): Promise { const {network} = hre; + const signers = await ethers.getSigners(); + const pluginDomain = process.env[`${network.name.toUpperCase()}_PLUGIN_ENS_DOMAIN`] || ''; if ( await isENSDomainRegistered( `${pluginName}.${pluginDomain}`, - await getENSAddress(hre) + await getENSAddress(hre), + signers[0] ) ) { // not beeing able to register the plugin repo means that something is not right with the framework deployment used. @@ -153,8 +157,6 @@ export async function createPluginRepo( throw new Error(`${pluginName} is already present! Aborting...`); } - const signers = await ethers.getSigners(); - const pluginRepoFactoryAddress = await getContractAddress( 'PluginRepoFactory', hre @@ -416,11 +418,12 @@ export async function managePermissions( export async function isENSDomainRegistered( domain: string, - ensRegistryAddress: string + ensRegistryAddress: string, + signer: SignerWithAddress ): Promise { - const ensRegistryContract = await ethers.getContractAt( - 'ENSRegistry', - ensRegistryAddress + const ensRegistryContract = ENSRegistry__factory.connect( + ensRegistryAddress, + signer ); return ensRegistryContract.recordExists(ethers.utils.namehash(domain)); @@ -458,7 +461,7 @@ export async function getPublicResolverAddress( export async function registerSubnodeRecord( domain: string, - owner: string, + owner: SignerWithAddress, ensRegistryAddress: string, publicResolver: string ): Promise { @@ -466,15 +469,14 @@ export async function registerSubnodeRecord( const subdomain = domainSplitted.splice(0, 1)[0]; const parentDomain = domainSplitted.join('.'); - const ensRegistryContract = await ethers.getContractAt( - 'ENSRegistry', - ensRegistryAddress + const ensRegistryContract = ENSRegistry__factory.connect( + ensRegistryAddress, + owner ); - const tx = await ensRegistryContract.setSubnodeRecord( ethers.utils.namehash(parentDomain), ethers.utils.keccak256(ethers.utils.toUtf8Bytes(subdomain)), - owner, + owner.address, publicResolver, 0 ); @@ -491,9 +493,11 @@ export async function transferSubnodeRecord( const subdomain = domainSplitted.splice(0, 1)[0]; const parentDomain = domainSplitted.join('.'); - const ensRegistryContract = await ethers.getContractAt( - 'ENSRegistry', - ensRegistryAddress + const [deployer] = await ethers.getSigners(); + + const ensRegistryContract = ENSRegistry__factory.connect( + ensRegistryAddress, + deployer ); const tx = await ensRegistryContract.setSubnodeOwner( @@ -514,9 +518,11 @@ export async function transferSubnodeChain( currentOwner: string, ensRegistryAddress: string ): Promise { - const ensRegistryContract = await ethers.getContractAt( - 'ENSRegistry', - ensRegistryAddress + const [deployer] = await ethers.getSigners(); + + const ensRegistryContract = ENSRegistry__factory.connect( + ensRegistryAddress, + deployer ); const daoDomainSplitted = fullDomain.split('.').reverse(); diff --git a/packages/contracts/deploy/new/00_managing-dao/00_managing-dao.ts b/packages/contracts/deploy/new/00_managing-dao/00_managing-dao.ts index 42404ed3b..01d87909b 100644 --- a/packages/contracts/deploy/new/00_managing-dao/00_managing-dao.ts +++ b/packages/contracts/deploy/new/00_managing-dao/00_managing-dao.ts @@ -9,18 +9,18 @@ import daoArtifactJson from '../../../artifacts/src/core/dao/DAO.sol/DAO.json'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log(`\nDeploying ManagingDao.`); - const {deployments, getNamedAccounts, ethers} = hre; + const {deployments, ethers} = hre; const {deploy} = deployments; - const {deployer} = await getNamedAccounts(); + const [deployer] = await ethers.getSigners(); console.log( - `ManagingDAO will be owned by the (Deployer: ${deployer}) temporarily, while the entire framework is getting deployed.` + + `ManagingDAO will be owned by the (Deployer: ${deployer.address}) temporarily, while the entire framework is getting deployed.` + ` At the final step when Multisig is available, it will be installed on managingDAO and all roles for the Deployer will be revoked.` ); const initializeParams = { metadata: '0x', - initialOwner: deployer, + initialOwner: deployer.address, trustedForwarder: ethers.constants.AddressZero, daoURI: '0x', }; @@ -29,11 +29,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { await deploy('DAO', { contract: daoArtifactData, - from: deployer, + from: deployer.address, args: [], log: true, proxy: { - owner: deployer, + owner: deployer.address, proxyContract: 'ERC1967Proxy', proxyArgs: ['{implementation}', '{data}'], execute: { diff --git a/packages/contracts/deploy/new/00_managing-dao/01_managing-dao-permissions.ts b/packages/contracts/deploy/new/00_managing-dao/01_managing-dao-permissions.ts index e2acb4f79..5ec2330e6 100644 --- a/packages/contracts/deploy/new/00_managing-dao/01_managing-dao-permissions.ts +++ b/packages/contracts/deploy/new/00_managing-dao/01_managing-dao-permissions.ts @@ -4,19 +4,20 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; import {Operation} from '../../../utils/types'; import {getContractAddress, managePermissions} from '../../helpers'; +import {DAO__factory} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {getNamedAccounts, ethers} = hre; - const {deployer} = await getNamedAccounts(); + const {ethers} = hre; + const [deployer] = await ethers.getSigners(); + + console.log(`Granting ${deployer.address} temp execute permissions`); - console.log(`Granting ${deployer} temp execute permissions`); // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); - // Get `DAO` contract. - const managingDaoContract = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress + const managingDaoContract = DAO__factory.connect( + managingDAOAddress, + deployer ); // grant the deployer execute permissions during deployment. This will be revoked in 40_finalize-managing-dao/40_revoke-permissions @@ -24,7 +25,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { { operation: Operation.Grant, where: {name: 'DAO', address: managingDAOAddress}, - who: {name: 'Deployer', address: deployer}, + who: {name: 'Deployer', address: deployer.address}, permission: 'EXECUTE_PERMISSION', }, ]); diff --git a/packages/contracts/deploy/new/00_managing-dao/20_set-dao-permission.ts b/packages/contracts/deploy/new/00_managing-dao/20_set-dao-permission.ts index 6621811b8..0454a8a04 100644 --- a/packages/contracts/deploy/new/00_managing-dao/20_set-dao-permission.ts +++ b/packages/contracts/deploy/new/00_managing-dao/20_set-dao-permission.ts @@ -7,18 +7,20 @@ import { getContractAddress, managePermissions, } from '../../helpers'; +import {DAO__factory} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log('\nSetting ManagingDao permissions.'); const {ethers} = hre; + const [deployer] = await ethers.getSigners(); // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); // Get `DAO` contract. - const managingDaoContract = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress + const managingDaoContract = DAO__factory.connect( + managingDAOAddress, + deployer ); // Set all the permission needed for a DAO to operate normally as if it was created via DAOFactory. diff --git a/packages/contracts/deploy/new/00_managing-dao/99_verify_step.ts b/packages/contracts/deploy/new/00_managing-dao/99_verify_step.ts index 323948ef7..4343aa9c4 100644 --- a/packages/contracts/deploy/new/00_managing-dao/99_verify_step.ts +++ b/packages/contracts/deploy/new/00_managing-dao/99_verify_step.ts @@ -7,26 +7,27 @@ import { DAO_PERMISSIONS, getContractAddress, } from '../../helpers'; +import {DAO__factory} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log('\nVerifying managing DAO deployment.'); const {getNamedAccounts, ethers} = hre; - const {deployer} = await getNamedAccounts(); + const [deployer] = await ethers.getSigners(); // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); // Get `DAO` contract. - const managingDaoContract = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress + const managingDaoContract = DAO__factory.connect( + managingDAOAddress, + deployer ); // Check that deployer has root permission. await checkPermission(managingDaoContract, { operation: Operation.Grant, where: {name: 'ManagingDAO', address: managingDAOAddress}, - who: {name: 'Deployer', address: deployer}, + who: {name: 'Deployer', address: deployer.address}, permission: 'ROOT_PERMISSION', }); diff --git a/packages/contracts/deploy/new/10_framework/01_ens_subdomains.ts b/packages/contracts/deploy/new/10_framework/01_ens_subdomains.ts index f1f318e54..946687737 100644 --- a/packages/contracts/deploy/new/10_framework/01_ens_subdomains.ts +++ b/packages/contracts/deploy/new/10_framework/01_ens_subdomains.ts @@ -7,10 +7,11 @@ import { registerSubnodeRecord, transferSubnodeChain, } from '../../helpers'; +import {ENSRegistry__factory} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {ethers, network, getNamedAccounts} = hre; - const {deployer} = await getNamedAccounts(); + const {ethers, network} = hre; + const [deployer] = await ethers.getSigners(); // Get ENS subdomains const daoDomain = @@ -23,9 +24,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { } const ensRegistryAddress = await getENSAddress(hre); - const ensRegistryContract = await ethers.getContractAt( - 'ENSRegistry', - ensRegistryAddress + const ensRegistryContract = ENSRegistry__factory.connect( + ensRegistryAddress, + deployer ); // Check if domains are owned by the managingDAO @@ -43,8 +44,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { await getPublicResolverAddress(hre) ); } - if (daoDomainOwnerAddress != deployer) { - throw new Error(`${daoDomain} is not owned by deployer: ${deployer}.`); + if (daoDomainOwnerAddress != deployer.address) { + throw new Error( + `${daoDomain} is not owned by deployer: ${deployer.address}.` + ); } let pluginDomainOwnerAddress = await ensRegistryContract.owner(pluginNode); @@ -57,8 +60,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { await getPublicResolverAddress(hre) ); } - if (pluginDomainOwnerAddress != deployer) { - throw new Error(`${pluginDomain} is not owned by deployer: ${deployer}.`); + if (pluginDomainOwnerAddress != deployer.address) { + throw new Error( + `${pluginDomain} is not owned by deployer: ${deployer.address}.` + ); } // Registration is now complete. Lets move the ownership of all domains to the managing DAO @@ -66,13 +71,13 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { await transferSubnodeChain( daoDomain, managingDAOAddress, - deployer, + deployer.address, await getENSAddress(hre) ); await transferSubnodeChain( pluginDomain, managingDAOAddress, - deployer, + deployer.address, await getENSAddress(hre) ); }; diff --git a/packages/contracts/deploy/new/10_framework/02_ens_subdomain_registrars.ts b/packages/contracts/deploy/new/10_framework/02_ens_subdomain_registrars.ts index c5c939d54..0031658ab 100644 --- a/packages/contracts/deploy/new/10_framework/02_ens_subdomain_registrars.ts +++ b/packages/contracts/deploy/new/10_framework/02_ens_subdomain_registrars.ts @@ -1,19 +1,18 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; -import {DAO} from '../../../typechain'; +import {DAO, ENSRegistry__factory} from '../../../typechain'; import {getContractAddress, getENSAddress} from '../../helpers'; +import {DAO__factory} from '../../../typechain/osx-versions/v1_2_0/contracts/core/dao/DAO.sol'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {deployments, getNamedAccounts, ethers, network} = hre; + const {deployments, ethers, network} = hre; const {deploy} = deployments; - const {deployer} = await getNamedAccounts(); + + const [deployer] = await ethers.getSigners(); // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); - const managingDAO: DAO = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress - ); + const managingDAO = DAO__factory.connect(managingDAOAddress, deployer); const ensRegistryAddress = await getENSAddress(hre); @@ -30,11 +29,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { await deploy('DAO_ENSSubdomainRegistrar', { contract: 'ENSSubdomainRegistrar', - from: deployer, + from: deployer.address, args: [], log: true, proxy: { - owner: deployer, + owner: deployer.address, proxyContract: 'ERC1967Proxy', proxyArgs: ['{implementation}', '{data}'], execute: { @@ -54,11 +53,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { await deploy('Plugin_ENSSubdomainRegistrar', { contract: 'ENSSubdomainRegistrar', - from: deployer, + from: deployer.address, args: [], log: true, proxy: { - owner: deployer, + owner: deployer.address, proxyContract: 'ERC1967Proxy', proxyArgs: ['{implementation}', '{data}'], execute: { @@ -76,9 +75,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { hre ); - const ensRegistryContract = await ethers.getContractAt( - 'ENSRegistry', - ensRegistryAddress + const ensRegistryContract = ENSRegistry__factory.connect( + ensRegistryAddress, + deployer ); const daoRegistrarTX = @@ -93,7 +92,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { ); const deployerTX = await ensRegistryContract.populateTransaction.setApprovalForAll( - deployer, + deployer.address, true ); diff --git a/packages/contracts/deploy/new/10_framework/10_dao-registry.ts b/packages/contracts/deploy/new/10_framework/10_dao-registry.ts index 779008b22..92e29c862 100644 --- a/packages/contracts/deploy/new/10_framework/10_dao-registry.ts +++ b/packages/contracts/deploy/new/10_framework/10_dao-registry.ts @@ -4,9 +4,9 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {getContractAddress} from '../../helpers'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {deployments, getNamedAccounts} = hre; + const {deployments, ethers} = hre; const {deploy} = deployments; - const {deployer} = await getNamedAccounts(); + const [deployer] = await ethers.getSigners(); // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); @@ -18,11 +18,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { ); await deploy('DAORegistry', { - from: deployer, + from: deployer.address, args: [], log: true, proxy: { - owner: deployer, + owner: deployer.address, proxyContract: 'ERC1967Proxy', proxyArgs: ['{implementation}', '{data}'], execute: { diff --git a/packages/contracts/deploy/new/10_framework/20_plugin-repo-registry.ts b/packages/contracts/deploy/new/10_framework/20_plugin-repo-registry.ts index 185f66a43..7272a1800 100644 --- a/packages/contracts/deploy/new/10_framework/20_plugin-repo-registry.ts +++ b/packages/contracts/deploy/new/10_framework/20_plugin-repo-registry.ts @@ -4,9 +4,9 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {getContractAddress} from '../../helpers'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {deployments, getNamedAccounts} = hre; + const {deployments, ethers} = hre; const {deploy} = deployments; - const {deployer} = await getNamedAccounts(); + const [deployer] = await ethers.getSigners(); // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); @@ -18,11 +18,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { ); await deploy('PluginRepoRegistry', { - from: deployer, + from: deployer.address, args: [], log: true, proxy: { - owner: deployer, + owner: deployer.address, proxyContract: 'ERC1967Proxy', proxyArgs: ['{implementation}', '{data}'], execute: { diff --git a/packages/contracts/deploy/new/10_framework/30_repo-factory.ts b/packages/contracts/deploy/new/10_framework/30_repo-factory.ts index e39e412d0..c86e0ce3e 100644 --- a/packages/contracts/deploy/new/10_framework/30_repo-factory.ts +++ b/packages/contracts/deploy/new/10_framework/30_repo-factory.ts @@ -4,9 +4,9 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {getContractAddress} from '../../helpers'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {deployments, getNamedAccounts} = hre; + const {deployments, ethers} = hre; const {deploy} = deployments; - const {deployer} = await getNamedAccounts(); + const [deployer] = await ethers.getSigners(); // Get `PluginRepoRegistry` address. const pluginRepoRegistryAddress = await getContractAddress( @@ -15,7 +15,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { ); await deploy('PluginRepoFactory', { - from: deployer, + from: deployer.address, args: [pluginRepoRegistryAddress], log: true, }); diff --git a/packages/contracts/deploy/new/10_framework/31_repo-factory_conclude.ts b/packages/contracts/deploy/new/10_framework/31_repo-factory_conclude.ts index 9bedd9635..95f71dd83 100644 --- a/packages/contracts/deploy/new/10_framework/31_repo-factory_conclude.ts +++ b/packages/contracts/deploy/new/10_framework/31_repo-factory_conclude.ts @@ -5,8 +5,8 @@ import {PluginRepoFactory__factory} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log(`Concluding Plugin Repo Registry deployment.\n`); - const [deployer] = await hre.ethers.getSigners(); - const {deployments} = hre; + const {deployments, ethers} = hre; + const [deployer] = await ethers.getSigners(); const pluginRepoFactoryDeployment = await deployments.get( 'PluginRepoFactory' diff --git a/packages/contracts/deploy/new/10_framework/40_plugin_setup_processor.ts b/packages/contracts/deploy/new/10_framework/40_plugin_setup_processor.ts index 064e6bf33..b4eab6faa 100644 --- a/packages/contracts/deploy/new/10_framework/40_plugin_setup_processor.ts +++ b/packages/contracts/deploy/new/10_framework/40_plugin_setup_processor.ts @@ -4,9 +4,9 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {getContractAddress} from '../../helpers'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {deployments, getNamedAccounts} = hre; + const {deployments, ethers} = hre; const {deploy} = deployments; - const {deployer} = await getNamedAccounts(); + const [deployer] = await ethers.getSigners(); // Get `PluginRepoRegistry` address. const pluginRepoRegistryAddress = await getContractAddress( @@ -15,7 +15,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { ); await deploy('PluginSetupProcessor', { - from: deployer, + from: deployer.address, args: [pluginRepoRegistryAddress], log: true, }); diff --git a/packages/contracts/deploy/new/10_framework/50_dao-factory.ts b/packages/contracts/deploy/new/10_framework/50_dao-factory.ts index 43b6f583c..66f718d76 100644 --- a/packages/contracts/deploy/new/10_framework/50_dao-factory.ts +++ b/packages/contracts/deploy/new/10_framework/50_dao-factory.ts @@ -4,9 +4,9 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {getContractAddress} from '../../helpers'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {deployments, getNamedAccounts} = hre; + const {deployments, ethers} = hre; const {deploy} = deployments; - const {deployer} = await getNamedAccounts(); + const [deployer] = await ethers.getSigners(); // Get `DAORegistry` address. const daoRegistryAddress = await getContractAddress('DAORegistry', hre); @@ -18,7 +18,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { ); await deploy('DAOFactory', { - from: deployer, + from: deployer.address, args: [daoRegistryAddress, pluginSetupProcessorAddress], log: true, }); diff --git a/packages/contracts/deploy/new/10_framework/51_dao-factory-conclude.ts b/packages/contracts/deploy/new/10_framework/51_dao-factory-conclude.ts index fe690f934..8909815b6 100644 --- a/packages/contracts/deploy/new/10_framework/51_dao-factory-conclude.ts +++ b/packages/contracts/deploy/new/10_framework/51_dao-factory-conclude.ts @@ -4,9 +4,9 @@ import {DAOFactory__factory} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log(`Concluding DAOFactory deployment.\n`); - const [deployer] = await hre.ethers.getSigners(); + const {deployments, ethers} = hre; - const {deployments} = hre; + const [deployer] = await ethers.getSigners(); const DAOFactoryDeployment = await deployments.get('DAOFactory'); const daoFactory = DAOFactory__factory.connect( diff --git a/packages/contracts/deploy/new/10_framework/99_verifiy_step.ts b/packages/contracts/deploy/new/10_framework/99_verifiy_step.ts index 5654139c9..f9801900c 100644 --- a/packages/contracts/deploy/new/10_framework/99_verifiy_step.ts +++ b/packages/contracts/deploy/new/10_framework/99_verifiy_step.ts @@ -2,11 +2,21 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; import {checkSetManagingDao, getContractAddress} from '../../helpers'; +import { + DAOFactory__factory, + DAORegistry__factory, + ENSRegistry__factory, + ENSSubdomainRegistrar__factory, + PluginRepoFactory__factory, + PluginRepoRegistry__factory, + PluginSetupProcessor__factory, +} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log('\nVerifying framework deployment.'); const {ethers} = hre; + const [deployer] = await ethers.getSigners(); // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); @@ -16,18 +26,15 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { 'DAO_ENSSubdomainRegistrar', hre ); - const DAOENSSubdomainRegistrar = await ethers.getContractAt( - 'ENSSubdomainRegistrar', - DAOENSSubdomainRegistrarAddress + const DAOENSSubdomainRegistrar = ENSSubdomainRegistrar__factory.connect( + DAOENSSubdomainRegistrarAddress, + deployer ); await checkSetManagingDao(DAOENSSubdomainRegistrar, managingDAOAddress); // scope to reuse same const again { const ensAddr = await DAOENSSubdomainRegistrar.ens(); - const ensRegistryContract = await ethers.getContractAt( - 'ENSRegistry', - ensAddr - ); + const ensRegistryContract = ENSRegistry__factory.connect(ensAddr, deployer); const isApprovedForAll = await ensRegistryContract.isApprovedForAll( managingDAOAddress, DAOENSSubdomainRegistrarAddress @@ -54,18 +61,15 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { 'Plugin_ENSSubdomainRegistrar', hre ); - const PluginENSSubdomainRegistrar = await ethers.getContractAt( - 'ENSSubdomainRegistrar', - PluginENSSubdomainRegistrarAddress + const PluginENSSubdomainRegistrar = ENSSubdomainRegistrar__factory.connect( + PluginENSSubdomainRegistrarAddress, + deployer ); await checkSetManagingDao(PluginENSSubdomainRegistrar, managingDAOAddress); // scope to reuse same const again { const ensAddr = await PluginENSSubdomainRegistrar.ens(); - const ensRegistryContract = await ethers.getContractAt( - 'ENSRegistry', - ensAddr - ); + const ensRegistryContract = ENSRegistry__factory.connect(ensAddr, deployer); const isApprovedForAll = await ensRegistryContract.isApprovedForAll( managingDAOAddress, PluginENSSubdomainRegistrarAddress @@ -89,9 +93,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // VERIFYING DAO REGISTRY const DAORegistryAddress = await getContractAddress('DAORegistry', hre); - const DAORegistry = await ethers.getContractAt( - 'DAORegistry', - DAORegistryAddress + const DAORegistry = DAORegistry__factory.connect( + DAORegistryAddress, + deployer ); await checkSetManagingDao(DAORegistry, managingDAOAddress); // scope to reuse same const again @@ -109,9 +113,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { 'PluginRepoRegistry', hre ); - const PluginRepoRegistry = await ethers.getContractAt( - 'PluginRepoRegistry', - PluginRepoRegistryAddress + const PluginRepoRegistry = PluginRepoRegistry__factory.connect( + PluginRepoRegistryAddress, + deployer ); await checkSetManagingDao(PluginRepoRegistry, managingDAOAddress); // scope to reuse same const again @@ -130,9 +134,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { 'PluginRepoFactory', hre ); - const PluginRepoFactory = await ethers.getContractAt( - 'PluginRepoFactory', - PluginRepoFactoryAddress + const PluginRepoFactory = PluginRepoFactory__factory.connect( + PluginRepoFactoryAddress, + deployer ); // scope to reuse same const again { @@ -150,9 +154,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { 'PluginSetupProcessor', hre ); - const PluginSetupProcessor = await ethers.getContractAt( - 'PluginSetupProcessor', - PluginSetupProcessorAddress + const PluginSetupProcessor = PluginSetupProcessor__factory.connect( + PluginSetupProcessorAddress, + deployer ); // scope to reuse same const again { @@ -167,10 +171,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // VERIFYING DAO FACTORY const DAOFactoryAddress = await getContractAddress('DAOFactory', hre); - const DAOFactory = await ethers.getContractAt( - 'DAOFactory', - DAOFactoryAddress - ); + const DAOFactory = DAOFactory__factory.connect(DAOFactoryAddress, deployer); // scope to reuse same const again { const SetDAORegistryAddress = await DAOFactory.daoRegistry(); diff --git a/packages/contracts/deploy/new/20_permissions/00_ens-permissions.ts b/packages/contracts/deploy/new/20_permissions/00_ens-permissions.ts index ce660cde9..841cfe0e8 100644 --- a/packages/contracts/deploy/new/20_permissions/00_ens-permissions.ts +++ b/packages/contracts/deploy/new/20_permissions/00_ens-permissions.ts @@ -3,19 +3,21 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {Operation} from '../../../utils/types'; import {getContractAddress, managePermissions} from '../../helpers'; +import {DAO__factory} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log(`\nSetting framework permission.`); const {ethers} = hre; + const [deployer] = await ethers.getSigners(); // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); // Get `DAO` contract. - const managingDaoContract = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress + const managingDaoContract = DAO__factory.connect( + managingDAOAddress, + deployer ); // Get `DAORegistry` address. diff --git a/packages/contracts/deploy/new/20_permissions/10_dao-registry-permissions.ts b/packages/contracts/deploy/new/20_permissions/10_dao-registry-permissions.ts index f969ed738..7700b6cd9 100644 --- a/packages/contracts/deploy/new/20_permissions/10_dao-registry-permissions.ts +++ b/packages/contracts/deploy/new/20_permissions/10_dao-registry-permissions.ts @@ -3,17 +3,19 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {Operation} from '../../../utils/types'; import {getContractAddress, managePermissions} from '../../helpers'; +import {DAO__factory} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const {ethers} = hre; + const [deployer] = await ethers.getSigners(); // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); // Get `DAO` contract. - const managingDaoContract = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress + const managingDaoContract = DAO__factory.connect( + managingDAOAddress, + deployer ); // Get `DAORegistry` address. diff --git a/packages/contracts/deploy/new/20_permissions/20_plugin-registrty-permissions.ts b/packages/contracts/deploy/new/20_permissions/20_plugin-registrty-permissions.ts index 68c13f030..8689a62bf 100644 --- a/packages/contracts/deploy/new/20_permissions/20_plugin-registrty-permissions.ts +++ b/packages/contracts/deploy/new/20_permissions/20_plugin-registrty-permissions.ts @@ -3,17 +3,19 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {Operation} from '../../../utils/types'; import {getContractAddress, managePermissions} from '../../helpers'; +import {DAO__factory} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const {ethers} = hre; + const [deployer] = await ethers.getSigners(); // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); // Get `DAO` contract. - const managingDaoContract = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress + const managingDaoContract = DAO__factory.connect( + managingDAOAddress, + deployer ); // Get `PluginRepoRegistry` address. diff --git a/packages/contracts/deploy/new/20_permissions/99_verify.ts b/packages/contracts/deploy/new/20_permissions/99_verify.ts index c4b6d93ef..8b0413afd 100644 --- a/packages/contracts/deploy/new/20_permissions/99_verify.ts +++ b/packages/contracts/deploy/new/20_permissions/99_verify.ts @@ -3,19 +3,22 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; import {Operation} from '../../../utils/types'; import {checkPermission, getContractAddress} from '../../helpers'; +import {DAO__factory} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log('\nVerifying permissions'); const {ethers} = hre; + const [deployer] = await ethers.getSigners(); + // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); // Get `DAO` contract. - const managingDaoContract = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress + const managingDaoContract = DAO__factory.connect( + managingDAOAddress, + deployer ); // Get `DAORegistry` address. diff --git a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/00_addresslist_voting_setup.ts b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/00_addresslist_voting_setup.ts index f09153c7e..537e5acd2 100644 --- a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/00_addresslist_voting_setup.ts +++ b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/00_addresslist_voting_setup.ts @@ -4,12 +4,12 @@ import {DeployFunction} from 'hardhat-deploy/types'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log(`\nDeploying plugins.`); - const {deployments, getNamedAccounts} = hre; + const {deployments, ethers} = hre; const {deploy} = deployments; - const {deployer} = await getNamedAccounts(); + const [deployer] = await ethers.getSigners(); await deploy('AddresslistVotingSetup', { - from: deployer, + from: deployer.address, args: [], log: true, }); diff --git a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/01_addresslist_voting_setup_conclude.ts b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/01_addresslist_voting_setup_conclude.ts index 46bc12ddf..5dbed7d98 100644 --- a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/01_addresslist_voting_setup_conclude.ts +++ b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/01_addresslist_voting_setup_conclude.ts @@ -5,9 +5,8 @@ import {AddresslistVotingSetup__factory} from '../../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log(`Concluding addresslist voting setup deployment.\n`); - const [deployer] = await hre.ethers.getSigners(); - - const {deployments, network} = hre; + const {deployments, network, ethers} = hre; + const [deployer] = await ethers.getSigners(); const AddresslistVotingSetupDeployment = await deployments.get( 'AddresslistVotingSetup' diff --git a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/10_token_voting_setup.ts b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/10_token_voting_setup.ts index d4c06db48..d89345c51 100644 --- a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/10_token_voting_setup.ts +++ b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/10_token_voting_setup.ts @@ -2,12 +2,12 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; import {DeployFunction} from 'hardhat-deploy/types'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {deployments, getNamedAccounts} = hre; + const {deployments, ethers} = hre; const {deploy} = deployments; - const {deployer} = await getNamedAccounts(); + const [deployer] = await ethers.getSigners(); await deploy('TokenVotingSetup', { - from: deployer, + from: deployer.address, args: [], log: true, }); diff --git a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/20_admin_setup.ts b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/20_admin_setup.ts index 8e41a4953..004a13a9f 100644 --- a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/20_admin_setup.ts +++ b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/20_admin_setup.ts @@ -2,12 +2,12 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; import {DeployFunction} from 'hardhat-deploy/types'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {deployments, getNamedAccounts} = hre; + const {deployments, ethers} = hre; const {deploy} = deployments; - const {deployer} = await getNamedAccounts(); + const [deployer] = await ethers.getSigners(); await deploy('AdminSetup', { - from: deployer, + from: deployer.address, args: [], log: true, }); diff --git a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/30_multisig_setup.ts b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/30_multisig_setup.ts index bcedfb486..873c31ac4 100644 --- a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/30_multisig_setup.ts +++ b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/30_multisig_setup.ts @@ -2,12 +2,12 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; import {DeployFunction} from 'hardhat-deploy/types'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {deployments, getNamedAccounts} = hre; + const {deployments, ethers} = hre; const {deploy} = deployments; - const {deployer} = await getNamedAccounts(); + const [deployer] = await ethers.getSigners(); await deploy('MultisigSetup', { - from: deployer, + from: deployer.address, args: [], log: true, }); diff --git a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/40_placeholder_setup.ts b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/40_placeholder_setup.ts index fe6dc26a0..9e1a2d255 100644 --- a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/40_placeholder_setup.ts +++ b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/40_placeholder_setup.ts @@ -5,12 +5,12 @@ import {uploadToIPFS} from '../../../helpers'; import placeholderBuildMetadata from '../../../../src/plugins/placeholder-version/build-metadata.json'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {deployments, getNamedAccounts} = hre; + const {deployments, ethers} = hre; const {deploy} = deployments; - const {deployer} = await getNamedAccounts(); + const [deployer] = await ethers.getSigners(); await deploy('PlaceholderSetup', { - from: deployer, + from: deployer.address, args: [], log: true, }); diff --git a/packages/contracts/deploy/new/40_finalize-managing-dao/00_grant-permissions.ts b/packages/contracts/deploy/new/40_finalize-managing-dao/00_grant-permissions.ts index bd9adf68e..26a16dc51 100644 --- a/packages/contracts/deploy/new/40_finalize-managing-dao/00_grant-permissions.ts +++ b/packages/contracts/deploy/new/40_finalize-managing-dao/00_grant-permissions.ts @@ -4,6 +4,7 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {Operation} from '../../../utils/types'; import {getContractAddress, managePermissions, Permission} from '../../helpers'; import {PluginRepo__factory} from '../../../typechain'; +import {DAO__factory} from '../../../typechain/osx-versions/v1_2_0/contracts/core/dao/DAO.sol'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log(`\nFinalizing ManagingDao.`); @@ -21,9 +22,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const managingDAOAddress = await getContractAddress('DAO', hre); // Get `DAO` contract. - const managingDaoContract = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress + const managingDaoContract = DAO__factory.connect( + managingDAOAddress, + deployer ); // Grant `REGISTER_DAO_PERMISSION` to `Deployer`. diff --git a/packages/contracts/deploy/new/40_finalize-managing-dao/20_register-managing-dao-on-dao-registry.ts b/packages/contracts/deploy/new/40_finalize-managing-dao/20_register-managing-dao-on-dao-registry.ts index ddabe1614..7d5809397 100644 --- a/packages/contracts/deploy/new/40_finalize-managing-dao/20_register-managing-dao-on-dao-registry.ts +++ b/packages/contracts/deploy/new/40_finalize-managing-dao/20_register-managing-dao-on-dao-registry.ts @@ -8,10 +8,11 @@ import { MANAGING_DAO_METADATA, uploadToIPFS, } from '../../helpers'; +import {DAO__factory, DAORegistry__factory} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const {getNamedAccounts, ethers, network} = hre; - const {deployer} = await getNamedAccounts(); + const {ethers, network} = hre; + const [deployer] = await ethers.getSigners(); // Get info from .env const daoSubdomain = process.env.MANAGINGDAO_SUBDOMAIN || ''; @@ -28,15 +29,16 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const daoRegistryAddress = await getContractAddress('DAORegistry', hre); // Get `DAORegistry` contract. - const daoRegistryContract = await ethers.getContractAt( - 'DAORegistry', - daoRegistryAddress + const daoRegistryContract = DAORegistry__factory.connect( + daoRegistryAddress, + deployer ); if ( await isENSDomainRegistered( `${daoSubdomain}.${daoDomain}`, - await getENSAddress(hre) + await getENSAddress(hre), + deployer ) ) { // not beeing able to register the managing DAO means that something is not right with the framework deployment used. @@ -48,7 +50,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Register `managingDAO` on `DAORegistry`. const registerTx = await daoRegistryContract.register( managingDAOAddress, - deployer, + deployer.address, daoSubdomain ); await registerTx.wait(); @@ -57,11 +59,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { ); // Set Metadata for the Managing DAO - const managingDaoContract = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress + const managingDaoContract = DAO__factory.connect( + managingDAOAddress, + deployer ); - const metadataCIDPath = await uploadToIPFS( JSON.stringify(MANAGING_DAO_METADATA), network.name diff --git a/packages/contracts/deploy/new/40_finalize-managing-dao/30_install-multisig-on-managing-dao.ts b/packages/contracts/deploy/new/40_finalize-managing-dao/30_install-multisig-on-managing-dao.ts index 70566cd96..3114a8093 100644 --- a/packages/contracts/deploy/new/40_finalize-managing-dao/30_install-multisig-on-managing-dao.ts +++ b/packages/contracts/deploy/new/40_finalize-managing-dao/30_install-multisig-on-managing-dao.ts @@ -6,9 +6,14 @@ import {findEvent} from '../../../utils/event'; import {checkPermission, getContractAddress} from '../../helpers'; import {Operation} from '../../../utils/types'; import {hashHelpers} from '../../../utils/psp'; -import {MultisigSetup__factory, Multisig__factory} from '../../../typechain'; +import { + MultisigSetup__factory, + Multisig__factory, + PluginSetupProcessor__factory, +} from '../../../typechain'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; import {InstallationPreparedEvent} from '../../../typechain/PluginSetupProcessor'; +import {DAO__factory} from '../../../typechain/osx-versions/v1_2_0/contracts/core/dao/DAO.sol'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const {ethers, network} = hre; @@ -41,18 +46,18 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const managingDAOAddress = await getContractAddress('DAO', hre); // Get `DAO` contract. - const managingDaoContract = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress + const managingDaoContract = DAO__factory.connect( + managingDAOAddress, + deployer ); // Get `PluginSetupProcessor` address. const pspAddress = await getContractAddress('PluginSetupProcessor', hre); // Get `PluginSetupProcessor` contract. - const pspContract = await ethers.getContractAt( - 'PluginSetupProcessor', - pspAddress + const pspContract = PluginSetupProcessor__factory.connect( + pspAddress, + deployer ); // Install multisig build 2 diff --git a/packages/contracts/deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts b/packages/contracts/deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts index 388812479..620ff92fd 100644 --- a/packages/contracts/deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts +++ b/packages/contracts/deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts @@ -4,6 +4,7 @@ import {getContractAddress, managePermissions, Permission} from '../../helpers'; import {Operation} from '../../../utils/types'; import {PluginRepo__factory} from '../../../typechain'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DAO__factory} from '../../../typechain/osx-versions/v1_2_0/contracts/core/dao/DAO.sol'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const {ethers} = hre; @@ -25,9 +26,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const managingDAOAddress = await getContractAddress('DAO', hre); // Get `DAO` contract. - const managingDaoContract = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress + const managingDaoContract = DAO__factory.connect( + managingDAOAddress, + deployer ); // Revoke `REGISTER_DAO_PERMISSION` from `Deployer`. diff --git a/packages/contracts/deploy/new/40_finalize-managing-dao/99_verify_step.ts b/packages/contracts/deploy/new/40_finalize-managing-dao/99_verify_step.ts index 8d960e321..d3e950450 100644 --- a/packages/contracts/deploy/new/40_finalize-managing-dao/99_verify_step.ts +++ b/packages/contracts/deploy/new/40_finalize-managing-dao/99_verify_step.ts @@ -3,19 +3,21 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; import {Operation} from '../../../utils/types'; import {checkPermission, getContractAddress} from '../../helpers'; +import {DAO__factory} from '../../../typechain'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log('\nVerifying managing DAO deployment.'); - const {getNamedAccounts, ethers} = hre; - const {deployer} = await getNamedAccounts(); + const {ethers} = hre; + const [deployer] = await ethers.getSigners(); // Get `managingDAO` address. const managingDAOAddress = await getContractAddress('DAO', hre); // Get `DAO` contract. - const managingDaoContract = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDAOAddress + + const managingDaoContract = DAO__factory.connect( + managingDAOAddress, + (await ethers.getSigners())[0] ); // Get `DAORegistry` address. const daoRegistryAddress = await getContractAddress('DAORegistry', hre); @@ -26,14 +28,14 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { await checkPermission(managingDaoContract, { operation: Operation.Revoke, where: {name: 'DAORegistry', address: daoRegistryAddress}, - who: {name: 'Deployer', address: deployer}, + who: {name: 'Deployer', address: deployer.address}, permission: 'REGISTER_DAO_PERMISSION', }); await checkPermission(managingDaoContract, { operation: Operation.Revoke, where: {name: 'PluginSetupProcessor', address: pspAddress}, - who: {name: 'Deployer', address: deployer}, + who: {name: 'Deployer', address: deployer.address}, permission: 'APPLY_INSTALLATION_PERMISSION', }); @@ -47,14 +49,14 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { await checkPermission(managingDaoContract, { operation: Operation.Revoke, where: {name: 'ManagingDAO', address: managingDAOAddress}, - who: {name: 'Deployer', address: deployer}, + who: {name: 'Deployer', address: deployer.address}, permission: 'ROOT_PERMISSION', }); await checkPermission(managingDaoContract, { operation: Operation.Revoke, where: {name: 'ManagingDAO', address: managingDAOAddress}, - who: {name: 'Deployer', address: deployer}, + who: {name: 'Deployer', address: deployer.address}, permission: 'EXECUTE_PERMISSION', }); diff --git a/packages/contracts/test/core/dao/callback-handler.ts b/packages/contracts/test/core/dao/callback-handler.ts index f5959810d..1b78126f4 100644 --- a/packages/contracts/test/core/dao/callback-handler.ts +++ b/packages/contracts/test/core/dao/callback-handler.ts @@ -3,7 +3,10 @@ import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {defaultAbiCoder, hexDataSlice, id} from 'ethers/lib/utils'; -import {CallbackHandlerMockHelper} from '../../../typechain'; +import { + CallbackHandlerMockHelper, + CallbackHandlerMockHelper__factory, +} from '../../../typechain'; const EVENTS = { STANDARD_CALLBACK_REGISTERED: 'StandardCallbackRegistered', @@ -22,8 +25,8 @@ describe('CallbackHandler', function () { beforeEach(async () => { signers = await ethers.getSigners(); owner = await signers[0].getAddress(); - const CallbackHandlerHelper = await ethers.getContractFactory( - 'CallbackHandlerMockHelper' + const CallbackHandlerHelper = new CallbackHandlerMockHelper__factory( + signers[0] ); callbackHandlerMockHelper = await CallbackHandlerHelper.deploy(); diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 651bd7aef..f11ab5ae5 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -10,6 +10,15 @@ import { IERC1271__factory, GasConsumer__factory, DAO__factory, + ERC1271Mock__factory, + TestERC20__factory, + TestERC1155__factory, + TestERC721__factory, + IERC1155, + IERC1155Receiver, + IERC1155Receiver__factory, + IERC721Receiver, + IERC721Receiver__factory, } from '../../../typechain'; import {findEvent, DAO_EVENTS} from '../../../utils/event'; import {flipBit} from '../../test-utils/bitmap'; @@ -82,7 +91,7 @@ describe('DAO', function () { ownerAddress = await signers[0].getAddress(); const DAO = new DAO__factory(signers[0]); - dao = await deployWithProxy(DAO); + dao = await deployWithProxy(DAO); await dao.initialize( dummyMetadata1, ownerAddress, @@ -448,7 +457,7 @@ describe('DAO', function () { let erc20Token: TestERC20; beforeEach(async () => { - const TestERC20 = await ethers.getContractFactory('TestERC20'); + const TestERC20 = new TestERC20__factory(signers[0]); erc20Token = await TestERC20.deploy('name', 'symbol', 0); }); @@ -488,7 +497,7 @@ describe('DAO', function () { let erc721Token: TestERC721; beforeEach(async () => { - const TestERC721 = await ethers.getContractFactory('TestERC721'); + const TestERC721 = new TestERC721__factory(signers[0]); erc721Token = await TestERC721.deploy('name', 'symbol'); }); @@ -531,7 +540,7 @@ describe('DAO', function () { let erc1155Token: TestERC1155; beforeEach(async () => { - const TestERC1155 = await ethers.getContractFactory('TestERC1155'); + const TestERC1155 = new TestERC1155__factory(signers[0]); erc1155Token = await TestERC1155.deploy('URI'); }); @@ -592,14 +601,14 @@ describe('DAO', function () { let erc1155Token: TestERC1155; beforeEach(async () => { - const TestERC1155 = await ethers.getContractFactory('TestERC1155'); + const TestERC1155 = new TestERC1155__factory(signers[0]); erc1155Token = await TestERC1155.deploy('URI'); - const TestERC721 = await ethers.getContractFactory('TestERC721'); + const TestERC721 = new TestERC721__factory(signers[0]); erc721Token = await TestERC721.deploy('name', 'symbol'); - erc721Token.mint(ownerAddress, 1); - erc1155Token.mint(ownerAddress, 1, 2); + await erc721Token.mint(ownerAddress, 1); + await erc1155Token.mint(ownerAddress, 1, 2); }); it('reverts if erc721 callback is not registered', async () => { @@ -619,9 +628,9 @@ describe('DAO', function () { }); it('successfully transfers erc721 into the dao and emits the correct callback received event', async () => { - const ABI = ['function onERC721Received(address,address,uint256,bytes)']; - const iface = new ethers.utils.Interface(ABI); - const encoded = iface.encodeFunctionData('onERC721Received', [ + const IERC721 = IERC721Receiver__factory.createInterface(); + + const encoded = IERC721.encodeFunctionData('onERC721Received', [ ownerAddress, ownerAddress, 1, @@ -671,27 +680,19 @@ describe('DAO', function () { }); it('successfully transfers erc1155 into the dao', async () => { + const IERC1155 = IERC1155Receiver__factory.createInterface(); + // encode onERC1155Received call - const erc1155ReceivedEncoded = new ethers.utils.Interface([ - 'function onERC1155Received(address,address,uint256,uint256,bytes)', - ]).encodeFunctionData('onERC1155Received', [ - ownerAddress, - ownerAddress, - 1, - 1, - '0x', - ]); + const erc1155ReceivedEncoded = IERC1155.encodeFunctionData( + 'onERC1155Received', + [ownerAddress, ownerAddress, 1, 1, '0x'] + ); // encode onERC1155BatchReceived call - const erc1155BatchReceivedEncoded = new ethers.utils.Interface([ - 'function onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)', - ]).encodeFunctionData('onERC1155BatchReceived', [ - ownerAddress, - ownerAddress, - [1], - [1], - '0x', - ]); + const erc1155BatchReceivedEncoded = IERC1155.encodeFunctionData( + 'onERC1155BatchReceived', + [ownerAddress, ownerAddress, [1], [1], '0x'] + ); await expect( erc1155Token.safeTransferFrom(ownerAddress, dao.address, 1, 1, '0x') @@ -725,7 +726,7 @@ describe('DAO', function () { let token: TestERC20; beforeEach(async () => { - const TestERC20 = await ethers.getContractFactory('TestERC20'); + const TestERC20 = new TestERC20__factory(signers[0]); token = await TestERC20.deploy('name', 'symbol', 0); }); @@ -939,7 +940,7 @@ describe('DAO', function () { }); it('should return the validators response', async () => { - const ERC1271MockFactory = await ethers.getContractFactory('ERC1271Mock'); + const ERC1271MockFactory = new ERC1271Mock__factory(signers[0]); const erc1271Mock = await ERC1271MockFactory.deploy(); await dao.setSignatureValidator(erc1271Mock.address); diff --git a/packages/contracts/test/core/permission/permission-manager.ts b/packages/contracts/test/core/permission/permission-manager.ts index 17b4e03be..ba50c4c2e 100644 --- a/packages/contracts/test/core/permission/permission-manager.ts +++ b/packages/contracts/test/core/permission/permission-manager.ts @@ -5,6 +5,7 @@ import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import { PermissionManagerTest, PermissionConditionMock, + PermissionManagerTest__factory, } from '../../../typechain'; import {DeployTestPermissionCondition} from '../../test-utils/conditions'; import {OZ_ERRORS} from '../../test-utils/error'; @@ -44,17 +45,18 @@ interface MultiTargetPermission { describe('Core: PermissionManager', function () { let pm: PermissionManagerTest; + let signers: SignerWithAddress[]; let ownerSigner: SignerWithAddress; let otherSigner: SignerWithAddress; before(async () => { - const signers = await ethers.getSigners(); + signers = await ethers.getSigners(); ownerSigner = signers[0]; otherSigner = signers[1]; }); beforeEach(async () => { - const PM = await ethers.getContractFactory('PermissionManagerTest'); + const PM = new PermissionManagerTest__factory(signers[0]); pm = await PM.deploy(); await pm.init(ownerSigner.address); }); @@ -67,7 +69,7 @@ describe('Core: PermissionManager', function () { }); it('should emit Granted', async () => { - const PM = await ethers.getContractFactory('PermissionManagerTest'); + const PM = new PermissionManagerTest__factory(ownerSigner); pm = await PM.deploy(); await expect(pm.init(ownerSigner.address)).to.emit(pm, 'Granted'); }); diff --git a/packages/contracts/test/core/plugin/parameter-scoping-condition.ts b/packages/contracts/test/core/plugin/parameter-scoping-condition.ts index deb167bb9..4716560d1 100644 --- a/packages/contracts/test/core/plugin/parameter-scoping-condition.ts +++ b/packages/contracts/test/core/plugin/parameter-scoping-condition.ts @@ -6,6 +6,8 @@ import { TestParameterScopingPermissionCondition, TestPlugin, DAO, + TestPlugin__factory, + TestParameterScopingPermissionCondition__factory, } from '../../../typechain'; import {deployNewDAO} from '../../test-utils/dao'; import {deployWithProxy} from '../../test-utils/proxy'; @@ -28,15 +30,15 @@ describe('TestParameterScopingCondition', function () { managingDao = await deployNewDAO(signers[0]); // Deploy the component - const TestPlugin = await ethers.getContractFactory('TestPlugin'); + const TestPlugin = new TestPlugin__factory(signers[0]); testPlugin = await deployWithProxy(TestPlugin); await testPlugin.initialize(managingDao.address); // Deploy the condition - const ParameterCondition = await ethers.getContractFactory( - 'TestParameterScopingPermissionCondition' - ); + const ParameterCondition = + new TestParameterScopingPermissionCondition__factory(signers[0]); + parameterCondition = await ParameterCondition.deploy(); // Give signers[0] the `DO_SOMETHING_PERMISSION_ID` on the TestPlugin diff --git a/packages/contracts/test/core/plugin/shared-plugin.ts b/packages/contracts/test/core/plugin/shared-plugin.ts index ee2d8374e..03f6ac2f9 100644 --- a/packages/contracts/test/core/plugin/shared-plugin.ts +++ b/packages/contracts/test/core/plugin/shared-plugin.ts @@ -2,7 +2,13 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; -import {TestSharedPlugin, TestIdGatingCondition, DAO} from '../../../typechain'; +import { + TestSharedPlugin, + TestIdGatingCondition, + DAO, + TestIdGatingCondition__factory, + TestSharedPlugin__factory, +} from '../../../typechain'; import {deployNewDAO} from '../../test-utils/dao'; import {deployWithProxy} from '../../test-utils/proxy'; @@ -29,9 +35,7 @@ describe('SharedPlugin', function () { dao2 = await deployNewDAO(signers[0]); // Deploy the `TestSharedPlugin` - const TestSharedPlugin = await ethers.getContractFactory( - 'TestSharedPlugin' - ); + const TestSharedPlugin = new TestSharedPlugin__factory(signers[0]); testPlugin = await deployWithProxy(TestSharedPlugin); await testPlugin.initialize(managingDao.address); @@ -65,9 +69,7 @@ describe('SharedPlugin', function () { const allowedId = 0; // Deploy `TestIdGatingCondition` and set the allowed ID in the constructor - const Condition = await ethers.getContractFactory( - 'TestIdGatingCondition' - ); + const Condition = new TestIdGatingCondition__factory(signers[0]); condition = await Condition.deploy(allowedId); // Grants signers[0] the permission to do ID gated actions with the deployed `TestIdGatingCondition` condition @@ -93,9 +95,7 @@ describe('SharedPlugin', function () { const nonExistingId = 1; // Deploy the condition and set the allowed ID - const Condition = await ethers.getContractFactory( - 'TestIdGatingCondition' - ); + const Condition = new TestIdGatingCondition__factory(signers[0]); condition = await Condition.deploy(allowedId); // Grants signers[0] the permission to do ID gated actions with the deployed `TestIdGatingCondition` condition @@ -131,9 +131,7 @@ describe('SharedPlugin', function () { const allowedId = 1; const existingButNotAllowedId = 0; - const Condition = await ethers.getContractFactory( - 'TestIdGatingCondition' - ); + const Condition = new TestIdGatingCondition__factory(signers[0]); condition = await Condition.deploy(allowedId); // Grants signers[0] the permission to do ID gated actions on `testPlugin` via `condition` @@ -172,9 +170,7 @@ describe('SharedPlugin', function () { // Deploy condition and set allowed ID const allowedId = 0; - const Condition = await ethers.getContractFactory( - 'TestIdGatingCondition' - ); + const Condition = new TestIdGatingCondition__factory(signers[0]); condition = await Condition.deploy(allowedId); // Create ID-gated object associated with `dao1` @@ -191,9 +187,7 @@ describe('SharedPlugin', function () { // Deploy condition and set allowed ID const allowedId = 0; - const Condition = await ethers.getContractFactory( - 'TestIdGatingCondition' - ); + const Condition = new TestIdGatingCondition__factory(signers[0]); condition = await Condition.deploy(allowedId); // Grants signers[0] the permission to do ID gated actions with the deployed `TestIdGatingCondition` condition @@ -218,9 +212,7 @@ describe('SharedPlugin', function () { // Deploy condition and set allowed ID const allowedId = 0; - const Condition = await ethers.getContractFactory( - 'TestIdGatingCondition' - ); + const Condition = new TestIdGatingCondition__factory(signers[0]); condition = await Condition.deploy(allowedId); // Grants signers[0] the permission to do ID gated actions with the deployed `TestIdGatingCondition` condition diff --git a/packages/contracts/test/deploy/managing-dao.ts b/packages/contracts/test/deploy/managing-dao.ts index e6ef08a3e..a684d0fd5 100644 --- a/packages/contracts/test/deploy/managing-dao.ts +++ b/packages/contracts/test/deploy/managing-dao.ts @@ -6,13 +6,18 @@ import {Deployment} from 'hardhat-deploy/dist/types'; import { DAO, DAORegistry, + DAORegistry__factory, DAO__factory, ENSSubdomainRegistrar, + ENSSubdomainRegistrar__factory, Multisig, + Multisig__factory, PluginRepoRegistry, + PluginRepoRegistry__factory, } from '../../typechain'; import daoArtifactData from '../../artifacts/src/core/dao/DAO.sol/DAO.json'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; async function deployAll() { await deployments.fixture(); @@ -22,6 +27,7 @@ const IMPLEMENTATION_SLOT = '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc'; describe('Managing DAO', function () { + let signers: SignerWithAddress[]; let ownerAddress: string; let managingDaoDeployment: Deployment; let managingDao: DAO; @@ -73,6 +79,8 @@ describe('Managing DAO', function () { } before(async () => { + signers = await ethers.getSigners(); + // deployment should be empty expect(await deployments.all()).to.be.empty; @@ -81,23 +89,23 @@ describe('Managing DAO', function () { // ManagingDAO managingDaoDeployment = await deployments.get('DAO'); - managingDao = await ethers.getContractAt( - 'src/core/dao/DAO.sol:DAO', - managingDaoDeployment.address + managingDao = DAO__factory.connect( + managingDaoDeployment.address, + signers[0] ); // DAORegistry daoRegistryDeployment = await deployments.get('DAORegistry'); - daoRegistry = await ethers.getContractAt( - 'DAORegistry', - daoRegistryDeployment.address + daoRegistry = DAORegistry__factory.connect( + daoRegistryDeployment.address, + signers[0] ); // PluginRepoRegistry pluginRepoRegistryDeployment = await deployments.get('PluginRepoRegistry'); - pluginRepoRegistry = await ethers.getContractAt( - 'PluginRepoRegistry', - pluginRepoRegistryDeployment.address + pluginRepoRegistry = PluginRepoRegistry__factory.connect( + pluginRepoRegistryDeployment.address, + signers[0] ); // ENSSubdomainRegistrar @@ -106,22 +114,22 @@ describe('Managing DAO', function () { await deployments.get('Plugin_ENSSubdomainRegistrar'), ]; ensSubdomainRegistrars = [ - await ethers.getContractAt( - 'ENSSubdomainRegistrar', - ensSubdomainRegistrarDeployments[0].address + ENSSubdomainRegistrar__factory.connect( + ensSubdomainRegistrarDeployments[0].address, + signers[0] ), - await ethers.getContractAt( - 'ENSSubdomainRegistrar', - ensSubdomainRegistrarDeployments[1].address + ENSSubdomainRegistrar__factory.connect( + ensSubdomainRegistrarDeployments[1].address, + signers[0] ), ]; const {deployer} = await getNamedAccounts(); ownerAddress = deployer; - multisig = await ethers.getContractAt( - 'Multisig', - hre.managingDAOMultisigPluginAddress + multisig = Multisig__factory.connect( + hre.managingDAOMultisigPluginAddress, + signers[0] ); }); diff --git a/packages/contracts/test/framework/dao/dao-factory.ts b/packages/contracts/test/framework/dao/dao-factory.ts index 570ce72cb..1ee24032d 100644 --- a/packages/contracts/test/framework/dao/dao-factory.ts +++ b/packages/contracts/test/framework/dao/dao-factory.ts @@ -18,6 +18,12 @@ import { PluginRepo, Admin, DAO, + Admin__factory, + AdminSetup__factory, + PluginUUPSUpgradeableSetupV2Mock__factory, + PluginUUPSUpgradeableSetupV1Mock__factory, + DAORegistry__factory, + PluginRepo__factory, } from '../../../typechain'; import {deployENSSubdomainRegistrar} from '../../test-utils/ens'; @@ -183,7 +189,7 @@ describe('DAOFactory: ', function () { ); // DAO Registry - const DAORegistry = await ethers.getContractFactory('DAORegistry'); + const DAORegistry = new DAORegistry__factory(signers[0]); daoRegistry = await deployWithProxy(DAORegistry); await daoRegistry.initialize( managingDao.address, @@ -193,7 +199,8 @@ describe('DAOFactory: ', function () { // Plugin Repo Registry pluginRepoRegistry = await deployPluginRepoRegistry( managingDao, - ensSubdomainRegistrar + ensSubdomainRegistrar, + signers[0] ); // Plugin Setup Processor @@ -243,9 +250,8 @@ describe('DAOFactory: ', function () { // Create and register a plugin on the `PluginRepoRegistry`. // PluginSetupV1 - const PluginUUPSUpgradeableSetupV1Mock = await ethers.getContractFactory( - 'PluginUUPSUpgradeableSetupV1Mock' - ); + const PluginUUPSUpgradeableSetupV1Mock = + new PluginUUPSUpgradeableSetupV1Mock__factory(signers[0]); pluginSetupV1Mock = await PluginUUPSUpgradeableSetupV1Mock.deploy(); const tx = await pluginRepoFactory.createPluginRepoWithFirstVersion( @@ -261,8 +267,10 @@ describe('DAOFactory: ', function () { ); pluginSetupMockRepoAddress = event.args.pluginRepo; - const factory = await ethers.getContractFactory('PluginRepo'); - pluginRepoMock = factory.attach(pluginSetupMockRepoAddress); + pluginRepoMock = PluginRepo__factory.connect( + pluginSetupMockRepoAddress, + signers[0] + ); // default params daoSettings = { @@ -534,9 +542,8 @@ describe('DAOFactory: ', function () { beforeEach(async () => { // create 2nd version of PluginUUPSUpgradeableSetupV1. - const PluginUUPSUpgradeableSetupV2Mock = await ethers.getContractFactory( - 'PluginUUPSUpgradeableSetupV2Mock' - ); + const PluginUUPSUpgradeableSetupV2Mock = + new PluginUUPSUpgradeableSetupV2Mock__factory(signers[0]); pluginSetupV2Mock = await PluginUUPSUpgradeableSetupV2Mock.deploy(); { await pluginRepoMock.createVersion( @@ -549,9 +556,7 @@ describe('DAOFactory: ', function () { // Create admin plugin repo so we can install it with dao // This will help us execute installation/update calldatas through dao's execute. - const AdminPluginSetupFactory = await ethers.getContractFactory( - 'AdminSetup' - ); + const AdminPluginSetupFactory = new AdminSetup__factory(signers[0]); adminPluginSetup = await AdminPluginSetupFactory.deploy(); let tx = await pluginRepoFactory.createPluginRepoWithFirstVersion( @@ -589,7 +594,7 @@ describe('DAOFactory: ', function () { tx, EVENTS.InstallationPrepared ); - const adminFactory = await ethers.getContractFactory('Admin'); + const adminFactory = new Admin__factory(signers[0]); adminPlugin = adminFactory.attach(event.args.plugin); const daoFactory = new DAO__factory(signers[0]); diff --git a/packages/contracts/test/framework/dao/dao-registry.ts b/packages/contracts/test/framework/dao/dao-registry.ts index 48475a744..a9f7167d5 100644 --- a/packages/contracts/test/framework/dao/dao-registry.ts +++ b/packages/contracts/test/framework/dao/dao-registry.ts @@ -2,7 +2,12 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {ensDomainHash, ensLabelHash} from '../../../utils/ens'; -import {DAO, DAORegistry, ENSSubdomainRegistrar} from '../../../typechain'; +import { + DAO, + DAORegistry, + DAORegistry__factory, + ENSSubdomainRegistrar, +} from '../../../typechain'; import {deployNewDAO} from '../../test-utils/dao'; import {deployENSSubdomainRegistrar} from '../../test-utils/ens'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; @@ -52,7 +57,7 @@ describe('DAORegistry', function () { targetDao = await deployNewDAO(signers[0]); // DAO Registry - const Registry = await ethers.getContractFactory('DAORegistry'); + const Registry = new DAORegistry__factory(signers[0]); daoRegistry = await deployWithProxy(Registry); diff --git a/packages/contracts/test/framework/plugin/plugin-repo-factory.ts b/packages/contracts/test/framework/plugin/plugin-repo-factory.ts index 66e584935..6f91bd30c 100644 --- a/packages/contracts/test/framework/plugin/plugin-repo-factory.ts +++ b/packages/contracts/test/framework/plugin/plugin-repo-factory.ts @@ -14,6 +14,7 @@ import { DAO, PluginRepoFactory, PluginRepoFactory__factory, + PluginRepo__factory, } from '../../../typechain'; import {getMergedABI} from '../../../utils/abi'; @@ -80,7 +81,8 @@ describe('PluginRepoFactory: ', function () { // deploy and initialize PluginRepoRegistry pluginRepoRegistry = await deployPluginRepoRegistry( managingDao, - ensSubdomainRegistrar + ensSubdomainRegistrar, + signers[0] ); // deploy PluginRepoFactory @@ -145,7 +147,7 @@ describe('PluginRepoFactory: ', function () { const expectedRepoAddress = await getExpectedRepoAddress( pluginRepoFactory.address ); - const PluginRepo = await ethers.getContractFactory('PluginRepo'); + const PluginRepo = new PluginRepo__factory(signers[0]); const pluginRepo = PluginRepo.attach(expectedRepoAddress); let tx = await pluginRepoFactory.createPluginRepo( @@ -236,7 +238,7 @@ describe('PluginRepoFactory: ', function () { const expectedRepoAddress = await getExpectedRepoAddress( pluginRepoFactory.address ); - const PluginRepo = await ethers.getContractFactory('PluginRepo'); + const PluginRepo = new PluginRepo__factory(signers[0]); const pluginRepo = PluginRepo.attach(expectedRepoAddress); let tx = await pluginRepoFactory.createPluginRepoWithFirstVersion( diff --git a/packages/contracts/test/framework/plugin/plugin-repo.ts b/packages/contracts/test/framework/plugin/plugin-repo.ts index b16e96810..f12c06951 100644 --- a/packages/contracts/test/framework/plugin/plugin-repo.ts +++ b/packages/contracts/test/framework/plugin/plugin-repo.ts @@ -10,6 +10,7 @@ import { PluginRepo, PluginUUPSUpgradeableSetupV1Mock, PlaceholderSetup__factory, + TestPlugin__factory, } from '../../../typechain'; import { deployMockPluginSetup, @@ -106,9 +107,7 @@ describe('PluginRepo', function () { ); // If a contract is passed, but doesn't have `supportsInterface` signature described in the contract. - const randomContract = await ( - await ethers.getContractFactory('TestPlugin') - ).deploy(); + const randomContract = await new TestPlugin__factory(signers[0]).deploy(); await expect( pluginRepo.createVersion( 1, diff --git a/packages/contracts/test/framework/plugin/plugin-setup-processor.ts b/packages/contracts/test/framework/plugin/plugin-setup-processor.ts index 05d253390..f37e36c2e 100644 --- a/packages/contracts/test/framework/plugin/plugin-setup-processor.ts +++ b/packages/contracts/test/framework/plugin/plugin-setup-processor.ts @@ -27,6 +27,8 @@ import { PluginCloneableSetupV1MockBad__factory, PluginUUPSUpgradeableSetupV1Mock__factory, PluginCloneableSetupV1Mock__factory, + PluginRepo__factory, + PluginUUPSUpgradeable__factory, } from '../../../typechain'; import {deployENSSubdomainRegistrar} from '../../test-utils/ens'; @@ -143,9 +145,9 @@ describe('Plugin Setup Processor', function () { signers = await ethers.getSigners(); ownerAddress = await signers[0].getAddress(); - PluginUV1 = await ethers.getContractFactory('PluginUUPSUpgradeableV1Mock'); - PluginUV2 = await ethers.getContractFactory('PluginUUPSUpgradeableV2Mock'); - PluginUV3 = await ethers.getContractFactory('PluginUUPSUpgradeableV3Mock'); + PluginUV1 = new PluginUUPSUpgradeableV1Mock__factory(signers[0]); + PluginUV2 = new PluginUUPSUpgradeableV2Mock__factory(signers[0]); + PluginUV3 = new PluginUUPSUpgradeableV3Mock__factory(signers[0]); // Deploy PluginUUPSUpgradeableSetupMock @@ -204,7 +206,8 @@ describe('Plugin Setup Processor', function () { // Deploy Plugin Repo Registry pluginRepoRegistry = await deployPluginRepoRegistry( managingDao, - ensSubdomainRegistrar + ensSubdomainRegistrar, + signers[0] ); // Deploy Plugin Repo Factory @@ -246,7 +249,7 @@ describe('Plugin Setup Processor', function () { tx, EVENTS.PluginRepoRegistered ); - const PluginRepo = await ethers.getContractFactory('PluginRepo'); + const PluginRepo = new PluginRepo__factory(signers[0]); repoU = PluginRepo.attach(event.args.pluginRepo); // Add setups @@ -2535,7 +2538,9 @@ async function updateAndValidatePluginUpdate( data ); - const PluginRepoFactory = await ethers.getContractFactory('PluginRepo'); + const signers = await ethers.getSigners(); + + const PluginRepoFactory = new PluginRepo__factory(signers[0]); const repo = PluginRepoFactory.attach(pluginRepo); const currentVersion = await repo['getVersion((uint8,uint16))']({ @@ -2547,8 +2552,8 @@ async function updateAndValidatePluginUpdate( build: newVersionTag[1], }); - const PluginSetupFactory = await ethers.getContractFactory( - 'PluginUUPSUpgradeableSetupV1Mock' + const PluginSetupFactory = new PluginUUPSUpgradeableSetupV1Mock__factory( + signers[0] ); const currentPluginSetup = PluginSetupFactory.attach( @@ -2565,10 +2570,11 @@ async function updateAndValidatePluginUpdate( const newImpl = await newPluginSetup.implementation(); if (currentImpl != newImpl) { - const proxyContract = await ethers.getContractAt( - 'PluginUUPSUpgradeable', - proxy + const proxyContract = PluginUUPSUpgradeable__factory.connect( + proxy, + signers[0] ); + expect(await proxyContract.implementation()).to.equal(newImpl); } } diff --git a/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts b/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts index 4217a6a6b..be90da591 100644 --- a/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts +++ b/packages/contracts/test/framework/utils/ens/ens-subdomain-registry.ts @@ -8,6 +8,9 @@ import { DAO, PublicResolver, ENSRegistry, + ENSRegistry__factory, + PublicResolver__factory, + ENSSubdomainRegistrar__factory, } from '../../../../typechain'; import {deployNewDAO} from '../../../test-utils/dao'; import {ensDomainHash, ensLabelHash} from '../../../../utils/ens'; @@ -24,18 +27,16 @@ const REGISTER_ENS_SUBDOMAIN_PERMISSION_ID = ethers.utils.id( async function setupENS( owner: SignerWithAddress ): Promise<[ENSRegistry, PublicResolver, DAO, ENSSubdomainRegistrar]> { - const ENSRegistry = await ethers.getContractFactory('ENSRegistry'); - const PublicResolver = await ethers.getContractFactory('PublicResolver'); - const ENSSubdomainRegistrar = await ethers.getContractFactory( - 'ENSSubdomainRegistrar' - ); + const ENSRegistry = new ENSRegistry__factory(owner); + const PublicResolver = new PublicResolver__factory(owner); + const ENSSubdomainRegistrar = new ENSSubdomainRegistrar__factory(owner); // Deploy the ENSRegistry - const ens = await ENSRegistry.connect(owner).deploy(); + const ens = await ENSRegistry.deploy(); await ens.deployed(); // Deploy the Resolver - const resolver = await PublicResolver.connect(owner).deploy( + const resolver = await PublicResolver.deploy( ens.address, ethers.constants.AddressZero ); @@ -95,9 +96,11 @@ describe('ENSSubdomainRegistrar', function () { ); } - beforeEach(async function () { + before(async function () { signers = await ethers.getSigners(); + }); + beforeEach(async function () { [ens, resolver, managingDao, registrar] = await setupENS(signers[0]); this.upgrade = { @@ -109,7 +112,7 @@ describe('ENSSubdomainRegistrar', function () { describe('Upgrade', () => { beforeEach(async function () { - registerSubdomainHelper('test', '', signers[0], registrar.address); + await registerSubdomainHelper('test', '', signers[0], registrar.address); this.upgrade = { contract: registrar, dao: managingDao, @@ -145,7 +148,7 @@ describe('ENSSubdomainRegistrar', function () { describe('Registrar is the domain owner but not approved', () => { beforeEach(async () => { // Register the parent domain 'test' through signers[0] who owns the ENS root node ('') and make the subdomain registrar the owner - registerSubdomainHelper('test', '', signers[0], registrar.address); + await registerSubdomainHelper('test', '', signers[0], registrar.address); }); it('initializes correctly', async () => { @@ -160,10 +163,15 @@ describe('ENSSubdomainRegistrar', function () { it('reverts if the registrar do not have the ownership of the domain node', async () => { // Register the parent domain 'test2' through signers[0] who owns the ENS root node ('') and make the subdomain registrar the owner - registerSubdomainHelper('test2', '', signers[0], signers[0].address); + await registerSubdomainHelper( + 'test2', + '', + signers[0], + signers[0].address + ); // Initialize the registrar with the 'test' domain - registrar.initialize( + await registrar.initialize( managingDao.address, ens.address, ensDomainHash('test2') @@ -186,7 +194,7 @@ describe('ENSSubdomainRegistrar', function () { it('reverts if the ownership of the domain node is removed from the registrar', async () => { // Initialize the registrar with the 'test' domain - registrar.initialize( + await registrar.initialize( managingDao.address, ens.address, ensDomainHash('test') @@ -227,7 +235,7 @@ describe('ENSSubdomainRegistrar', function () { describe('Registrar is not the domain owner but it is approved', () => { beforeEach(async () => { // Register the parent domain 'test' through signers[0] who owns the ENS root node ('') and make the signers[0] the owner - registerSubdomainHelper('test', '', signers[0], signers[0].address); + await registerSubdomainHelper('test', '', signers[0], signers[0].address); // Approve the subdomain registrar contract address to operate for signers[0] (who owns 'test') await ens.connect(signers[0]).setApprovalForAll(registrar.address, true); @@ -331,7 +339,7 @@ describe('ENSSubdomainRegistrar', function () { describe('After registrar initialization', () => { beforeEach(async () => { // Initialize the registrar with the 'test' domain - registrar.initialize( + await registrar.initialize( managingDao.address, ens.address, ensDomainHash('test') diff --git a/packages/contracts/test/framework/utils/interface-based-registry.ts b/packages/contracts/test/framework/utils/interface-based-registry.ts index 1cd518725..f8f6459b3 100644 --- a/packages/contracts/test/framework/utils/interface-based-registry.ts +++ b/packages/contracts/test/framework/utils/interface-based-registry.ts @@ -7,6 +7,8 @@ import { DAO, IDAO__factory, InterfaceBasedRegistryMock, + InterfaceBasedRegistryMock__factory, + PluginRepo__factory, } from '../../../typechain'; import {deployNewDAO} from '../../test-utils/dao'; import {getInterfaceID} from '../../test-utils/interfaces'; @@ -32,8 +34,8 @@ describe('InterfaceBasedRegistry', function () { }); beforeEach(async () => { - const InterfaceBasedRegistryMock = await ethers.getContractFactory( - 'InterfaceBasedRegistryMock' + const InterfaceBasedRegistryMock = new InterfaceBasedRegistryMock__factory( + signers[0] ); interfaceBasedRegistryMock = await deployWithProxy( @@ -68,7 +70,7 @@ describe('InterfaceBasedRegistry', function () { it('fail to register if the interface is not supported', async () => { // Use the `PluginRepo` contract for testing purposes here, because the interface differs from the `DAO` interface - const PluginRepo = await ethers.getContractFactory('PluginRepo'); + const PluginRepo = new PluginRepo__factory(signers[0]); let contractNotBeingADao = await PluginRepo.deploy(); await expect( diff --git a/packages/contracts/test/framework/utils/registry-utils.ts b/packages/contracts/test/framework/utils/registry-utils.ts index f25bcd2d9..56a907c4a 100644 --- a/packages/contracts/test/framework/utils/registry-utils.ts +++ b/packages/contracts/test/framework/utils/registry-utils.ts @@ -1,14 +1,18 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; -import {RegistryUtils} from '../../../typechain'; +import {RegistryUtils, RegistryUtils__factory} from '../../../typechain'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; describe('RegistryUtils', () => { let registryUtilsContract: RegistryUtils; + let signers: SignerWithAddress[]; + + before(async () => { + signers = await ethers.getSigners(); + }); beforeEach(async () => { - const RegistryUtilsFactory = await ethers.getContractFactory( - 'RegistryUtils' - ); + const RegistryUtilsFactory = new RegistryUtils__factory(signers[0]); registryUtilsContract = await RegistryUtilsFactory.deploy(); }); diff --git a/packages/contracts/test/framework/utils/token-factory.ts b/packages/contracts/test/framework/utils/token-factory.ts index 74979b0af..b0929bb21 100644 --- a/packages/contracts/test/framework/utils/token-factory.ts +++ b/packages/contracts/test/framework/utils/token-factory.ts @@ -3,7 +3,9 @@ import {ethers} from 'hardhat'; import {FakeContract, MockContract, smock} from '@defi-wonderland/smock'; import { + ActionExecute__factory, DAO, + ERC20Upgradeable__factory, GovernanceERC20, GovernanceERC20__factory, GovernanceWrappedERC20, @@ -18,6 +20,7 @@ import { TokenCreatedEvent, WrappedTokenEvent, } from '../../../typechain/TokenFactory'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; chai.use(smock.matchers); @@ -38,11 +41,16 @@ interface MintConfig { const zeroAddr = ethers.constants.AddressZero; describe('Core: TokenFactory', () => { + let signers: SignerWithAddress[]; let tokenFactory: MockContract; let governanceBase: MockContract; let governanceWrappedBase: MockContract; let merkleMinterBase: MockContract; + before(async () => { + signers = await ethers.getSigners(); + }); + beforeEach(async () => { const GovernanceBaseFactory = await smock.mock( 'GovernanceERC20' @@ -93,9 +101,8 @@ describe('Core: TokenFactory', () => { it('should fail if token addr is no ERC20 contract', async () => { // NOTE that any contract that don't contain `balanceOf` is enough to use. - const dummyContractFactory = await ethers.getContractFactory( - 'ActionExecute' - ); + const dummyContractFactory = new ActionExecute__factory(signers[0]); + const dummyContract = await dummyContractFactory.deploy(); const config: TokenConfig = { addr: dummyContract.address, @@ -161,7 +168,7 @@ describe('Core: TokenFactory', () => { ); const event = await findEvent(tx, 'WrappedToken'); - const factory = await ethers.getContractFactory('GovernanceWrappedERC20'); + const factory = new GovernanceWrappedERC20__factory(signers[0]); const wrappedToken = factory.attach(event.args.token); expect(await wrappedToken.underlying()).to.equal(erc20Contract.address); @@ -259,9 +266,10 @@ describe('Core: TokenFactory', () => { ); const event = await findEvent(tx, 'TokenCreated'); - const erc20Contract = await ethers.getContractAt( - 'ERC20Upgradeable', - event.args.token + + const erc20Contract = ERC20Upgradeable__factory.connect( + event.args.token, + signers[0] ); for (const i in mintConfig.receivers) { diff --git a/packages/contracts/test/plugins/counter-example/counter-plugin-setup.ts b/packages/contracts/test/plugins/counter-example/counter-plugin-setup.ts index 31a5ea712..0aaf2f90a 100644 --- a/packages/contracts/test/plugins/counter-example/counter-plugin-setup.ts +++ b/packages/contracts/test/plugins/counter-example/counter-plugin-setup.ts @@ -8,6 +8,11 @@ import { CounterV1PluginSetup, CounterV2PluginSetup, MultiplyHelper, + CounterV2PluginSetup__factory, + CounterV1__factory, + MultiplyHelper__factory, + CounterV1PluginSetup__factory, + DAOMock__factory, } from '../../../typechain'; import {Operation} from '../../../utils/types'; @@ -36,28 +41,24 @@ describe('CounterPluginSetup(Example)', function () { address1 = await signers[1].getAddress(); address2 = await signers[2].getAddress(); - const DAOMock = await ethers.getContractFactory('DAOMock'); + const DAOMock = new DAOMock__factory(signers[0]); daoMock = await DAOMock.deploy(ownerAddress); - const CounterV1Setup = await ethers.getContractFactory( - 'CounterV1PluginSetup' - ); + const CounterV1Setup = new CounterV1PluginSetup__factory(signers[0]); counterV1Setup = await CounterV1Setup.deploy(); - const COUNTER_V1 = await ethers.getContractFactory('CounterV1'); - const counterV1 = COUNTER_V1.attach( - await counterV1Setup.multiplyHelperBase() + const counterV1 = CounterV1__factory.connect( + await counterV1Setup.multiplyHelperBase(), + signers[0] ); multiplyPermissionId = await counterV1.MULTIPLY_PERMISSION_ID(); implementationAddress = await counterV1Setup.implementation(); - const MultiplyHelper = await ethers.getContractFactory('MultiplyHelper'); + const MultiplyHelper = new MultiplyHelper__factory(signers[0]); multiplyHelper = await MultiplyHelper.deploy(); - const CounterV2Setup = await ethers.getContractFactory( - 'CounterV2PluginSetup' - ); + const CounterV2Setup = new CounterV2PluginSetup__factory(signers[0]); counterV2Setup = await CounterV2Setup.deploy(multiplyHelper.address); }); diff --git a/packages/contracts/test/plugins/governance/admin/admin-setup.ts b/packages/contracts/test/plugins/governance/admin/admin-setup.ts index ddc179435..7f7517dbf 100644 --- a/packages/contracts/test/plugins/governance/admin/admin-setup.ts +++ b/packages/contracts/test/plugins/governance/admin/admin-setup.ts @@ -2,7 +2,11 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {Operation} from '../../../../utils/types'; -import {AdminSetup} from '../../../../typechain'; +import { + AdminSetup, + AdminSetup__factory, + Admin__factory, +} from '../../../../typechain'; import {deployNewDAO} from '../../../test-utils/dao'; import {getInterfaceID} from '../../../test-utils/interfaces'; import metadata from '../../../../src/plugins/governance/admin/build-metadata.json'; @@ -36,7 +40,7 @@ describe('AdminSetup', function () { [ownerAddress] ); - const AdminSetup = await ethers.getContractFactory('AdminSetup'); + const AdminSetup = new AdminSetup__factory(signers[0]); adminSetup = await AdminSetup.deploy(); implementationAddress = await adminSetup.implementation(); @@ -47,7 +51,7 @@ describe('AdminSetup', function () { }); it('creates admin address base with the correct interface', async () => { - const factory = await ethers.getContractFactory('Admin'); + const factory = new Admin__factory(signers[0]); const adminAddressContract = factory.attach(implementationAddress); expect( @@ -139,7 +143,7 @@ describe('AdminSetup', function () { await adminSetup.prepareInstallation(daoAddress, minimum_data); - const factory = await ethers.getContractFactory('Admin'); + const factory = new Admin__factory(signers[0]); const adminAddressContract = factory.attach(anticipatedPluginAddress); expect(await adminAddressContract.dao()).to.be.equal(daoAddress); diff --git a/packages/contracts/test/plugins/governance/admin/admin.ts b/packages/contracts/test/plugins/governance/admin/admin.ts index 0bb23d667..411b1d872 100644 --- a/packages/contracts/test/plugins/governance/admin/admin.ts +++ b/packages/contracts/test/plugins/governance/admin/admin.ts @@ -15,6 +15,7 @@ import {OZ_ERRORS} from '../../../test-utils/error'; import {toBytes32} from '../../../test-utils/voting'; import { AdminCloneFactory, + AdminCloneFactory__factory, IERC165Upgradeable__factory, IMembership__factory, IPlugin__factory, @@ -70,9 +71,7 @@ describe('Admin', function () { dao = await deployNewDAO(signers[0]); - const AdminCloneFactory = await ethers.getContractFactory( - 'AdminCloneFactory' - ); + const AdminCloneFactory = new AdminCloneFactory__factory(signers[0]); adminCloneFactory = await AdminCloneFactory.deploy(); }); diff --git a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting-setup.ts b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting-setup.ts index ff24ada6c..a1444cbc6 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting-setup.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting-setup.ts @@ -2,7 +2,11 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; -import {AddresslistVotingSetup} from '../../../../../typechain'; +import { + AddresslistVotingSetup, + AddresslistVotingSetup__factory, + AddresslistVoting__factory, +} from '../../../../../typechain'; import {deployNewDAO} from '../../../../test-utils/dao'; import {getInterfaceID} from '../../../../test-utils/interfaces'; import {Operation} from '../../../../../utils/types'; @@ -52,8 +56,8 @@ describe('AddresslistVotingSetup', function () { }; defaultMembers = [signers[0].address]; - const AddresslistVotingSetup = await ethers.getContractFactory( - 'AddresslistVotingSetup' + const AddresslistVotingSetup = new AddresslistVotingSetup__factory( + signers[0] ); addresslistVotingSetup = await AddresslistVotingSetup.deploy(); @@ -71,7 +75,7 @@ describe('AddresslistVotingSetup', function () { }); it('creates address list voting base with the correct interface', async () => { - const factory = await ethers.getContractFactory('AddresslistVoting'); + const factory = new AddresslistVoting__factory(signers[0]); const addresslistVotingContract = factory.attach(implementationAddress); expect( @@ -171,9 +175,9 @@ describe('AddresslistVotingSetup', function () { defaultData ); - const factory = await ethers.getContractFactory('AddresslistVoting'); - const addresslistVotingContract = factory.attach( - anticipatedPluginAddress + const addresslistVotingContract = AddresslistVoting__factory.connect( + anticipatedPluginAddress, + signers[0] ); const latestBlock = await ethers.provider.getBlock('latest'); diff --git a/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts index c6b424cf5..79086f6d0 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/majority-voting.ts @@ -10,6 +10,7 @@ import { IProposal__factory, IMajorityVoting__factory, DAO__factory, + MajorityVotingMock__factory, } from '../../../../typechain'; import {VOTING_EVENTS} from '../../../../utils/event'; import { @@ -64,9 +65,7 @@ describe('MajorityVotingMock', function () { minProposerVotingPower: 0, }; - const MajorityVotingBase = await ethers.getContractFactory( - 'MajorityVotingMock' - ); + const MajorityVotingBase = new MajorityVotingMock__factory(signers[0]); votingBase = await deployWithProxy(MajorityVotingBase); await dao.grant( diff --git a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting-setup.ts b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting-setup.ts index 378b64f5c..1d2149542 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting-setup.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting-setup.ts @@ -2,7 +2,15 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; -import {ERC20, TokenVotingSetup} from '../../../../../typechain'; +import { + ERC20, + ERC20__factory, + GovernanceERC20__factory, + GovernanceWrappedERC20__factory, + TokenVotingSetup, + TokenVotingSetup__factory, + TokenVoting__factory, +} from '../../../../../typechain'; import {deployNewDAO} from '../../../../test-utils/dao'; import {getInterfaceID} from '../../../../test-utils/interfaces'; import {Operation} from '../../../../../utils/types'; @@ -62,14 +70,12 @@ describe('TokenVotingSetup', function () { defaultTokenSettings = {addr: AddressZero, name: '', symbol: ''}; defaultMintSettings = {receivers: [], amounts: []}; - const TokenVotingSetup = await ethers.getContractFactory( - 'TokenVotingSetup' - ); + const TokenVotingSetup = new TokenVotingSetup__factory(signers[0]); tokenVotingSetup = await TokenVotingSetup.deploy(); implementationAddress = await tokenVotingSetup.implementation(); - const ERC20Token = await ethers.getContractFactory('ERC20'); + const ERC20Token = new ERC20__factory(signers[0]); erc20Token = await ERC20Token.deploy(tokenName, tokenSymbol); defaultData = abiCoder.encode(prepareInstallationDataTypes, [ @@ -84,7 +90,7 @@ describe('TokenVotingSetup', function () { }); it('creates token voting base with the correct interface', async () => { - const factory = await ethers.getContractFactory('TokenVoting'); + const factory = new TokenVoting__factory(signers[0]); const tokenVoting = factory.attach(implementationAddress); expect( @@ -127,9 +133,7 @@ describe('TokenVotingSetup', function () { nonce, }); - const GovernanceERC20 = await ethers.getContractFactory( - 'GovernanceERC20' - ); + const GovernanceERC20 = new GovernanceERC20__factory(signers[0]); const govToken = GovernanceERC20.attach(anticipatedPluginAddress); @@ -246,8 +250,8 @@ describe('TokenVotingSetup', function () { await tokenVotingSetup.prepareInstallation(targetDao.address, data); - const GovernanceWrappedERC20Factory = await ethers.getContractFactory( - 'GovernanceWrappedERC20' + const GovernanceWrappedERC20Factory = new GovernanceWrappedERC20__factory( + signers[0] ); const governanceWrappedERC20Contract = GovernanceWrappedERC20Factory.attach(anticipatedWrappedTokenAddress); @@ -265,9 +269,7 @@ describe('TokenVotingSetup', function () { }); it('correctly returns plugin, helpers and permissions, when a governance token address is supplied', async () => { - const GovernanceERC20 = await ethers.getContractFactory( - 'GovernanceERC20' - ); + const GovernanceERC20 = new GovernanceERC20__factory(signers[0]); const governanceERC20 = await GovernanceERC20.deploy( targetDao.address, 'name', @@ -409,7 +411,7 @@ describe('TokenVotingSetup', function () { await tokenVotingSetup.prepareInstallation(daoAddress, data); // check plugin - const PluginFactory = await ethers.getContractFactory('TokenVoting'); + const PluginFactory = new TokenVoting__factory(signers[0]); const tokenVoting = PluginFactory.attach(anticipatedPluginAddress); expect(await tokenVoting.dao()).to.be.equal(daoAddress); @@ -431,9 +433,7 @@ describe('TokenVotingSetup', function () { ); // check helpers - const GovernanceTokenFactory = await ethers.getContractFactory( - 'GovernanceERC20' - ); + const GovernanceTokenFactory = new GovernanceERC20__factory(signers[0]); const governanceTokenContract = GovernanceTokenFactory.attach( anticipatedTokenAddress ); @@ -477,11 +477,9 @@ describe('TokenVotingSetup', function () { it('correctly returns permissions, when the required number of helpers is supplied', async () => { const plugin = ethers.Wallet.createRandom().address; - const GovernanceERC20 = await ethers.getContractFactory( - 'GovernanceERC20' - ); - const GovernanceWrappedERC20 = await ethers.getContractFactory( - 'GovernanceWrappedERC20' + const GovernanceERC20 = new GovernanceERC20__factory(signers[0]); + const GovernanceWrappedERC20 = new GovernanceWrappedERC20__factory( + signers[0] ); const governanceERC20 = await GovernanceERC20.deploy( targetDao.address, diff --git a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts index d1227e4a7..ffc185ba5 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts @@ -107,9 +107,7 @@ describe('TokenVoting', function () { minProposerVotingPower: 0, }; - GovernanceERC20Mock = await ethers.getContractFactory( - 'GovernanceERC20Mock' - ); + GovernanceERC20Mock = new GovernanceERC20Mock__factory(signers[0]); governanceErc20Mock = await GovernanceERC20Mock.deploy( dao.address, 'GOV', diff --git a/packages/contracts/test/plugins/governance/multisig/multisig-setup.ts b/packages/contracts/test/plugins/governance/multisig/multisig-setup.ts index a99cdcf7e..95d44070b 100644 --- a/packages/contracts/test/plugins/governance/multisig/multisig-setup.ts +++ b/packages/contracts/test/plugins/governance/multisig/multisig-setup.ts @@ -66,10 +66,10 @@ describe('MultisigSetup', function () { [[signers[0].address], Object.values(defaultMultisigSettings)] ); - const MultisigSetup = await ethers.getContractFactory('MultisigSetup'); + const MultisigSetup = new MultisigSetup__factory(signers[0]); multisigSetup = await MultisigSetup.deploy(); - MultisigFactory = await ethers.getContractFactory('Multisig'); + MultisigFactory = new Multisig__factory(signers[0]); implementationAddress = await multisigSetup.implementation(); }); @@ -79,7 +79,7 @@ describe('MultisigSetup', function () { }); it('creates multisig base with the correct interface', async () => { - const factory = await ethers.getContractFactory('Multisig'); + const factory = new Multisig__factory(signers[0]); const multisigContract = factory.attach(implementationAddress); expect( @@ -255,7 +255,7 @@ describe('MultisigSetup', function () { await multisigSetup.prepareInstallation(daoAddress, minimum_data); - const factory = await ethers.getContractFactory('Multisig'); + const factory = new Multisig__factory(signers[0]); const multisigContract = factory.attach(anticipatedPluginAddress); expect(await multisigContract.dao()).to.eq(daoAddress); diff --git a/packages/contracts/test/plugins/token/distribution/merkle-distributor.ts b/packages/contracts/test/plugins/token/distribution/merkle-distributor.ts index dc23d46de..821a8ab53 100644 --- a/packages/contracts/test/plugins/token/distribution/merkle-distributor.ts +++ b/packages/contracts/test/plugins/token/distribution/merkle-distributor.ts @@ -12,6 +12,8 @@ import { IERC165Upgradeable__factory, IPlugin__factory, IMerkleDistributor__factory, + TestERC20__factory, + MerkleDistributor__factory, } from '../../../../typechain'; import {deployWithProxy} from '../../../test-utils/proxy'; import BalanceTree from './src/balance-tree'; @@ -38,12 +40,10 @@ describe('MerkleDistributor', function () { // create a DAO dao = await deployNewDAO(signers[0]); - const TestERC20 = await ethers.getContractFactory('TestERC20'); + const TestERC20 = new TestERC20__factory(signers[0]); token = await TestERC20.deploy('FOO', 'FOO', 0); // mint 0 FOO tokens - const MerkleDistributor = await ethers.getContractFactory( - 'MerkleDistributor' - ); + const MerkleDistributor = new MerkleDistributor__factory(signers[0]); distributor = await deployWithProxy(MerkleDistributor); }); diff --git a/packages/contracts/test/plugins/token/distribution/merkle-minter.ts b/packages/contracts/test/plugins/token/distribution/merkle-minter.ts index c26dd915d..1dea27e7b 100644 --- a/packages/contracts/test/plugins/token/distribution/merkle-minter.ts +++ b/packages/contracts/test/plugins/token/distribution/merkle-minter.ts @@ -13,6 +13,9 @@ import { IERC165Upgradeable__factory, IPlugin__factory, IMerkleMinter__factory, + MerkleMinter__factory, + MerkleDistributor__factory, + GovernanceERC20__factory, } from '../../../../typechain'; import BalanceTree from './src/balance-tree'; import {deployNewDAO} from '../../../test-utils/dao'; @@ -53,18 +56,16 @@ describe('MerkleMinter', function () { // create a DAO managingDao = await deployNewDAO(signers[0]); - const GovernanceERC20 = await ethers.getContractFactory('GovernanceERC20'); + const GovernanceERC20 = new GovernanceERC20__factory(signers[0]); token = await GovernanceERC20.deploy(managingDao.address, 'GOV', 'GOV', { receivers: [], amounts: [], }); - const MerkleDistributor = await ethers.getContractFactory( - 'MerkleDistributor' - ); + const MerkleDistributor = new MerkleDistributor__factory(signers[0]); distributorBase = await MerkleDistributor.deploy(); - const MerkleMinter = await ethers.getContractFactory('MerkleMinter'); + const MerkleMinter = new MerkleMinter__factory(signers[0]); minter = await deployWithProxy(MerkleMinter); await minter.initialize( diff --git a/packages/contracts/test/plugins/utils/addresslist.ts b/packages/contracts/test/plugins/utils/addresslist.ts index e2d1c891e..329cb6628 100644 --- a/packages/contracts/test/plugins/utils/addresslist.ts +++ b/packages/contracts/test/plugins/utils/addresslist.ts @@ -2,7 +2,7 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; -import {AddresslistMock} from '../../../typechain'; +import {AddresslistMock, AddresslistMock__factory} from '../../../typechain'; describe('AddresslistMock', function () { let signers: SignerWithAddress[]; @@ -13,7 +13,7 @@ describe('AddresslistMock', function () { }); beforeEach(async () => { - const AddresslistMock = await ethers.getContractFactory('AddresslistMock'); + const AddresslistMock = new AddresslistMock__factory(signers[0]); addresslist = await AddresslistMock.deploy(); }); @@ -103,7 +103,7 @@ describe('AddresslistMock', function () { context('isListed', function () { it('returns `true` if the address is listed', async () => { - addresslist.addAddresses([signers[0].address]); + await addresslist.addAddresses([signers[0].address]); await ethers.provider.send('evm_mine', []); expect(await addresslist.isListed(signers[0].address)).to.equal(true); diff --git a/packages/contracts/test/plugins/utils/ratio.ts b/packages/contracts/test/plugins/utils/ratio.ts index 103b9d402..66c8d8c3b 100644 --- a/packages/contracts/test/plugins/utils/ratio.ts +++ b/packages/contracts/test/plugins/utils/ratio.ts @@ -1,14 +1,14 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; -import {RatioTest} from '../../../typechain'; +import {RatioTest, RatioTest__factory} from '../../../typechain'; import {pctToRatio, RATIO_BASE} from '../../test-utils/voting'; describe('Ratio', function () { let ratio: RatioTest; before(async () => { - const RatioTest = await ethers.getContractFactory('RatioTest'); + const RatioTest = new RatioTest__factory((await ethers.getSigners())[0]); ratio = await RatioTest.deploy(); }); diff --git a/packages/contracts/test/test-utils/conditions.ts b/packages/contracts/test/test-utils/conditions.ts index b32dd0913..8e7d7ddd0 100644 --- a/packages/contracts/test/test-utils/conditions.ts +++ b/packages/contracts/test/test-utils/conditions.ts @@ -1,10 +1,11 @@ import {ethers} from 'hardhat'; import {PermissionConditionMock} from '../../../typechain'; +import {PermissionConditionMock__factory} from '../../typechain'; export async function DeployTestPermissionCondition(): Promise { - const aclConditionFactory = await ethers.getContractFactory( - 'PermissionConditionMock' + const aclConditionFactory = new PermissionConditionMock__factory( + (await ethers.getSigners())[0] ); const permissionCondition = await aclConditionFactory.deploy(); return permissionCondition; diff --git a/packages/contracts/test/test-utils/dao.ts b/packages/contracts/test/test-utils/dao.ts index cdf0e1fdf..202f5b7dc 100644 --- a/packages/contracts/test/test-utils/dao.ts +++ b/packages/contracts/test/test-utils/dao.ts @@ -38,7 +38,8 @@ export async function deployNewDAO(signer: SignerWithAddress): Promise { } export async function getActions() { - const ActionExecuteFactory = await ethers.getContractFactory('ActionExecute'); + const signers = await ethers.getSigners(); + const ActionExecuteFactory = new ActionExecute__factory(signers[0]); let ActionExecute = await ActionExecuteFactory.deploy(); const iface = new ethers.utils.Interface(ActionExecute__factory.abi); diff --git a/packages/contracts/test/test-utils/ens.ts b/packages/contracts/test/test-utils/ens.ts index 1c85a4dba..c0d6951a2 100644 --- a/packages/contracts/test/test-utils/ens.ts +++ b/packages/contracts/test/test-utils/ens.ts @@ -9,18 +9,21 @@ import { ENSRegistry, PublicResolver, } from '../../../typechain'; +import { + ENSRegistry__factory, + ENSSubdomainRegistrar__factory, + PublicResolver__factory, +} from '../../typechain'; export async function deployENSSubdomainRegistrar( owner: SignerWithAddress, managingDao: DAO, domain: string ): Promise { - const ENSRegistryFactory = await ethers.getContractFactory('ENSRegistry'); + const ENSRegistryFactory = new ENSRegistry__factory(owner); const ensRegistry = await ENSRegistryFactory.connect(owner).deploy(); - const PublicResolverFactory = await ethers.getContractFactory( - 'PublicResolver' - ); + const PublicResolverFactory = new PublicResolver__factory(owner); const publicResolver = await PublicResolverFactory.connect(owner).deploy( ensRegistry.address, owner.address @@ -47,9 +50,7 @@ export async function deployENSSubdomainRegistrar( ); } - const ENSSubdomainRegistrar = await ethers.getContractFactory( - 'ENSSubdomainRegistrar' - ); + const ENSSubdomainRegistrar = new ENSSubdomainRegistrar__factory(owner); // Deploy the ENS and approve the subdomain registrar const ensSubdomainRegistrar = await deployWithProxy( diff --git a/packages/contracts/test/test-utils/repo.ts b/packages/contracts/test/test-utils/repo.ts index 5d16b2311..17eff06bc 100644 --- a/packages/contracts/test/test-utils/repo.ts +++ b/packages/contracts/test/test-utils/repo.ts @@ -7,6 +7,7 @@ import { PluginUUPSUpgradeableSetupV1Mock, PluginRepo__factory, PluginUUPSUpgradeableSetupV1Mock__factory, + PluginRepoRegistry__factory, } from '../../typechain'; import {deployWithProxy} from './proxy'; import {getMergedABI} from '../../utils/abi'; @@ -58,11 +59,10 @@ export async function deployPluginRepoFactory( export async function deployPluginRepoRegistry( managingDao: any, - ensSubdomainRegistrar: any + ensSubdomainRegistrar: any, + signer: SignerWithAddress ): Promise { - const PluginRepoRegistry = await ethers.getContractFactory( - 'PluginRepoRegistry' - ); + const PluginRepoRegistry = new PluginRepoRegistry__factory(signer); let pluginRepoRegistry = await deployWithProxy( PluginRepoRegistry diff --git a/packages/contracts/test/test-utils/uups-upgradeable.ts b/packages/contracts/test/test-utils/uups-upgradeable.ts index 2f55b00cb..62466115a 100644 --- a/packages/contracts/test/test-utils/uups-upgradeable.ts +++ b/packages/contracts/test/test-utils/uups-upgradeable.ts @@ -2,6 +2,7 @@ import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; import {Contract} from 'ethers'; import {ethers} from 'hardhat'; +import {PluginUUPSUpgradeableV1Mock__factory} from '../../typechain'; /// Used as a common test suite to test upgradeability of the contracts. /// Presumes that `upgrade` object is set on `this` inside the actual test file. @@ -29,9 +30,8 @@ export function shouldUpgradeCorrectly( describe('UUPS Upgradeability Test', async () => { before(async () => { - const factory = await ethers.getContractFactory( - 'PluginUUPSUpgradeableV1Mock' - ); + const signers = await ethers.getSigners(); + const factory = new PluginUUPSUpgradeableV1Mock__factory(signers[0]); uupsCompatibleBase = (await factory.deploy()).address; }); diff --git a/packages/contracts/test/token/erc20/governance-erc20.ts b/packages/contracts/test/token/erc20/governance-erc20.ts index 6bfa83b89..20ea51d7d 100644 --- a/packages/contracts/test/token/erc20/governance-erc20.ts +++ b/packages/contracts/test/token/erc20/governance-erc20.ts @@ -39,7 +39,7 @@ describe('GovernanceERC20', function () { before(async () => { signers = await ethers.getSigners(); dao = await deployNewDAO(signers[0]); - GovernanceERC20 = await ethers.getContractFactory('GovernanceERC20'); + GovernanceERC20 = new GovernanceERC20__factory(signers[0]); from = signers[0]; to = signers[1]; diff --git a/packages/contracts/test/token/erc20/governance-wrapped-erc20.ts b/packages/contracts/test/token/erc20/governance-wrapped-erc20.ts index dc8f94ed1..7bf3691a0 100644 --- a/packages/contracts/test/token/erc20/governance-wrapped-erc20.ts +++ b/packages/contracts/test/token/erc20/governance-wrapped-erc20.ts @@ -46,10 +46,8 @@ describe('GovernanceWrappedERC20', function () { before(async () => { signers = await ethers.getSigners(); - TestERC20 = await ethers.getContractFactory('TestERC20'); - GovernanceWrappedERC20 = await ethers.getContractFactory( - 'GovernanceWrappedERC20' - ); + TestERC20 = new TestERC20__factory(signers[0]); + GovernanceWrappedERC20 = new GovernanceWrappedERC20__factory(signers[0]); defaultBalances = [ {account: signers[0].address, amount: 123}, {account: signers[1].address, amount: 456}, @@ -105,9 +103,9 @@ describe('GovernanceWrappedERC20', function () { it('should return modified decimals', async () => { const defaultDecimals = await erc20.decimals(); - erc20.setDecimals(5); + await erc20.setDecimals(5); expect(await governanceToken.decimals()).to.eq(5); - erc20.setDecimals(defaultDecimals); + await erc20.setDecimals(defaultDecimals); }); }); From c1088ef47c166ec1daaedec6df8de15d2e831bec Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 12 May 2023 17:00:43 +0200 Subject: [PATCH 090/112] fix: test timings --- packages/contracts/test/framework/dao/dao-registry.ts | 4 ++-- .../contracts/test/framework/plugin/plugin-repo-registry.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/contracts/test/framework/dao/dao-registry.ts b/packages/contracts/test/framework/dao/dao-registry.ts index a9f7167d5..272c75ab1 100644 --- a/packages/contracts/test/framework/dao/dao-registry.ts +++ b/packages/contracts/test/framework/dao/dao-registry.ts @@ -210,7 +210,7 @@ describe('DAORegistry', function () { .to.be.revertedWithCustomError(daoRegistry, 'InvalidDaoSubdomain') .withArgs(subdomainName); } - }); + }).timeout(120000); it('should validate the passed subdomain correctly (> 32 bytes long subdomain)', async () => { const baseSubdomain = @@ -250,6 +250,6 @@ describe('DAORegistry', function () { .to.be.revertedWithCustomError(daoRegistry, 'InvalidDaoSubdomain') .withArgs(subdomainName); } - }); + }).timeout(120000); }); }); diff --git a/packages/contracts/test/framework/plugin/plugin-repo-registry.ts b/packages/contracts/test/framework/plugin/plugin-repo-registry.ts index a7457331d..40bdb1042 100644 --- a/packages/contracts/test/framework/plugin/plugin-repo-registry.ts +++ b/packages/contracts/test/framework/plugin/plugin-repo-registry.ts @@ -219,7 +219,7 @@ describe('PluginRepoRegistry', function () { ) .withArgs(subdomainName); } - }); + }).timeout(120000); it('should validate the passed subdomain correctly (> 32 bytes long subdomain)', async () => { const baseSubdomain = @@ -259,6 +259,6 @@ describe('PluginRepoRegistry', function () { ) .withArgs(subdomainName); } - }); + }).timeout(120000); }); }); From 099018a10ddef8eb409b9f22c83af209091d9748 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 12 May 2023 17:34:55 +0200 Subject: [PATCH 091/112] fix: re-introduced yarn postinstall --- packages/contracts/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/contracts/package.json b/packages/contracts/package.json index b2fb4488b..2589ed165 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -18,6 +18,7 @@ "build": "hardhat compile && yarn typechain && yarn typechain:osx-versions", "build:npm": "rollup --config rollup.config.ts", "build:contracts-versions": "cd ../contracts-versions && yarn build", + "postinstall": "yarn build:contracts-versions", "coverage": "hardhat coverage --solcoverjs ./.solcover.js", "flatten": "hardhat flatten", "analyze": "mythx analyze", From 1a15563164514df493c8fe683eadfa48c362928f Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 12 May 2023 17:35:10 +0200 Subject: [PATCH 092/112] fix: remove redundant includes --- packages/contracts/test/core/dao/dao.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 307f199f0..8b1077d38 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -14,10 +14,7 @@ import { TestERC20__factory, TestERC1155__factory, TestERC721__factory, - IERC1155, - IERC1155Receiver, IERC1155Receiver__factory, - IERC721Receiver, IERC721Receiver__factory, } from '../../../typechain'; import {findEvent, DAO_EVENTS} from '../../../utils/event'; From ba71d523e61f0e6bb974cd2b988fec5f7a7092a6 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 12 May 2023 17:50:55 +0200 Subject: [PATCH 093/112] fix: adapt upgrade tests --- packages/contracts/test/upgrade/dao.ts | 73 ++++++++++++-------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 38e7c2b66..ab6a65fac 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -2,28 +2,33 @@ import {expect} from 'chai'; import {ethers} from 'hardhat'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; -import DAO100 from '../../artifacts/@aragon/osx-versions/versions/v1_0_0/contracts/core/dao/DAO.sol/DAO.json'; -import DAO120 from '../../artifacts/@aragon/osx-versions/versions/v1_2_0/contracts/core/dao/DAO.sol/DAO.json'; -import DAOCurrent from '../../artifacts/src/core/dao/DAO.sol/DAO.json'; +import { + DAO as DAO_V1_0_0, + DAO__factory as DAO_V1_0_0__factory, +} from '../../typechain/osx-versions/v1_0_0/contracts/core/dao/DAO.sol'; +import { + DAO as DAO_V1_2_0, + DAO__factory as DAO_V1_2_0__factory, +} from '../../typechain/osx-versions/v1_2_0/contracts/core/dao/DAO.sol'; +import {DAO, DAO__factory} from '../../typechain'; import {daoExampleURI, ZERO_BYTES32} from '../test-utils/dao'; import {deployWithProxy} from '../test-utils/proxy'; import {UPGRADE_PERMISSIONS} from '../test-utils/permissions'; import {findEventTopicLog} from '../../utils/event'; import {readImplementationValueFromSlot} from '../../utils/storage'; -import {Contract, ContractFactory} from 'ethers'; let signers: SignerWithAddress[]; -let Dao_v1_0_0: ContractFactory; -let Dao_v1_2_0: ContractFactory; -let DaoCurrent: ContractFactory; +let DAO_V1_0_0: DAO_V1_0_0__factory; +let DAO_V1_2_0: DAO_V1_2_0__factory; +let DAO_Current: DAO__factory; -let daoV100Proxy: Contract; -let daoV120Proxy: Contract; +let daoV100Proxy: DAO_V1_0_0; +let daoV120Proxy: DAO_V1_2_0; let daoV100Implementation: string; let daoV120Implementation: string; -let daoCurrentImplementaion: Contract; +let daoCurrentImplementaion: DAO; const EMPTY_DATA = '0x'; @@ -39,31 +44,17 @@ describe('DAO Upgrade', function () { signers = await ethers.getSigners(); // We don't use the typchain here but directly grab the artifacts. This will be changed in an upcoming PR again. - Dao_v1_0_0 = new ContractFactory( - new ethers.utils.Interface(DAO100.abi), - DAO100.bytecode, - signers[0] - ); - - Dao_v1_2_0 = new ContractFactory( - new ethers.utils.Interface(DAO120.abi), - DAO100.bytecode, - signers[0] - ); - - DaoCurrent = new ContractFactory( - new ethers.utils.Interface(DAOCurrent.abi), - DAOCurrent.bytecode, - signers[0] - ); + DAO_V1_0_0 = new DAO_V1_0_0__factory(signers[0]); + DAO_V1_2_0 = new DAO_V1_2_0__factory(signers[0]); + DAO_Current = new DAO__factory(signers[0]); // Deploy the v1.3.0 implementation - daoCurrentImplementaion = await DaoCurrent.deploy(); + daoCurrentImplementaion = await DAO_Current.deploy(); }); context(`v1.0.0 to v1.3.0`, function () { beforeEach(async function () { - daoV100Proxy = await deployWithProxy(Dao_v1_0_0); + daoV100Proxy = await deployWithProxy(DAO_V1_0_0); await daoV100Proxy.initialize( DUMMY_METADATA, signers[0].address, @@ -88,8 +79,9 @@ describe('DAO Upgrade', function () { // Upgrade and call `initializeUpgradeFrom`. const upgradeTx = await daoV100Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - DaoCurrent.interface.encodeFunctionData('initializeUpgradeFrom', [ + DAO_Current.interface.encodeFunctionData('initializeUpgradeFrom', [ [1, 0, 0], + EMPTY_DATA, ]) ); @@ -104,7 +96,7 @@ describe('DAO Upgrade', function () { // Check the emitted implementation. const emittedImplementation = ( - await findEventTopicLog(upgradeTx, Dao_v1_0_0.interface, 'Upgraded') + await findEventTopicLog(upgradeTx, DAO_V1_0_0.interface, 'Upgraded') ).args.implementation; expect(emittedImplementation).to.equal(daoCurrentImplementaion.address); @@ -127,8 +119,9 @@ describe('DAO Upgrade', function () { // Upgrade and call `initializeUpgradeFrom`. await daoV100Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - DaoCurrent.interface.encodeFunctionData('initializeUpgradeFrom', [ + DAO_Current.interface.encodeFunctionData('initializeUpgradeFrom', [ [1, 0, 0], + EMPTY_DATA, ]) ); @@ -195,8 +188,9 @@ describe('DAO Upgrade', function () { // Upgrade and call `initializeUpgradeFrom`. await daoV100Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - DaoCurrent.interface.encodeFunctionData('initializeUpgradeFrom', [ + DAO_Current.interface.encodeFunctionData('initializeUpgradeFrom', [ [1, 0, 0], + EMPTY_DATA, ]) ); @@ -233,7 +227,7 @@ describe('DAO Upgrade', function () { context(`v1.2.0 to v1.3.0`, function () { beforeEach(async function () { - daoV120Proxy = await deployWithProxy(Dao_v1_2_0); + daoV120Proxy = await deployWithProxy(DAO_V1_2_0); await daoV120Proxy.initialize( DUMMY_METADATA, signers[0].address, @@ -258,8 +252,9 @@ describe('DAO Upgrade', function () { // Upgrade and call `initializeUpgradeFrom`. const upgradeTx = await daoV120Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - DaoCurrent.interface.encodeFunctionData('initializeUpgradeFrom', [ + DAO_Current.interface.encodeFunctionData('initializeUpgradeFrom', [ [1, 2, 0], + EMPTY_DATA, ]) ); @@ -274,7 +269,7 @@ describe('DAO Upgrade', function () { // Check the emitted implementation. const emittedImplementation = ( - await findEventTopicLog(upgradeTx, Dao_v1_2_0.interface, 'Upgraded') + await findEventTopicLog(upgradeTx, DAO_V1_2_0.interface, 'Upgraded') ).args.implementation; expect(emittedImplementation).to.equal(daoCurrentImplementaion.address); @@ -297,8 +292,9 @@ describe('DAO Upgrade', function () { // Upgrade and call `initializeUpgradeFrom`. await daoV120Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - DaoCurrent.interface.encodeFunctionData('initializeUpgradeFrom', [ + DAO_Current.interface.encodeFunctionData('initializeUpgradeFrom', [ [1, 2, 0], + EMPTY_DATA, ]) ); @@ -365,8 +361,9 @@ describe('DAO Upgrade', function () { // Upgrade and call `initializeUpgradeFrom`. await daoV120Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - DaoCurrent.interface.encodeFunctionData('initializeUpgradeFrom', [ + DAO_Current.interface.encodeFunctionData('initializeUpgradeFrom', [ [1, 2, 0], + EMPTY_DATA, ]) ); From 51c831cae41a847295fb1f75ebd4fa781575a82a Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 12 May 2023 18:12:40 +0200 Subject: [PATCH 094/112] feat: optimize if statements --- packages/contracts/src/core/dao/DAO.sol | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 812e73cc8..f4ba8e8dc 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -163,14 +163,13 @@ contract DAO is ) external reinitializer(2) { _initData; // Silences the unused function parameter warning. + // Check that the version the contract is upgrading from is < v1.3.0. if (_protocolVersion[0] != 1 || _protocolVersion[1] >= 3) { revert ProtocolVersionUpgradeNotSupported(_protocolVersion); } - // All versions before v1.3.0 must initialize the newly added `_reentrancyStatus`. - if (_protocolVersion[1] < 3) { - _reentrancyStatus = _NOT_ENTERED; - } + // Initialize `_reentrancyStatus` that was added in the current version (v1.3.0). + _reentrancyStatus = _NOT_ENTERED; } /// @inheritdoc PermissionManager From 1ab55d6faa8d73c8bb4491ca64de546aebd8d151 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 12 May 2023 18:23:26 +0200 Subject: [PATCH 095/112] fix: tests --- packages/contracts/test/core/dao/dao.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 8b1077d38..4f69bf209 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -51,6 +51,8 @@ const MAX_ACTIONS = 256; const OZ_INITIALIZED_SLOT_POSITION = 0; const REENTRANCY_STATUS_SLOT_POSITION = 304; +const EMPTY_DATA = '0x'; + const EVENTS = { MetadataSet: 'MetadataSet', TrustedForwarderSet: 'TrustedForwarderSet', @@ -229,7 +231,9 @@ describe('DAO', function () { it('reverts if trying to upgrade from a previous major release', async () => { const uninitializedDao = await deployWithProxy(DAO); - await expect(uninitializedDao.initializeUpgradeFrom([0, 1, 0])) + await expect( + uninitializedDao.initializeUpgradeFrom([0, 1, 0], EMPTY_DATA) + ) .to.be.revertedWithCustomError( dao, 'ProtocolVersionUpgradeNotSupported' @@ -240,7 +244,9 @@ describe('DAO', function () { it('reverts if trying to upgrade to the same version', async () => { const uninitializedDao = await deployWithProxy(DAO); - await expect(uninitializedDao.initializeUpgradeFrom([1, 3, 0])) + await expect( + uninitializedDao.initializeUpgradeFrom([1, 3, 0], EMPTY_DATA) + ) .to.be.revertedWithCustomError( dao, 'ProtocolVersionUpgradeNotSupported' @@ -263,7 +269,9 @@ describe('DAO', function () { ).to.equal(0); // Call `initializeUpgradeFrom` with the previous version 1.3.0 which is not supported. - await expect(uninitializedDao.initializeUpgradeFrom([1, 3, 0])) + await expect( + uninitializedDao.initializeUpgradeFrom([1, 3, 0], EMPTY_DATA) + ) .to.be.revertedWithCustomError( dao, 'ProtocolVersionUpgradeNotSupported' @@ -271,8 +279,9 @@ describe('DAO', function () { .withArgs([1, 3, 0]); // Call `initializeUpgradeFrom` with the previous version 1.2.0. - await expect(uninitializedDao.initializeUpgradeFrom([1, 2, 0])).to.not.be - .reverted; + await expect( + uninitializedDao.initializeUpgradeFrom([1, 2, 0], EMPTY_DATA) + ).to.not.be.reverted; // Expect the contract to be initialized with `_initialized = 2` expect( From 58a9250d77aa96085b997e364f8ad72035b87918 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 12 May 2023 18:24:11 +0200 Subject: [PATCH 096/112] feat: rename initializeUpgradeFrom to initializeFrom --- packages/contracts/src/core/dao/DAO.sol | 2 +- packages/contracts/test/core/dao/dao.ts | 23 ++++++++--------------- packages/contracts/test/upgrade/dao.ts | 24 ++++++++++++------------ 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index f4ba8e8dc..2dd6ba415 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -157,7 +157,7 @@ contract DAO is /// @notice Initializes the DAO after an upgrade from a previous version. /// @param _protocolVersion The protocol version number of the previous DAO implementation contract this upgrade is transitioning from. /// @param _initData The initialization data to be passed to via `upgradeToAndCall` (see [ERC-1967](https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Upgrade)). - function initializeUpgradeFrom( + function initializeFrom( uint8[3] calldata _protocolVersion, bytes calldata _initData ) external reinitializer(2) { diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 4f69bf209..181c1bf2a 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -227,13 +227,11 @@ describe('DAO', function () { }); }); - describe('initializeUpgradeFrom', async () => { + describe('initializeFrom', async () => { it('reverts if trying to upgrade from a previous major release', async () => { const uninitializedDao = await deployWithProxy(DAO); - await expect( - uninitializedDao.initializeUpgradeFrom([0, 1, 0], EMPTY_DATA) - ) + await expect(uninitializedDao.initializeFrom([0, 1, 0], EMPTY_DATA)) .to.be.revertedWithCustomError( dao, 'ProtocolVersionUpgradeNotSupported' @@ -244,9 +242,7 @@ describe('DAO', function () { it('reverts if trying to upgrade to the same version', async () => { const uninitializedDao = await deployWithProxy(DAO); - await expect( - uninitializedDao.initializeUpgradeFrom([1, 3, 0], EMPTY_DATA) - ) + await expect(uninitializedDao.initializeFrom([1, 3, 0], EMPTY_DATA)) .to.be.revertedWithCustomError( dao, 'ProtocolVersionUpgradeNotSupported' @@ -268,20 +264,17 @@ describe('DAO', function () { ).toNumber() ).to.equal(0); - // Call `initializeUpgradeFrom` with the previous version 1.3.0 which is not supported. - await expect( - uninitializedDao.initializeUpgradeFrom([1, 3, 0], EMPTY_DATA) - ) + // Call `initializeFrom` with the previous version 1.3.0 which is not supported. + await expect(uninitializedDao.initializeFrom([1, 3, 0], EMPTY_DATA)) .to.be.revertedWithCustomError( dao, 'ProtocolVersionUpgradeNotSupported' ) .withArgs([1, 3, 0]); - // Call `initializeUpgradeFrom` with the previous version 1.2.0. - await expect( - uninitializedDao.initializeUpgradeFrom([1, 2, 0], EMPTY_DATA) - ).to.not.be.reverted; + // Call `initializeFrom` with the previous version 1.2.0. + await expect(uninitializedDao.initializeFrom([1, 2, 0], EMPTY_DATA)).to + .not.be.reverted; // Expect the contract to be initialized with `_initialized = 2` expect( diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index ab6a65fac..c48127cd1 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -76,10 +76,10 @@ describe('DAO Upgrade', function () { }); it('does not corrupt the DAO storage', async () => { - // Upgrade and call `initializeUpgradeFrom`. + // Upgrade and call `initializeFrom`. const upgradeTx = await daoV100Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - DAO_Current.interface.encodeFunctionData('initializeUpgradeFrom', [ + DAO_Current.interface.encodeFunctionData('initializeFrom', [ [1, 0, 0], EMPTY_DATA, ]) @@ -116,10 +116,10 @@ describe('DAO Upgrade', function () { ethers.utils.id('ROOT_PERMISSION') ); - // Upgrade and call `initializeUpgradeFrom`. + // Upgrade and call `initializeFrom`. await daoV100Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - DAO_Current.interface.encodeFunctionData('initializeUpgradeFrom', [ + DAO_Current.interface.encodeFunctionData('initializeFrom', [ [1, 0, 0], EMPTY_DATA, ]) @@ -185,10 +185,10 @@ describe('DAO Upgrade', function () { // Check that the storage variable now forwarder 1. expect(await daoV100Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); - // Upgrade and call `initializeUpgradeFrom`. + // Upgrade and call `initializeFrom`. await daoV100Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - DAO_Current.interface.encodeFunctionData('initializeUpgradeFrom', [ + DAO_Current.interface.encodeFunctionData('initializeFrom', [ [1, 0, 0], EMPTY_DATA, ]) @@ -249,10 +249,10 @@ describe('DAO Upgrade', function () { }); it('does not corrupt the DAO storage', async () => { - // Upgrade and call `initializeUpgradeFrom`. + // Upgrade and call `initializeFrom`. const upgradeTx = await daoV120Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - DAO_Current.interface.encodeFunctionData('initializeUpgradeFrom', [ + DAO_Current.interface.encodeFunctionData('initializeFrom', [ [1, 2, 0], EMPTY_DATA, ]) @@ -289,10 +289,10 @@ describe('DAO Upgrade', function () { ethers.utils.id('ROOT_PERMISSION') ); - // Upgrade and call `initializeUpgradeFrom`. + // Upgrade and call `initializeFrom`. await daoV120Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - DAO_Current.interface.encodeFunctionData('initializeUpgradeFrom', [ + DAO_Current.interface.encodeFunctionData('initializeFrom', [ [1, 2, 0], EMPTY_DATA, ]) @@ -358,10 +358,10 @@ describe('DAO Upgrade', function () { // Check that the storage variable now forwarder 1. expect(await daoV120Proxy.getTrustedForwarder()).to.equal(FORWARDER_1); - // Upgrade and call `initializeUpgradeFrom`. + // Upgrade and call `initializeFrom`. await daoV120Proxy.upgradeToAndCall( daoCurrentImplementaion.address, - DAO_Current.interface.encodeFunctionData('initializeUpgradeFrom', [ + DAO_Current.interface.encodeFunctionData('initializeFrom', [ [1, 2, 0], EMPTY_DATA, ]) From b71193feb67fa412397db691f11ca7236a2e9cbd Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 15 May 2023 10:56:26 +0200 Subject: [PATCH 097/112] fix: correct test description --- packages/contracts/test/core/dao/dao.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 181c1bf2a..69df2aaf4 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -228,7 +228,7 @@ describe('DAO', function () { }); describe('initializeFrom', async () => { - it('reverts if trying to upgrade from a previous major release', async () => { + it('reverts if trying to upgrade from a different major release', async () => { const uninitializedDao = await deployWithProxy(DAO); await expect(uninitializedDao.initializeFrom([0, 1, 0], EMPTY_DATA)) From 054bca1cf78f42cda0ed7526926cf46ce156f7e5 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 15 May 2023 12:00:40 +0200 Subject: [PATCH 098/112] fix: removed duplicate file --- packages/contracts/src/test/Migration.sol | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 packages/contracts/src/test/Migration.sol diff --git a/packages/contracts/src/test/Migration.sol b/packages/contracts/src/test/Migration.sol deleted file mode 100644 index 0cbdef673..000000000 --- a/packages/contracts/src/test/Migration.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity 0.8.17; - -import {DAO as DAO_v1_0_0} from "@aragon/osx-versions/versions/v1_0_0/contracts/core/dao/DAO.sol"; -import {DAO as DAO_v1_2_0} from "@aragon/osx-versions/versions/v1_2_0/contracts/core/dao/DAO.sol"; From 8566eec600acc743086e073425bfdd370fff6871 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 15 May 2023 14:08:00 +0200 Subject: [PATCH 099/112] fix: typo --- .../plugins/governance/majority-voting/token/TokenVoting.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol b/packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol index 9d5ef3217..3d10ac635 100644 --- a/packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol +++ b/packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol @@ -148,7 +148,7 @@ contract TokenVoting is IMembership, MajorityVotingBase { /// @inheritdoc IMembership function isMember(address _account) external view returns (bool) { - // A member must own or least one token or have at least one token delegated to her/him. + // A member must own at least one token or have at least one token delegated to her/him. return votingToken.getVotes(_account) > 0 || IERC20Upgradeable(address(votingToken)).balanceOf(_account) > 0; From 0604694f937beaffb4a4e47930c303b23a3e374c Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 15 May 2023 14:20:08 +0200 Subject: [PATCH 100/112] fix: delete legacy files --- .../addresslist/build1/AddresslistVoting.sol | 228 -------------- .../build1/AddresslistVotingSetup.sol | 132 -------- .../addresslist/build1/build-metadata.json | 12 - .../token/build1/TokenVoting.sol | 225 -------------- .../token/build1/TokenVotingSetup.sol | 282 ------------------ .../token/build1/build-metadata.json | 13 - 6 files changed, 892 deletions(-) delete mode 100644 packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVoting.sol delete mode 100644 packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVotingSetup.sol delete mode 100644 packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/build-metadata.json delete mode 100644 packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVoting.sol delete mode 100644 packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVotingSetup.sol delete mode 100644 packages/contracts/src/plugins/governance/majority-voting/token/build1/build-metadata.json diff --git a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVoting.sol b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVoting.sol deleted file mode 100644 index aa9d3a13d..000000000 --- a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVoting.sol +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity 0.8.17; - -import {SafeCastUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; - -import {IDAO} from "../../../../../core/dao/IDAO.sol"; -import {RATIO_BASE, _applyRatioCeiled} from "../../../../utils/Ratio.sol"; - -import {IMembership} from "../../../../../core/plugin/membership/IMembership.sol"; -import {Addresslist} from "../../../../utils/Addresslist.sol"; -import {IMajorityVoting} from "../../IMajorityVoting.sol"; -import {MajorityVotingBase} from "../../MajorityVotingBase.sol"; - -/// @title AddresslistVoting v1.0.0 -/// @author Aragon Association - 2021-2023. -/// @notice The majority voting implementation using a list of member addresses. -/// @dev This contract inherits from `MajorityVotingBase` and implements the `IMajorityVoting` interface. -contract AddresslistVoting_v1_0_0 is IMembership, Addresslist, MajorityVotingBase { - using SafeCastUpgradeable for uint256; - - /// @notice The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract. - bytes4 internal constant ADDRESSLIST_VOTING_INTERFACE_ID = - this.initialize.selector ^ this.addAddresses.selector ^ this.removeAddresses.selector; - - /// @notice The ID of the permission required to call the `addAddresses` and `removeAddresses` functions. - bytes32 public constant UPDATE_ADDRESSES_PERMISSION_ID = - keccak256("UPDATE_ADDRESSES_PERMISSION"); - - /// @notice Initializes the component. - /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). - /// @param _dao The IDAO interface of the associated DAO. - /// @param _votingSettings The voting settings. - function initialize( - IDAO _dao, - VotingSettings calldata _votingSettings, - address[] calldata _members - ) external initializer { - __MajorityVotingBase_init(_dao, _votingSettings); - - _addAddresses(_members); - emit MembersAdded({members: _members}); - } - - /// @notice Checks if this or the parent contract supports an interface by its ID. - /// @param _interfaceId The ID of the interface. - /// @return Returns `true` if the interface is supported. - function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { - return - _interfaceId == ADDRESSLIST_VOTING_INTERFACE_ID || - _interfaceId == type(Addresslist).interfaceId || - _interfaceId == type(IMembership).interfaceId || - super.supportsInterface(_interfaceId); - } - - /// @notice Adds new members to the address list. - /// @param _members The addresses of members to be added. - /// @dev This function is used during the plugin initialization. - function addAddresses( - address[] calldata _members - ) external auth(UPDATE_ADDRESSES_PERMISSION_ID) { - _addAddresses(_members); - - emit MembersAdded({members: _members}); - } - - /// @notice Removes existing members from the address list. - /// @param _members The addresses of the members to be removed. - function removeAddresses( - address[] calldata _members - ) external auth(UPDATE_ADDRESSES_PERMISSION_ID) { - _removeAddresses(_members); - - emit MembersRemoved({members: _members}); - } - - /// @inheritdoc MajorityVotingBase - function totalVotingPower(uint256 _blockNumber) public view override returns (uint256) { - return addresslistLengthAtBlock(_blockNumber); - } - - /// @inheritdoc MajorityVotingBase - function createProposal( - bytes calldata _metadata, - IDAO.Action[] calldata _actions, - uint256 _allowFailureMap, - uint64 _startDate, - uint64 _endDate, - VoteOption _voteOption, - bool _tryEarlyExecution - ) external override returns (uint256 proposalId) { - uint64 snapshotBlock; - unchecked { - snapshotBlock = block.number.toUint64() - 1; - } - - if (minProposerVotingPower() != 0 && !isListedAtBlock(_msgSender(), snapshotBlock)) { - revert ProposalCreationForbidden(_msgSender()); - } - - (_startDate, _endDate) = _validateProposalDates(_startDate, _endDate); - - proposalId = _createProposal({ - _creator: _msgSender(), - _metadata: _metadata, - _startDate: _startDate, - _endDate: _endDate, - _actions: _actions, - _allowFailureMap: _allowFailureMap - }); - - // Store proposal related information - Proposal storage proposal_ = proposals[proposalId]; - - proposal_.parameters.startDate = _startDate; - proposal_.parameters.endDate = _endDate; - proposal_.parameters.snapshotBlock = snapshotBlock; - proposal_.parameters.votingMode = votingMode(); - proposal_.parameters.supportThreshold = supportThreshold(); - proposal_.parameters.minVotingPower = _applyRatioCeiled( - totalVotingPower(snapshotBlock), - minParticipation() - ); - - // Reduce costs - if (_allowFailureMap != 0) { - proposal_.allowFailureMap = _allowFailureMap; - } - - for (uint256 i; i < _actions.length; ) { - proposal_.actions.push(_actions[i]); - unchecked { - ++i; - } - } - - if (_voteOption != VoteOption.None) { - vote(proposalId, _voteOption, _tryEarlyExecution); - } - } - - /// @inheritdoc IMembership - function isMember(address _account) external view returns (bool) { - return isListed(_account); - } - - /// @inheritdoc MajorityVotingBase - function _vote( - uint256 _proposalId, - VoteOption _voteOption, - address _voter, - bool _tryEarlyExecution - ) internal override { - Proposal storage proposal_ = proposals[_proposalId]; - - VoteOption state = proposal_.voters[_voter]; - - // Remove the previous vote. - if (state == VoteOption.Yes) { - proposal_.tally.yes = proposal_.tally.yes - 1; - } else if (state == VoteOption.No) { - proposal_.tally.no = proposal_.tally.no - 1; - } else if (state == VoteOption.Abstain) { - proposal_.tally.abstain = proposal_.tally.abstain - 1; - } - - // Store the updated/new vote for the voter. - if (_voteOption == VoteOption.Yes) { - proposal_.tally.yes = proposal_.tally.yes + 1; - } else if (_voteOption == VoteOption.No) { - proposal_.tally.no = proposal_.tally.no + 1; - } else if (_voteOption == VoteOption.Abstain) { - proposal_.tally.abstain = proposal_.tally.abstain + 1; - } - - proposal_.voters[_voter] = _voteOption; - - emit VoteCast({ - proposalId: _proposalId, - voter: _voter, - voteOption: _voteOption, - votingPower: 1 - }); - - if (_tryEarlyExecution && _canExecute(_proposalId)) { - _execute(_proposalId); - } - } - - /// @inheritdoc MajorityVotingBase - function _canVote( - uint256 _proposalId, - address _account, - VoteOption _voteOption - ) internal view override returns (bool) { - Proposal storage proposal_ = proposals[_proposalId]; - - // The proposal vote hasn't started or has already ended. - if (!_isProposalOpen(proposal_)) { - return false; - } - - // The voter votes `None` which is not allowed. - if (_voteOption == VoteOption.None) { - return false; - } - - // The voter has no voting power. - if (!isListedAtBlock(_account, proposal_.parameters.snapshotBlock)) { - return false; - } - - // The voter has already voted but vote replacement is not allowed. - if ( - proposal_.voters[_account] != VoteOption.None && - proposal_.parameters.votingMode != VotingMode.VoteReplacement - ) { - return false; - } - - return true; - } - - /// @dev This empty reserved space is put in place to allow future versions to add new - /// variables without shifting down storage in the inheritance chain. - /// https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - uint256[50] private __gap; -} diff --git a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVotingSetup.sol b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVotingSetup.sol deleted file mode 100644 index fbc447b3d..000000000 --- a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/AddresslistVotingSetup.sol +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity 0.8.17; - -import {IDAO_v1_0_0} from "../../../../../core/dao/legacy/IDAO_v1_0_0.sol"; -import {DAO_v1_0_0} from "../../../../../core/dao/legacy/DAO_v1_0_0.sol"; -import {PermissionLib} from "../../../../../core/permission/PermissionLib.sol"; -import {PluginSetup, IPluginSetup} from "../../../../../framework/plugin/setup/PluginSetup.sol"; -import {MajorityVotingBase} from "../../MajorityVotingBase.sol"; -import {AddresslistVoting} from "./AddresslistVoting.sol"; - -/// @title AddresslistVotingSetup Release 1, Build 1 -/// @author Aragon Association - 2022-2023 -/// @notice The setup contract of the `AddresslistVoting` plugin. -contract AddresslistVotingSetup_R1B1 is PluginSetup { - /// @notice The address of `AddresslistVoting` plugin logic contract to be used in creating proxy contracts. - AddresslistVoting private immutable addresslistVotingBase; - - /// @notice The contract constructor, that deploys the `AddresslistVoting` plugin logic contract. - constructor() { - addresslistVotingBase = new AddresslistVoting(); - } - - /// @inheritdoc IPluginSetup - function prepareInstallation( - address _dao, - bytes calldata _data - ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { - // Decode `_data` to extract the params needed for deploying and initializing `AddresslistVoting` plugin. - (MajorityVotingBase.VotingSettings memory votingSettings, address[] memory members) = abi - .decode(_data, (MajorityVotingBase.VotingSettings, address[])); - - // Prepare and Deploy the plugin proxy. - plugin = createERC1967Proxy( - address(addresslistVotingBase), - abi.encodeWithSelector( - AddresslistVoting.initialize.selector, - _dao, - votingSettings, - members - ) - ); - - // Prepare permissions - PermissionLib.MultiTargetPermission[] - memory permissions = new PermissionLib.MultiTargetPermission[](4); - - // Set permissions to be granted. - // Grant the list of permissions of the plugin to the DAO. - permissions[0] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Grant, - plugin, - _dao, - PermissionLib.NO_CONDITION, - addresslistVotingBase.UPDATE_ADDRESSES_PERMISSION_ID() - ); - - permissions[1] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Grant, - plugin, - _dao, - PermissionLib.NO_CONDITION, - addresslistVotingBase.UPDATE_VOTING_SETTINGS_PERMISSION_ID() - ); - - permissions[2] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Grant, - plugin, - _dao, - PermissionLib.NO_CONDITION, - addresslistVotingBase.UPGRADE_PLUGIN_PERMISSION_ID() - ); - - // Grant `EXECUTE_PERMISSION` of the DAO to the plugin. - permissions[3] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Grant, - _dao, - plugin, - PermissionLib.NO_CONDITION, - DAO(payable(_dao)).EXECUTE_PERMISSION_ID() - ); - - preparedSetupData.permissions = permissions; - } - - /// @inheritdoc IPluginSetup - function prepareUninstallation( - address _dao, - SetupPayload calldata _payload - ) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) { - // Prepare permissions - permissions = new PermissionLib.MultiTargetPermission[](4); - - // Set permissions to be Revoked. - permissions[0] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Revoke, - _payload.plugin, - _dao, - PermissionLib.NO_CONDITION, - addresslistVotingBase.UPDATE_ADDRESSES_PERMISSION_ID() - ); - - permissions[1] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Revoke, - _payload.plugin, - _dao, - PermissionLib.NO_CONDITION, - addresslistVotingBase.UPDATE_VOTING_SETTINGS_PERMISSION_ID() - ); - - permissions[2] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Revoke, - _payload.plugin, - _dao, - PermissionLib.NO_CONDITION, - addresslistVotingBase.UPGRADE_PLUGIN_PERMISSION_ID() - ); - - permissions[3] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Revoke, - _dao, - _payload.plugin, - PermissionLib.NO_CONDITION, - DAO(payable(_dao)).EXECUTE_PERMISSION_ID() - ); - } - - /// @inheritdoc IPluginSetup - function implementation() external view returns (address) { - return address(addresslistVotingBase); - } -} diff --git a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/build-metadata.json b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/build-metadata.json deleted file mode 100644 index e746b71aa..000000000 --- a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build1/build-metadata.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "ui": "", - "change": "", - "pluginSetupABI": { - "prepareInstallation": [ - "tuple(uint8 votingMode, uint64 supportThreshold, uint64 minParticipation, uint64 minDuration, uint256 minProposerVotingPower) votingSettings", - "address[] members" - ], - "prepareUpdate": [""], - "prepareUninstallation": [""] - } -} diff --git a/packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVoting.sol b/packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVoting.sol deleted file mode 100644 index 7b6c6089d..000000000 --- a/packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVoting.sol +++ /dev/null @@ -1,225 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity 0.8.17; - -import {IVotesUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol"; -import {SafeCastUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; - -import {IMembership} from "../../../../core/plugin/membership/IMembership.sol"; -import {IDAO} from "../../../../core/dao/IDAO.sol"; -import {RATIO_BASE, _applyRatioCeiled} from "../../../utils/Ratio.sol"; -import {MajorityVotingBase} from "../MajorityVotingBase.sol"; -import {IMajorityVoting} from "../IMajorityVoting.sol"; - -/// @title TokenVoting -/// @author Aragon Association - 2021-2023 -/// @notice The majority voting implementation using an [OpenZeppelin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) compatible governance token. -/// @dev This contract inherits from `MajorityVotingBase` and implements the `IMajorityVoting` interface. -contract TokenVoting is IMembership, MajorityVotingBase { - using SafeCastUpgradeable for uint256; - - /// @notice The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract. - bytes4 internal constant TOKEN_VOTING_INTERFACE_ID = - this.initialize.selector ^ this.getVotingToken.selector; - - /// @notice An [OpenZeppelin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) compatible contract referencing the token being used for voting. - IVotesUpgradeable private votingToken; - - /// @notice Thrown if the voting power is zero - error NoVotingPower(); - - /// @notice Initializes the component. - /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). - /// @param _dao The IDAO interface of the associated DAO. - /// @param _votingSettings The voting settings. - /// @param _token The [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token used for voting. - function initialize( - IDAO _dao, - VotingSettings calldata _votingSettings, - IVotesUpgradeable _token - ) external initializer { - __MajorityVotingBase_init(_dao, _votingSettings); - - votingToken = _token; - - emit MembershipContractAnnounced({definingContract: address(_token)}); - } - - /// @notice Checks if this or the parent contract supports an interface by its ID. - /// @param _interfaceId The ID of the interface. - /// @return Returns `true` if the interface is supported. - function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { - return - _interfaceId == TOKEN_VOTING_INTERFACE_ID || - _interfaceId == type(IMembership).interfaceId || - super.supportsInterface(_interfaceId); - } - - /// @notice getter function for the voting token. - /// @dev public function also useful for registering interfaceId and for distinguishing from majority voting interface. - /// @return The token used for voting. - function getVotingToken() public view returns (IVotesUpgradeable) { - return votingToken; - } - - /// @inheritdoc MajorityVotingBase - function totalVotingPower(uint256 _blockNumber) public view override returns (uint256) { - return votingToken.getPastTotalSupply(_blockNumber); - } - - /// @inheritdoc MajorityVotingBase - function createProposal( - bytes calldata _metadata, - IDAO.Action[] calldata _actions, - uint256 _allowFailureMap, - uint64 _startDate, - uint64 _endDate, - VoteOption _voteOption, - bool _tryEarlyExecution - ) external override returns (uint256 proposalId) { - uint256 snapshotBlock; - unchecked { - snapshotBlock = block.number - 1; - } - - uint256 totalVotingPower_ = totalVotingPower(snapshotBlock); - - if (totalVotingPower_ == 0) { - revert NoVotingPower(); - } - - if (votingToken.getPastVotes(_msgSender(), snapshotBlock) < minProposerVotingPower()) { - revert ProposalCreationForbidden(_msgSender()); - } - - proposalId = _createProposal({ - _creator: _msgSender(), - _metadata: _metadata, - _startDate: _startDate, - _endDate: _endDate, - _actions: _actions, - _allowFailureMap: _allowFailureMap - }); - - // Store proposal related information - Proposal storage proposal_ = proposals[proposalId]; - - (proposal_.parameters.startDate, proposal_.parameters.endDate) = _validateProposalDates( - _startDate, - _endDate - ); - proposal_.parameters.snapshotBlock = snapshotBlock.toUint64(); - proposal_.parameters.votingMode = votingMode(); - proposal_.parameters.supportThreshold = supportThreshold(); - proposal_.parameters.minVotingPower = _applyRatioCeiled( - totalVotingPower_, - minParticipation() - ); - - // Reduce costs - if (_allowFailureMap != 0) { - proposal_.allowFailureMap = _allowFailureMap; - } - - for (uint256 i; i < _actions.length; ) { - proposal_.actions.push(_actions[i]); - unchecked { - ++i; - } - } - - if (_voteOption != VoteOption.None) { - vote(proposalId, _voteOption, _tryEarlyExecution); - } - } - - /// @inheritdoc IMembership - function isMember(address _account) external view returns (bool) { - /// whatever condition - return votingToken.getVotes(_account) > 0; - } - - /// @inheritdoc MajorityVotingBase - function _vote( - uint256 _proposalId, - VoteOption _voteOption, - address _voter, - bool _tryEarlyExecution - ) internal override { - Proposal storage proposal_ = proposals[_proposalId]; - - // This could re-enter, though we can assume the governance token is not malicious - uint256 votingPower = votingToken.getPastVotes(_voter, proposal_.parameters.snapshotBlock); - VoteOption state = proposal_.voters[_voter]; - - // If voter had previously voted, decrease count - if (state == VoteOption.Yes) { - proposal_.tally.yes = proposal_.tally.yes - votingPower; - } else if (state == VoteOption.No) { - proposal_.tally.no = proposal_.tally.no - votingPower; - } else if (state == VoteOption.Abstain) { - proposal_.tally.abstain = proposal_.tally.abstain - votingPower; - } - - // write the updated/new vote for the voter. - if (_voteOption == VoteOption.Yes) { - proposal_.tally.yes = proposal_.tally.yes + votingPower; - } else if (_voteOption == VoteOption.No) { - proposal_.tally.no = proposal_.tally.no + votingPower; - } else if (_voteOption == VoteOption.Abstain) { - proposal_.tally.abstain = proposal_.tally.abstain + votingPower; - } - - proposal_.voters[_voter] = _voteOption; - - emit VoteCast({ - proposalId: _proposalId, - voter: _voter, - voteOption: _voteOption, - votingPower: votingPower - }); - - if (_tryEarlyExecution && _canExecute(_proposalId)) { - _execute(_proposalId); - } - } - - /// @inheritdoc MajorityVotingBase - function _canVote( - uint256 _proposalId, - address _account, - VoteOption _voteOption - ) internal view override returns (bool) { - Proposal storage proposal_ = proposals[_proposalId]; - - // The proposal vote hasn't started or has already ended. - if (!_isProposalOpen(proposal_)) { - return false; - } - - // The voter votes `None` which is not allowed. - if (_voteOption == VoteOption.None) { - return false; - } - - // The voter has no voting power. - if (votingToken.getPastVotes(_account, proposal_.parameters.snapshotBlock) == 0) { - return false; - } - - // The voter has already voted but vote replacment is not allowed. - if ( - proposal_.voters[_account] != VoteOption.None && - proposal_.parameters.votingMode != VotingMode.VoteReplacement - ) { - return false; - } - - return true; - } - - /// @dev This empty reserved space is put in place to allow future versions to add new - /// variables without shifting down storage in the inheritance chain. - /// https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - uint256[49] private __gap; -} diff --git a/packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVotingSetup.sol b/packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVotingSetup.sol deleted file mode 100644 index 74616e4b1..000000000 --- a/packages/contracts/src/plugins/governance/majority-voting/token/build1/TokenVotingSetup.sol +++ /dev/null @@ -1,282 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity 0.8.17; - -import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; -import {Address} from "@openzeppelin/contracts/utils/Address.sol"; -import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; -import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import {IVotesUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol"; - -import {IDAO_v1_0_0} from "../../../../core/dao/legacy/IDAO_v1_0_0.sol"; -import {DAO_v1_0_0} from "../../../../../core/dao/DAO_v1_0_0.sol"; -import {PermissionLib} from "../../../../../core/permission/PermissionLib.sol"; -import {PluginSetup, IPluginSetup} from "../../../../../framework/plugin/setup/PluginSetup.sol"; -import {GovernanceERC20} from "../../../../token/ERC20/governance/GovernanceERC20.sol"; -import {GovernanceWrappedERC20} from "../../../../token/ERC20/governance/GovernanceWrappedERC20.sol"; -import {IGovernanceWrappedERC20} from "../../../../token/ERC20/governance/IGovernanceWrappedERC20.sol"; -import {MajorityVotingBase} from "../MajorityVotingBase.sol"; -import {TokenVoting} from "./TokenVoting.sol"; - -/// @title TokenVotingSetup -/// @author Aragon Association - 2022-2023 -/// @notice The setup contract of the `TokenVoting` plugin. -contract TokenVotingSetup_R1B1 is PluginSetup { - using Address for address; - using Clones for address; - using ERC165Checker for address; - - /// @notice The address of the `TokenVoting` base contract. - TokenVoting private immutable tokenVotingBase; - - /// @notice The address of the `GovernanceERC20` base contract. - address public immutable governanceERC20Base; - - /// @notice The address of the `GovernanceWrappedERC20` base contract. - address public immutable governanceWrappedERC20Base; - - /// @notice The token settings struct. - /// @param addr The token address. If this is `address(0)`, a new `GovernanceERC20` token is deployed. If not, the existing token is wrapped as an `GovernanceWrappedERC20`. - /// @param name The token name. This parameter is only relevant if the token address is `address(0)`. - /// @param name The token symbol. This parameter is only relevant if the token address is `address(0)`. - struct TokenSettings { - address addr; - string name; - string symbol; - } - - /// @notice Thrown if token address is passed which is not a token. - /// @param token The token address - error TokenNotContract(address token); - - /// @notice Thrown if token address is not ERC20. - /// @param token The token address - error TokenNotERC20(address token); - - /// @notice Thrown if passed helpers array is of wrong length. - /// @param length The array length of passed helpers. - error WrongHelpersArrayLength(uint256 length); - - /// @notice The contract constructor, that deploys the bases. - constructor() { - governanceERC20Base = address( - new GovernanceERC20( - IDAO(address(0)), - "", - "", - GovernanceERC20.MintSettings(new address[](0), new uint256[](0)) - ) - ); - governanceWrappedERC20Base = address( - new GovernanceWrappedERC20(IERC20Upgradeable(address(0)), "", "") - ); - tokenVotingBase = new TokenVoting(); - } - - /// @inheritdoc IPluginSetup - function prepareInstallation( - address _dao, - bytes calldata _data - ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { - // Decode `_data` to extract the params needed for deploying and initializing `TokenVoting` plugin, - // and the required helpers - ( - MajorityVotingBase.VotingSettings memory votingSettings, - TokenSettings memory tokenSettings, - // only used for GovernanceERC20(token is not passed) - GovernanceERC20.MintSettings memory mintSettings - ) = abi.decode( - _data, - (MajorityVotingBase.VotingSettings, TokenSettings, GovernanceERC20.MintSettings) - ); - - address token = tokenSettings.addr; - - // Prepare helpers. - address[] memory helpers = new address[](1); - - if (token != address(0)) { - if (!token.isContract()) { - revert TokenNotContract(token); - } - - if (!_isERC20(token)) { - revert TokenNotERC20(token); - } - - // [0] = IERC20Upgradeable, [1] = IVotesUpgradeable, [2] = IGovernanceWrappedERC20 - bool[] memory supportedIds = _getTokenInterfaceIds(token); - - if ( - // If token supports none of them - // it's simply ERC20 which gets checked by _isERC20 - // Currently, not a satisfiable check. - (!supportedIds[0] && !supportedIds[1] && !supportedIds[2]) || - // If token supports IERC20, but neither - // IVotes nor IGovernanceWrappedERC20, it needs wrapping. - (supportedIds[0] && !supportedIds[1] && !supportedIds[2]) - ) { - token = governanceWrappedERC20Base.clone(); - // User already has a token. We need to wrap it in - // GovernanceWrappedERC20 in order to make the token - // include governance functionality. - GovernanceWrappedERC20(token).initialize( - IERC20Upgradeable(tokenSettings.addr), - tokenSettings.name, - tokenSettings.symbol - ); - } - } else { - // Clone a `GovernanceERC20`. - token = governanceERC20Base.clone(); - GovernanceERC20(token).initialize( - IDAO(_dao), - tokenSettings.name, - tokenSettings.symbol, - mintSettings - ); - } - - helpers[0] = token; - - // Prepare and deploy plugin proxy. - plugin = createERC1967Proxy( - address(tokenVotingBase), - abi.encodeWithSelector(TokenVoting.initialize.selector, _dao, votingSettings, token) - ); - - // Prepare permissions - PermissionLib.MultiTargetPermission[] - memory permissions = new PermissionLib.MultiTargetPermission[]( - tokenSettings.addr != address(0) ? 3 : 4 - ); - - // Set plugin permissions to be granted. - // Grant the list of permissions of the plugin to the DAO. - permissions[0] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Grant, - plugin, - _dao, - PermissionLib.NO_CONDITION, - tokenVotingBase.UPDATE_VOTING_SETTINGS_PERMISSION_ID() - ); - - permissions[1] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Grant, - plugin, - _dao, - PermissionLib.NO_CONDITION, - tokenVotingBase.UPGRADE_PLUGIN_PERMISSION_ID() - ); - - // Grant `EXECUTE_PERMISSION` of the DAO to the plugin. - permissions[2] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Grant, - _dao, - plugin, - PermissionLib.NO_CONDITION, - DAO(payable(_dao)).EXECUTE_PERMISSION_ID() - ); - - if (tokenSettings.addr == address(0)) { - bytes32 tokenMintPermission = GovernanceERC20(token).MINT_PERMISSION_ID(); - - permissions[3] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Grant, - token, - _dao, - PermissionLib.NO_CONDITION, - tokenMintPermission - ); - } - - preparedSetupData.helpers = helpers; - preparedSetupData.permissions = permissions; - } - - /// @inheritdoc IPluginSetup - function prepareUninstallation( - address _dao, - SetupPayload calldata _payload - ) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) { - // Prepare permissions. - uint256 helperLength = _payload.currentHelpers.length; - if (helperLength != 1) { - revert WrongHelpersArrayLength({length: helperLength}); - } - - // token can be either GovernanceERC20, GovernanceWrappedERC20, or IVotesUpgradeable, which - // does not follow the GovernanceERC20 and GovernanceWrappedERC20 standard. - address token = _payload.currentHelpers[0]; - - bool[] memory supportedIds = _getTokenInterfaceIds(token); - - bool isGovernanceERC20 = supportedIds[0] && supportedIds[1] && !supportedIds[2]; - - permissions = new PermissionLib.MultiTargetPermission[](isGovernanceERC20 ? 4 : 3); - - // Set permissions to be Revoked. - permissions[0] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Revoke, - _payload.plugin, - _dao, - PermissionLib.NO_CONDITION, - tokenVotingBase.UPDATE_VOTING_SETTINGS_PERMISSION_ID() - ); - - permissions[1] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Revoke, - _payload.plugin, - _dao, - PermissionLib.NO_CONDITION, - tokenVotingBase.UPGRADE_PLUGIN_PERMISSION_ID() - ); - - permissions[2] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Revoke, - _dao, - _payload.plugin, - PermissionLib.NO_CONDITION, - DAO(payable(_dao)).EXECUTE_PERMISSION_ID() - ); - - // Revocation of permission is necessary only if the deployed token is GovernanceERC20, - // as GovernanceWrapped does not possess this permission. Only return the following - // if it's type of GovernanceERC20, otherwise revoking this permission wouldn't have any effect. - if (isGovernanceERC20) { - permissions[3] = PermissionLib.MultiTargetPermission( - PermissionLib.Operation.Revoke, - token, - _dao, - PermissionLib.NO_CONDITION, - GovernanceERC20(token).MINT_PERMISSION_ID() - ); - } - } - - /// @inheritdoc IPluginSetup - function implementation() external view virtual override returns (address) { - return address(tokenVotingBase); - } - - /// @notice Retrieves the interface identifiers supported by the token contract. - /// @dev It is crucial to verify if the provided token address represents a valid contract before using the below. - /// @param token The token address - function _getTokenInterfaceIds(address token) private view returns (bool[] memory) { - bytes4[] memory interfaceIds = new bytes4[](3); - interfaceIds[0] = type(IERC20Upgradeable).interfaceId; - interfaceIds[1] = type(IVotesUpgradeable).interfaceId; - interfaceIds[2] = type(IGovernanceWrappedERC20).interfaceId; - return token.getSupportedInterfaces(interfaceIds); - } - - /// @notice Unsatisfiably determines if the contract is an ERC20 token. - /// @dev It's important to first check whether token is a contract prior to this call. - /// @param token The token address - function _isERC20(address token) private view returns (bool) { - (bool success, bytes memory data) = token.staticcall( - abi.encodeWithSelector(IERC20Upgradeable.balanceOf.selector, address(this)) - ); - return success && data.length == 0x20; - } -} diff --git a/packages/contracts/src/plugins/governance/majority-voting/token/build1/build-metadata.json b/packages/contracts/src/plugins/governance/majority-voting/token/build1/build-metadata.json deleted file mode 100644 index 0f451e2bc..000000000 --- a/packages/contracts/src/plugins/governance/majority-voting/token/build1/build-metadata.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "ui": "", - "change": "", - "pluginSetupABI": { - "prepareInstallation": [ - "tuple(uint8 votingMode, uint64 supportThreshold, uint64 minParticipation, uint64 minDuration, uint256 minProposerVotingPower) votingSettings", - "tuple(address addr, string name, string symbol) tokenSettings", - "tuple(address[] receivers, uint256[] amounts) mintSettings" - ], - "prepareUpdate": [""], - "prepareUninstallation": [""] - } -} From 8b51d4b411347b1a35cd07f85a7be924f1f20f4a Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Mon, 15 May 2023 14:22:44 +0200 Subject: [PATCH 101/112] revert: metadata changes as they will happen in #375 --- .../majority-voting/addresslist/build-metadata.json | 4 ++-- .../governance/majority-voting/token/build-metadata.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build-metadata.json b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build-metadata.json index 683173e55..e746b71aa 100644 --- a/packages/contracts/src/plugins/governance/majority-voting/addresslist/build-metadata.json +++ b/packages/contracts/src/plugins/governance/majority-voting/addresslist/build-metadata.json @@ -6,7 +6,7 @@ "tuple(uint8 votingMode, uint64 supportThreshold, uint64 minParticipation, uint64 minDuration, uint256 minProposerVotingPower) votingSettings", "address[] members" ], - "prepareUpdate": [], - "prepareUninstallation": [] + "prepareUpdate": [""], + "prepareUninstallation": [""] } } diff --git a/packages/contracts/src/plugins/governance/majority-voting/token/build-metadata.json b/packages/contracts/src/plugins/governance/majority-voting/token/build-metadata.json index ee68a93d2..0f451e2bc 100644 --- a/packages/contracts/src/plugins/governance/majority-voting/token/build-metadata.json +++ b/packages/contracts/src/plugins/governance/majority-voting/token/build-metadata.json @@ -7,7 +7,7 @@ "tuple(address addr, string name, string symbol) tokenSettings", "tuple(address[] receivers, uint256[] amounts) mintSettings" ], - "prepareUpdate": [], - "prepareUninstallation": [] + "prepareUpdate": [""], + "prepareUninstallation": [""] } } From 0e1128aac832dcf3946ed890487dd353b377aa94 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Tue, 16 May 2023 11:41:23 +0200 Subject: [PATCH 102/112] fix: merge conflicts --- .../contracts/src/test/osx-versions/Migration.sol | 3 --- .../test/plugins/governance/multisig/multisig.ts | 12 ------------ packages/contracts/test/plugins/utils/ratio.ts | 4 ---- 3 files changed, 19 deletions(-) diff --git a/packages/contracts/src/test/osx-versions/Migration.sol b/packages/contracts/src/test/osx-versions/Migration.sol index 70325a110..bbe19a2ad 100644 --- a/packages/contracts/src/test/osx-versions/Migration.sol +++ b/packages/contracts/src/test/osx-versions/Migration.sol @@ -2,8 +2,6 @@ pragma solidity 0.8.17; -<<<<<<< HEAD -======= /* * @title Migration * @@ -21,6 +19,5 @@ pragma solidity 0.8.17; * */ ->>>>>>> develop import {DAO as DAO_v1_0_0} from "@aragon/osx-versions/versions/v1_0_0/contracts/core/dao/DAO.sol"; import {DAO as DAO_v1_2_0} from "@aragon/osx-versions/versions/v1_2_0/contracts/core/dao/DAO.sol"; diff --git a/packages/contracts/test/plugins/governance/multisig/multisig.ts b/packages/contracts/test/plugins/governance/multisig/multisig.ts index 07f2d2c05..ff4ab8d7a 100644 --- a/packages/contracts/test/plugins/governance/multisig/multisig.ts +++ b/packages/contracts/test/plugins/governance/multisig/multisig.ts @@ -854,19 +854,11 @@ describe('Multisig', function () { it('should revert if startDate is < than now', async () => { // set next block time & mine a block with this time. -<<<<<<< HEAD - const nextBlockTime = (await getTime()) + 500; - await ethers.provider.send('evm_mine', [nextBlockTime]); - // set next block's timestamp - const nextTimeStamp = nextBlockTime + 500; - await setTimeForNextBlock(nextTimeStamp); -======= const block1Timestamp = (await getTime()) + 12; await ethers.provider.send('evm_mine', [block1Timestamp]); // set next block's timestamp const block2Timestamp = block1Timestamp + 12; await setTimeForNextBlock(block2Timestamp); ->>>>>>> develop await expect( multisig.createProposal( @@ -880,11 +872,7 @@ describe('Multisig', function () { ) ) .to.be.revertedWithCustomError(multisig, 'DateOutOfBounds') -<<<<<<< HEAD - .withArgs(nextTimeStamp, 5); -======= .withArgs(block2Timestamp, 5); ->>>>>>> develop }); it('should revert if endDate is < than startDate', async () => { diff --git a/packages/contracts/test/plugins/utils/ratio.ts b/packages/contracts/test/plugins/utils/ratio.ts index b667e42e1..0405d1e52 100644 --- a/packages/contracts/test/plugins/utils/ratio.ts +++ b/packages/contracts/test/plugins/utils/ratio.ts @@ -8,12 +8,8 @@ describe('Ratio', function () { let ratio: RatioTest; before(async () => { -<<<<<<< HEAD - const RatioTest = new RatioTest__factory((await ethers.getSigners())[0]); -======= const signers = await ethers.getSigners(); const RatioTest = new RatioTest__factory(signers[0]); ->>>>>>> develop ratio = await RatioTest.deploy(); }); From 3c64f8e98b91dcae7acb8b23ec571e7d8338da8e Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Tue, 16 May 2023 11:45:44 +0200 Subject: [PATCH 103/112] fix: re-order changelog entries --- packages/contracts/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/CHANGELOG.md b/packages/contracts/CHANGELOG.md index 8055afbb9..285e98217 100644 --- a/packages/contracts/CHANGELOG.md +++ b/packages/contracts/CHANGELOG.md @@ -9,8 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Added `allowFailureMap` to `IDAO.Executed` event. - Added a `nonReentrant` modifier to the `execute` function in the `DAO` contract. +- Added `allowFailureMap` to `IDAO.Executed` event. ### Changed From d08e1eeba8a69e9bebe9a3caacb0b9dd214bf87d Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Tue, 16 May 2023 11:52:27 +0200 Subject: [PATCH 104/112] fix: remove wrong/redundant import originating from merge --- .../deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/contracts/deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts b/packages/contracts/deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts index fd05696f5..e53df13b0 100644 --- a/packages/contracts/deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts +++ b/packages/contracts/deploy/new/40_finalize-managing-dao/40_revoke-permissions.ts @@ -4,7 +4,6 @@ import {getContractAddress, managePermissions, Permission} from '../../helpers'; import {Operation} from '../../../utils/types'; import {DAO__factory, PluginRepo__factory} from '../../../typechain'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; -import {DAO__factory} from '../../../typechain/osx-versions/v1_2_0/contracts/core/dao/DAO.sol'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const {ethers} = hre; From cc571dcaed2dbd5f3d21a5ed6ca381ea95ac0219 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Tue, 16 May 2023 12:09:21 +0200 Subject: [PATCH 105/112] feat: improve upgrade version checks --- packages/contracts/src/core/dao/DAO.sol | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 2dd6ba415..40eb849a9 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -163,8 +163,12 @@ contract DAO is ) external reinitializer(2) { _initData; // Silences the unused function parameter warning. - // Check that the version the contract is upgrading from is < v1.3.0. - if (_protocolVersion[0] != 1 || _protocolVersion[1] >= 3) { + // Check that the contract is not upgrading from a different major release. + if (_protocolVersion[0] != 1) { + revert ProtocolVersionUpgradeNotSupported(_protocolVersion); + } + // Check that the contract is not downgrading from a newer or the same minor release. + if (_protocolVersion[1] >= 3) { revert ProtocolVersionUpgradeNotSupported(_protocolVersion); } From 649732bf29643735916cd16e3ecf397ca6992afd Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Tue, 16 May 2023 13:15:19 +0200 Subject: [PATCH 106/112] fix: remove redundant ROOT_PERMISSION grant call --- packages/contracts/test/upgrade/dao.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index c48127cd1..15db4baf5 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -110,11 +110,6 @@ describe('DAO Upgrade', function () { signers[0].address, ethers.utils.id('EXECUTE_PERMISSION') ); - await daoV100Proxy.grant( - daoV100Proxy.address, - signers[0].address, - ethers.utils.id('ROOT_PERMISSION') - ); // Upgrade and call `initializeFrom`. await daoV100Proxy.upgradeToAndCall( @@ -283,11 +278,6 @@ describe('DAO Upgrade', function () { signers[0].address, ethers.utils.id('EXECUTE_PERMISSION') ); - await daoV120Proxy.grant( - daoV120Proxy.address, - signers[0].address, - ethers.utils.id('ROOT_PERMISSION') - ); // Upgrade and call `initializeFrom`. await daoV120Proxy.upgradeToAndCall( From c275b62edcc5a56486e2ec369602d15301b0a70e Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Tue, 16 May 2023 13:22:21 +0200 Subject: [PATCH 107/112] feat: added more checks to the upgrade tests --- packages/contracts/test/upgrade/dao.ts | 78 ++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/packages/contracts/test/upgrade/dao.ts b/packages/contracts/test/upgrade/dao.ts index 15db4baf5..491f082f0 100644 --- a/packages/contracts/test/upgrade/dao.ts +++ b/packages/contracts/test/upgrade/dao.ts @@ -111,6 +111,34 @@ describe('DAO Upgrade', function () { ethers.utils.id('EXECUTE_PERMISSION') ); + // Check that permissions are granted before the upgrade + expect( + await daoV100Proxy.hasPermission( + daoV100Proxy.address, + signers[0].address, + ethers.utils.id('EXECUTE_PERMISSION'), + EMPTY_DATA + ) + ).to.be.true; + expect( + await daoV100Proxy.hasPermission( + daoV100Proxy.address, + signers[0].address, + ethers.utils.id('ROOT_PERMISSION'), + EMPTY_DATA + ) + ).to.be.true; + + // Check that a arbitrary permission is not granted. + expect( + await daoV100Proxy.hasPermission( + daoV100Proxy.address, + signers[0].address, + ethers.utils.id('NOT_GRANTED'), + EMPTY_DATA + ) + ).to.be.false; + // Upgrade and call `initializeFrom`. await daoV100Proxy.upgradeToAndCall( daoCurrentImplementaion.address, @@ -129,6 +157,7 @@ describe('DAO Upgrade', function () { ); expect(implementationAfterUpgrade).to.not.equal(daoV100Implementation); + // Check that the permissions are still granted. expect( await daoV100Proxy.hasPermission( daoV100Proxy.address, @@ -145,6 +174,16 @@ describe('DAO Upgrade', function () { EMPTY_DATA ) ).to.be.true; + + // Check that a the arbitrary permission is still not granted. + expect( + await daoV100Proxy.hasPermission( + daoV100Proxy.address, + signers[0].address, + ethers.utils.id('NOT_GRANTED'), + EMPTY_DATA + ) + ).to.be.false; }); it('executes actions after the upgrade', async () => { @@ -279,6 +318,34 @@ describe('DAO Upgrade', function () { ethers.utils.id('EXECUTE_PERMISSION') ); + // Check that permissions are granted before the upgrade + expect( + await daoV120Proxy.hasPermission( + daoV120Proxy.address, + signers[0].address, + ethers.utils.id('EXECUTE_PERMISSION'), + EMPTY_DATA + ) + ).to.be.true; + expect( + await daoV120Proxy.hasPermission( + daoV120Proxy.address, + signers[0].address, + ethers.utils.id('ROOT_PERMISSION'), + EMPTY_DATA + ) + ).to.be.true; + + // Check that a arbitrary permission is not granted. + expect( + await daoV120Proxy.hasPermission( + daoV120Proxy.address, + signers[0].address, + ethers.utils.id('NOT_GRANTED'), + EMPTY_DATA + ) + ).to.be.false; + // Upgrade and call `initializeFrom`. await daoV120Proxy.upgradeToAndCall( daoCurrentImplementaion.address, @@ -297,6 +364,7 @@ describe('DAO Upgrade', function () { ); expect(implementationAfterUpgrade).to.not.equal(daoV120Implementation); + // Check that the permissions are still granted. expect( await daoV120Proxy.hasPermission( daoV120Proxy.address, @@ -313,6 +381,16 @@ describe('DAO Upgrade', function () { EMPTY_DATA ) ).to.be.true; + + // Check that a the arbitrary permission is still not granted. + expect( + await daoV120Proxy.hasPermission( + daoV120Proxy.address, + signers[0].address, + ethers.utils.id('NOT_GRANTED'), + EMPTY_DATA + ) + ).to.be.false; }); it('executes actions after the upgrade', async () => { From a97a9bac9e2bc56663a80089abe2562caebcfced Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Tue, 16 May 2023 13:36:57 +0200 Subject: [PATCH 108/112] feat: more explicit variable naming --- packages/contracts/src/core/dao/DAO.sol | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 40eb849a9..3a4fc2c27 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -154,22 +154,22 @@ contract DAO is __PermissionManager_init(_initialOwner); } - /// @notice Initializes the DAO after an upgrade from a previous version. - /// @param _protocolVersion The protocol version number of the previous DAO implementation contract this upgrade is transitioning from. + /// @notice Initializes the DAO after an upgrade from a previous protocol version. + /// @param _previousProtocolVersion The semantic protocol version number of the previous DAO implementation contract this upgrade is transitioning from. /// @param _initData The initialization data to be passed to via `upgradeToAndCall` (see [ERC-1967](https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Upgrade)). function initializeFrom( - uint8[3] calldata _protocolVersion, + uint8[3] calldata _previousProtocolVersion, bytes calldata _initData ) external reinitializer(2) { _initData; // Silences the unused function parameter warning. // Check that the contract is not upgrading from a different major release. - if (_protocolVersion[0] != 1) { - revert ProtocolVersionUpgradeNotSupported(_protocolVersion); + if (_previousProtocolVersion[0] != 1) { + revert ProtocolVersionUpgradeNotSupported(_previousProtocolVersion); } // Check that the contract is not downgrading from a newer or the same minor release. - if (_protocolVersion[1] >= 3) { - revert ProtocolVersionUpgradeNotSupported(_protocolVersion); + if (_previousProtocolVersion[1] >= 3) { + revert ProtocolVersionUpgradeNotSupported(_previousProtocolVersion); } // Initialize `_reentrancyStatus` that was added in the current version (v1.3.0). From 7c3e22c975331af37294570d5705514c4b6ceb71 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Tue, 16 May 2023 18:06:23 +0200 Subject: [PATCH 109/112] fix: reworked initializeFrom logic --- packages/contracts/src/core/dao/DAO.sol | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index 3a4fc2c27..1bcbdc728 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -167,13 +167,11 @@ contract DAO is if (_previousProtocolVersion[0] != 1) { revert ProtocolVersionUpgradeNotSupported(_previousProtocolVersion); } - // Check that the contract is not downgrading from a newer or the same minor release. - if (_previousProtocolVersion[1] >= 3) { - revert ProtocolVersionUpgradeNotSupported(_previousProtocolVersion); - } - // Initialize `_reentrancyStatus` that was added in the current version (v1.3.0). - _reentrancyStatus = _NOT_ENTERED; + // Initialize `_reentrancyStatus` that was added in v1.3.0 + if (_previousProtocolVersion[1] <= 2) { + _reentrancyStatus = _NOT_ENTERED; + } } /// @inheritdoc PermissionManager From 8317c611ccc2e190a33a4b8c0bc8aec5fd2bfa18 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 17 May 2023 18:07:05 +0200 Subject: [PATCH 110/112] feat: improved changelog entry --- packages/contracts/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/CHANGELOG.md b/packages/contracts/CHANGELOG.md index f84360f85..1159b01e0 100644 --- a/packages/contracts/CHANGELOG.md +++ b/packages/contracts/CHANGELOG.md @@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Fixed ordering bug in the `createProposal` function used by the `TokenVoting` and `AddresslistVoting` implementations resulting emitting the unvalidated `_startDate` and `_endDate` input arguments (that both can be zero) in the `ProposalCreated` event instead of the validated ones. +- Fixed logic bug in the `TokenVoting` and `AddresslistVoting` implementations that caused the `createProposal` function to emit the unvalidated `_startDate` and `_endDate` input arguments (that both can be zero) in the `ProposalCreated` event instead of the validated ones. - Changed the `createProposal` functions in `Multisig` to allow creating proposals when the `_msgSender()` is listed in the current block. - Changed the `createProposal` functions in `AddresslistVoting` to allow creating proposals when the `_msgSender()` is listed in the current block. - Changed the `createProposal` functions in `TokenVoting` to allow creating proposals when the `_msgSender()` owns more tokens at least `minProposerVotingPower()` tokens in the current block. From ffc580051a2b36aa3b23dc16012c1685de1bc7b9 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Wed, 17 May 2023 18:12:09 +0200 Subject: [PATCH 111/112] feat: improved comment --- .../majority-voting/addresslist/addresslist-voting.ts | 2 ++ .../plugins/governance/majority-voting/token/token-voting.ts | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts index 24805b11f..01442f4d9 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/addresslist/addresslist-voting.ts @@ -482,6 +482,8 @@ describe('AddresslistVoting', function () { await voting.initialize(dao.address, votingSettings, [ signers[0].address, ]); + + // Create a proposal with zero as an input for `_startDate` and `_endDate` const startDate = 0; // now const endDate = 0; // startDate + minDuration diff --git a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts index e23e9e9d4..0031887e4 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting.ts @@ -789,6 +789,8 @@ describe('TokenVoting', function () { votingSettings, governanceErc20Mock.address ); + + // Create a proposal with zero as an input for `_startDate` and `_endDate` const startDate = 0; // now const endDate = 0; // startDate + minDuration @@ -809,7 +811,7 @@ describe('TokenVoting', function () { const expectedStartDate = currentTime; const expectedEndDate = expectedStartDate + votingSettings.minDuration; - // heck the state + // Check the state const proposal = await voting.getProposal(id); expect(proposal.parameters.startDate).to.eq(expectedStartDate); expect(proposal.parameters.endDate).to.eq(expectedEndDate); From 5dd7b557dd563447f9833d2dc2a1e73bcc755b98 Mon Sep 17 00:00:00 2001 From: Michael Heuer Date: Fri, 19 May 2023 11:27:49 +0200 Subject: [PATCH 112/112] chore: remove deploy scripts to be handled in a separate task --- .../update/to_v1.3.0/10_TokenVoting_Plugin.ts | 86 ------------------- .../11_TokenVoting_Plugin_conclude.ts | 11 --- 2 files changed, 97 deletions(-) delete mode 100644 packages/contracts/deploy/update/to_v1.3.0/10_TokenVoting_Plugin.ts delete mode 100644 packages/contracts/deploy/update/to_v1.3.0/11_TokenVoting_Plugin_conclude.ts diff --git a/packages/contracts/deploy/update/to_v1.3.0/10_TokenVoting_Plugin.ts b/packages/contracts/deploy/update/to_v1.3.0/10_TokenVoting_Plugin.ts deleted file mode 100644 index 9cef80f9f..000000000 --- a/packages/contracts/deploy/update/to_v1.3.0/10_TokenVoting_Plugin.ts +++ /dev/null @@ -1,86 +0,0 @@ -import {DeployFunction} from 'hardhat-deploy/types'; -import {HardhatRuntimeEnvironment} from 'hardhat/types'; -import {PluginRepo__factory} from '../../../typechain'; -import {getContractAddress, uploadToIPFS} from '../../helpers'; - -import tokenVotingReleaseMetadata from '../../../src/plugins/governance/majority-voting/token/release-metadata.json'; -import tokenVotingBuildMetadata from '../../../src/plugins/governance/majority-voting/token/build-metadata.json'; - -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - console.log('\nUpdate TokenVoting Plugin'); - const {deployments, ethers, network} = hre; - const {deploy} = deployments; - const [deployer] = await ethers.getSigners(); - - const deployResult = await deploy('TokenVotingSetup', { - from: deployer.address, - args: [], - log: true, - }); - - const tokenVotingReleaseCIDPath = await uploadToIPFS( - JSON.stringify(tokenVotingReleaseMetadata), - network.name - ); - const tokenVotingBuildCIDPath = await uploadToIPFS( - JSON.stringify(tokenVotingBuildMetadata), - network.name - ); - - const tokenVotingRepoAddress = await getContractAddress( - 'token-voting-repo', - hre - ); - const tokenVotingRepo = PluginRepo__factory.connect( - tokenVotingRepoAddress, - ethers.provider - ); - if ( - await tokenVotingRepo.callStatic.isGranted( - tokenVotingRepoAddress, - deployer.address, - await tokenVotingRepo.MAINTAINER_PERMISSION_ID(), - '0x00' - ) - ) { - console.log(`Deployer has permission to install new TokenVoting version`); - const tx = await tokenVotingRepo - .connect(deployer) - .createVersion( - 1, - deployResult.address, - ethers.utils.toUtf8Bytes(`ipfs://${tokenVotingBuildCIDPath}`), - ethers.utils.toUtf8Bytes(`ipfs://${tokenVotingReleaseCIDPath}`) - ); - console.log(`Creating new TokenVoting build version with ${tx.hash}`); - await tx.wait(); - return; - } - - const tx = await tokenVotingRepo - .connect(deployer) - .populateTransaction.createVersion( - 1, - deployResult.address, - ethers.utils.toUtf8Bytes(`ipfs://${tokenVotingBuildCIDPath}`), - ethers.utils.toUtf8Bytes(`ipfs://${tokenVotingReleaseCIDPath}`) - ); - - if (!tx.to || !tx.data) { - throw new Error( - `Failed to populate TokenVoting Repo createVersion transaction` - ); - } - - console.log( - `Deployer has no permission to create a new version. Adding managingDAO action` - ); - hre.managingDAOActions.push({ - to: tx.to, - data: tx.data, - value: 0, - description: `Creates a new build for release 1 in the TokenVotingRepo (${tokenVotingRepoAddress}) with TokenVotingSetup (${deployResult.address})`, - }); -}; -export default func; -func.tags = ['TokenVotingPlugin']; diff --git a/packages/contracts/deploy/update/to_v1.3.0/11_TokenVoting_Plugin_conclude.ts b/packages/contracts/deploy/update/to_v1.3.0/11_TokenVoting_Plugin_conclude.ts deleted file mode 100644 index eeae40165..000000000 --- a/packages/contracts/deploy/update/to_v1.3.0/11_TokenVoting_Plugin_conclude.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {DeployFunction} from 'hardhat-deploy/types'; -import {HardhatRuntimeEnvironment} from 'hardhat/types'; -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - console.log('\nConcluding TokenVoting Plugin Update'); - - hre.aragonToVerifyContracts.push( - await hre.deployments.get('TokenVotingSetup') - ); -}; -export default func; -func.tags = ['TokenVotingPlugin', 'Verify'];