From 8907452cd94c532c045dfd429954cbfe1cdd9f6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8r=E2=88=82=C2=A1?= Date: Wed, 18 Dec 2024 15:43:06 +0100 Subject: [PATCH] Formatting --- src/LockManager.sol | 33 +- src/LockToVotePlugin.sol | 190 +++------ src/interfaces/ILockManager.sol | 5 +- src/interfaces/ILockToVote.sol | 20 +- src/setup/LockToVotePluginSetup.sol | 618 ++++++++++++++-------------- test/LockManager.t.sol | 80 +--- test/LockToVote.t.sol | 5 +- test/constants.sol | 24 +- test/mocks/TestToken.sol | 16 +- test/mocks/osx/MockPSP.sol | 273 ++++-------- test/util/AragonTest.sol | 4 +- test/util/DaoBuilder.sol | 362 ++++++++-------- test/util/proxy.sol | 5 +- 13 files changed, 658 insertions(+), 977 deletions(-) diff --git a/src/LockManager.sol b/src/LockManager.sol index ad56663..945d1e4 100644 --- a/src/LockManager.sol +++ b/src/LockManager.sol @@ -42,16 +42,10 @@ contract LockManager is ILockManager, DaoAuthorizable { /// @notice Raised when attempting to unlock while active votes are cast in strict mode error LocksStillActive(); - constructor( - IDAO _dao, - LockManagerSettings memory _settings, - ILockToVote _plugin, - IERC20 _token - ) DaoAuthorizable(_dao) { - if ( - _settings.unlockMode != UnlockMode.STRICT && - _settings.unlockMode != UnlockMode.EARLY - ) { + constructor(IDAO _dao, LockManagerSettings memory _settings, ILockToVote _plugin, IERC20 _token) + DaoAuthorizable(_dao) + { + if (_settings.unlockMode != UnlockMode.STRICT && _settings.unlockMode != UnlockMode.EARLY) { revert InvalidUnlockMode(); } @@ -78,10 +72,7 @@ contract LockManager is ILockManager, DaoAuthorizable { } /// @inheritdoc ILockManager - function canVote( - uint256 _proposalId, - address _voter - ) external view returns (bool) { + function canVote(uint256 _proposalId, address _voter) external view returns (bool) { return plugin.canVote(_proposalId, _voter); } @@ -113,7 +104,7 @@ contract LockManager is ILockManager, DaoAuthorizable { revert InvalidPluginAddress(); } - for (uint _i; _i < knownProposalIds.length; ) { + for (uint256 _i; _i < knownProposalIds.length;) { if (knownProposalIds[_i] == _proposalId) { _removeKnownProposalId(_i); return; @@ -138,9 +129,7 @@ contract LockManager is ILockManager, DaoAuthorizable { uint256 _newVotingPower = lockedBalances[msg.sender]; if (_newVotingPower == 0) { revert NoBalance(); - } else if ( - _newVotingPower == plugin.usedVotingPower(_proposalId, msg.sender) - ) { + } else if (_newVotingPower == plugin.usedVotingPower(_proposalId, msg.sender)) { return; } @@ -149,7 +138,7 @@ contract LockManager is ILockManager, DaoAuthorizable { function _hasActiveLocks() internal returns (bool _activeLocks) { uint256 _proposalCount = knownProposalIds.length; - for (uint256 _i; _i < _proposalCount; ) { + for (uint256 _i; _i < _proposalCount;) { if (!plugin.isProposalOpen(knownProposalIds[_i])) { _removeKnownProposalId(_i); _proposalCount = knownProposalIds.length; @@ -175,7 +164,7 @@ contract LockManager is ILockManager, DaoAuthorizable { function _withdrawActiveVotingPower() internal { uint256 _proposalCount = knownProposalIds.length; - for (uint256 _i; _i < _proposalCount; ) { + for (uint256 _i; _i < _proposalCount;) { if (!plugin.isProposalOpen(knownProposalIds[_i])) { _removeKnownProposalId(_i); _proposalCount = knownProposalIds.length; @@ -200,8 +189,8 @@ contract LockManager is ILockManager, DaoAuthorizable { } /// @dev Cleaning up ended proposals, otherwise they would pile up and make unlocks more and more gas costly over time - function _removeKnownProposalId(uint _arrayIndex) internal { - uint _lastItemIdx = knownProposalIds.length - 1; + function _removeKnownProposalId(uint256 _arrayIndex) internal { + uint256 _lastItemIdx = knownProposalIds.length - 1; // Swap the current item with the last, if needed if (_arrayIndex < _lastItemIdx) { diff --git a/src/LockToVotePlugin.sol b/src/LockToVotePlugin.sol index d054c2d..1dc8634 100644 --- a/src/LockToVotePlugin.sol +++ b/src/LockToVotePlugin.sol @@ -10,7 +10,8 @@ import {IProposal} from "@aragon/osx-commons-contracts/src/plugin/extensions/pro import {Action} from "@aragon/osx-commons-contracts/src/executors/IExecutor.sol"; import {IPlugin} from "@aragon/osx-commons-contracts/src/plugin/IPlugin.sol"; import {PluginUUPSUpgradeable} from "@aragon/osx-commons-contracts/src/plugin/PluginUUPSUpgradeable.sol"; -import {MetadataExtensionUpgradeable} from "@aragon/osx-commons-contracts/src/utils/metadata/MetadataExtensionUpgradeable.sol"; +import {MetadataExtensionUpgradeable} from + "@aragon/osx-commons-contracts/src/utils/metadata/MetadataExtensionUpgradeable.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; import {SafeCastUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; @@ -32,20 +33,16 @@ contract LockToVotePlugin is mapping(uint256 => Proposal) proposals; /// @notice The ID of the permission required to call the `createProposal` functions. - bytes32 public constant CREATE_PROPOSAL_PERMISSION_ID = - keccak256("CREATE_PROPOSAL_PERMISSION"); + bytes32 public constant CREATE_PROPOSAL_PERMISSION_ID = keccak256("CREATE_PROPOSAL_PERMISSION"); /// @notice The ID of the permission required to call the `execute` function. - bytes32 public constant EXECUTE_PROPOSAL_PERMISSION_ID = - keccak256("EXECUTE_PROPOSAL_PERMISSION"); + bytes32 public constant EXECUTE_PROPOSAL_PERMISSION_ID = keccak256("EXECUTE_PROPOSAL_PERMISSION"); /// @notice The ID of the permission required to call the `execute` function. - bytes32 public constant LOCK_MANAGER_PERMISSION_ID = - keccak256("LOCK_MANAGER_PERMISSION"); + bytes32 public constant LOCK_MANAGER_PERMISSION_ID = keccak256("LOCK_MANAGER_PERMISSION"); /// @notice The ID of the permission required to call the `updateVotingSettings` function. - bytes32 public constant UPDATE_VOTING_SETTINGS_PERMISSION_ID = - keccak256("UPDATE_VOTING_SETTINGS_PERMISSION"); + bytes32 public constant UPDATE_VOTING_SETTINGS_PERMISSION_ID = keccak256("UPDATE_VOTING_SETTINGS_PERMISSION"); /// @notice Initializes the component. /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). @@ -70,31 +67,21 @@ contract LockToVotePlugin is lockManager = _lockManager; - emit MembershipContractAnnounced({ - definingContract: address(_lockManager.token()) - }); + emit MembershipContractAnnounced({definingContract: address(_lockManager.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 - ) + function supportsInterface(bytes4 _interfaceId) public view virtual - override( - MetadataExtensionUpgradeable, - PluginUUPSUpgradeable, - ProposalUpgradeable - ) + override(MetadataExtensionUpgradeable, PluginUUPSUpgradeable, ProposalUpgradeable) returns (bool) { - return - _interfaceId == type(IMembership).interfaceId || - _interfaceId == type(ILockToVote).interfaceId || - super.supportsInterface(_interfaceId); + return _interfaceId == type(IMembership).interfaceId || _interfaceId == type(ILockToVote).interfaceId + || super.supportsInterface(_interfaceId); } /// @inheritdoc IProposal @@ -105,11 +92,7 @@ contract LockToVotePlugin is uint64 _startDate, uint64 _endDate, bytes memory _data - ) - external - auth(CREATE_PROPOSAL_PERMISSION_ID) - returns (uint256 proposalId) - { + ) external auth(CREATE_PROPOSAL_PERMISSION_ID) returns (uint256 proposalId) { uint256 _allowFailureMap; if (_data.length != 0) { @@ -122,9 +105,7 @@ contract LockToVotePlugin is (_startDate, _endDate) = _validateProposalDates(_startDate, _endDate); - proposalId = _createProposalId( - keccak256(abi.encode(_actions, _metadata)) - ); + proposalId = _createProposalId(keccak256(abi.encode(_actions, _metadata))); // Store proposal related information Proposal storage proposal_ = proposals[proposalId]; @@ -144,31 +125,18 @@ contract LockToVotePlugin is proposal_.allowFailureMap = _allowFailureMap; } - for (uint256 i; i < _actions.length; ) { + for (uint256 i; i < _actions.length;) { proposal_.actions.push(_actions[i]); unchecked { ++i; } } - emit ProposalCreated( - proposalId, - _msgSender(), - _startDate, - _endDate, - _metadata, - _actions, - _allowFailureMap - ); + emit ProposalCreated(proposalId, _msgSender(), _startDate, _endDate, _metadata, _actions, _allowFailureMap); } /// @inheritdoc IProposal - function customProposalParamsABI() - external - pure - override - returns (string memory) - { + function customProposalParamsABI() external pure override returns (string memory) { return "(uint256 allowFailureMap)"; } @@ -181,9 +149,7 @@ contract LockToVotePlugin is /// @return actions The actions to be executed to the `target` contract address. /// @return allowFailureMap The bit map representations of which actions are allowed to revert so tx still succeeds. /// @return targetConfig Execution configuration, applied to the proposal when it was created. Added in build 3. - function getProposal( - uint256 _proposalId - ) + function getProposal(uint256 _proposalId) public view virtual @@ -209,9 +175,7 @@ contract LockToVotePlugin is } /// @inheritdoc ILockToVote - function isProposalOpen( - uint256 _proposalId - ) external view virtual returns (bool) { + function isProposalOpen(uint256 _proposalId) external view virtual returns (bool) { Proposal storage proposal_ = proposals[_proposalId]; return _isProposalOpen(proposal_); } @@ -224,21 +188,17 @@ contract LockToVotePlugin is } /// @inheritdoc ILockToVote - function canVote( - uint256 _proposalId, - address _voter - ) external view returns (bool) { + function canVote(uint256 _proposalId, address _voter) external view returns (bool) { Proposal storage proposal_ = proposals[_proposalId]; return _canVote(proposal_, _voter); } /// @inheritdoc ILockToVote - function vote( - uint256 _proposalId, - address _voter, - uint _newVotingPower - ) external auth(LOCK_MANAGER_PERMISSION_ID) { + function vote(uint256 _proposalId, address _voter, uint256 _newVotingPower) + external + auth(LOCK_MANAGER_PERMISSION_ID) + { Proposal storage proposal_ = proposals[_proposalId]; if (!_canVote(proposal_, _voter)) { @@ -257,10 +217,7 @@ contract LockToVotePlugin is } /// @inheritdoc ILockToVote - function clearVote( - uint256 _proposalId, - address _voter - ) external auth(LOCK_MANAGER_PERMISSION_ID) { + function clearVote(uint256 _proposalId, address _voter) external auth(LOCK_MANAGER_PERMISSION_ID) { Proposal storage proposal_ = proposals[_proposalId]; if (proposal_.approvals[_voter] == 0) return; @@ -275,10 +232,7 @@ contract LockToVotePlugin is } /// @inheritdoc ILockToVote - function usedVotingPower( - uint256 proposalId, - address voter - ) public view returns (uint256) { + function usedVotingPower(uint256 proposalId, address voter) public view returns (uint256) { return proposals[proposalId].approvals[voter]; } @@ -295,9 +249,7 @@ contract LockToVotePlugin is } /// @inheritdoc IProposal - function execute( - uint256 _proposalId - ) external auth(EXECUTE_PROPOSAL_PERMISSION_ID) { + function execute(uint256 _proposalId) external auth(EXECUTE_PROPOSAL_PERMISSION_ID) { Proposal storage proposal_ = proposals[_proposalId]; if (!_canExecute(proposal_)) { @@ -313,46 +265,36 @@ contract LockToVotePlugin is } /// @inheritdoc ILockToVote - function updatePluginSettings( - LockToVoteSettings calldata _newSettings - ) external auth(UPDATE_VOTING_SETTINGS_PERMISSION_ID) { + function updatePluginSettings(LockToVoteSettings calldata _newSettings) + external + auth(UPDATE_VOTING_SETTINGS_PERMISSION_ID) + { _updatePluginSettings(_newSettings); } // Internal helpers - function _isProposalOpen( - Proposal storage proposal_ - ) internal view returns (bool) { + function _isProposalOpen(Proposal storage proposal_) internal view returns (bool) { uint64 currentTime = block.timestamp.toUint64(); - return - proposal_.parameters.startDate <= currentTime && - currentTime < proposal_.parameters.endDate && - !proposal_.executed; + return proposal_.parameters.startDate <= currentTime && currentTime < proposal_.parameters.endDate + && !proposal_.executed; } - function _canVote( - Proposal storage proposal_, - address _voter - ) internal view returns (bool) { + function _canVote(Proposal storage proposal_, address _voter) internal view returns (bool) { // The proposal vote hasn't started or has already ended. if (!_isProposalOpen(proposal_)) { return false; } // More balance could be added - else if ( - lockManager.lockedBalances(_voter) <= proposal_.approvals[_voter] - ) { + else if (lockManager.lockedBalances(_voter) <= proposal_.approvals[_voter]) { return false; } return true; } - function _canExecute( - Proposal storage proposal_ - ) internal view returns (bool) { + function _canExecute(Proposal storage proposal_) internal view returns (bool) { if (proposal_.executed) { return false; } else if (proposal_.parameters.endDate < block.timestamp) { @@ -364,13 +306,9 @@ contract LockToVotePlugin is return true; } - function _hasSucceeded( - Proposal storage proposal_ - ) internal view returns (bool) { - uint256 _minApprovalTally = _applyRatioCeiled( - lockManager.token().totalSupply(), - proposal_.parameters.minApprovalRatio - ); + function _hasSucceeded(Proposal storage proposal_) internal view returns (bool) { + uint256 _minApprovalTally = + _applyRatioCeiled(lockManager.token().totalSupply(), proposal_.parameters.minApprovalRatio); return proposal_.approvalTally >= _minApprovalTally; } @@ -380,10 +318,12 @@ contract LockToVotePlugin is /// @param _end The end date of the proposal. If 0, `_start + minDuration` is used. /// @return startDate The validated start date of the proposal. /// @return endDate The validated end date of the proposal. - function _validateProposalDates( - uint64 _start, - uint64 _end - ) internal view virtual returns (uint64 startDate, uint64 endDate) { + function _validateProposalDates(uint64 _start, uint64 _end) + internal + view + virtual + returns (uint64 startDate, uint64 endDate) + { uint64 currentTimestamp = block.timestamp.toUint64(); if (_start == 0) { @@ -392,10 +332,7 @@ contract LockToVotePlugin is startDate = _start; if (startDate < currentTimestamp) { - revert DateOutOfBounds({ - limit: currentTimestamp, - actual: startDate - }); + revert DateOutOfBounds({limit: currentTimestamp, actual: startDate}); } } @@ -410,47 +347,26 @@ contract LockToVotePlugin is endDate = _end; if (endDate < earliestEndDate) { - revert DateOutOfBounds({ - limit: earliestEndDate, - actual: endDate - }); + revert DateOutOfBounds({limit: earliestEndDate, actual: endDate}); } } } - function _checkEarlyExecution( - uint256 _proposalId, - Proposal storage proposal_, - address _voter - ) internal { + function _checkEarlyExecution(uint256 _proposalId, Proposal storage proposal_, address _voter) internal { if (!_canExecute(proposal_)) { return; - } else if ( - !dao().hasPermission( - address(this), - _voter, - EXECUTE_PROPOSAL_PERMISSION_ID, - _msgData() - ) - ) { + } else if (!dao().hasPermission(address(this), _voter, EXECUTE_PROPOSAL_PERMISSION_ID, _msgData())) { return; } _execute(_proposalId, proposal_); } - function _execute( - uint256 _proposalId, - Proposal storage proposal_ - ) internal { + function _execute(uint256 _proposalId, Proposal storage proposal_) internal { proposal_.executed = true; // IProposal's target execution - _execute( - bytes32(_proposalId), - proposal_.actions, - proposal_.allowFailureMap - ); + _execute(bytes32(_proposalId), proposal_.actions, proposal_.allowFailureMap); emit Executed(_proposalId); @@ -458,9 +374,7 @@ contract LockToVotePlugin is lockManager.proposalEnded(_proposalId); } - function _updatePluginSettings( - LockToVoteSettings memory _newSettings - ) internal { + function _updatePluginSettings(LockToVoteSettings memory _newSettings) internal { settings.minApprovalRatio = _newSettings.minApprovalRatio; settings.minProposalDuration = _newSettings.minProposalDuration; } diff --git a/src/interfaces/ILockManager.sol b/src/interfaces/ILockManager.sol index 33be30a..f9bd2dd 100644 --- a/src/interfaces/ILockManager.sol +++ b/src/interfaces/ILockManager.sol @@ -52,10 +52,7 @@ interface ILockManager { /// @param voter The account address to be checked. /// @return Returns true if the account is allowed to vote. /// @dev The function assumes that the queried proposal exists. - function canVote( - uint256 proposalId, - address voter - ) external view returns (bool); + function canVote(uint256 proposalId, address voter) external view returns (bool); /// @notice If the mode allows it, releases all active locks placed on active proposals and transfers msg.sender's locked balance back. Depending on the current mode, it withdraws only if no locks are being used in active proposals. function unlock() external; diff --git a/src/interfaces/ILockToVote.sol b/src/interfaces/ILockToVote.sol index e949aec..1d2cf38 100644 --- a/src/interfaces/ILockToVote.sol +++ b/src/interfaces/ILockToVote.sol @@ -64,21 +64,14 @@ interface ILockToVote { function isProposalOpen(uint256 _proposalId) external view returns (bool); /// @notice Returns wether the given address can vote or increase the amount of tokens assigned to a proposal - function canVote( - uint256 proposalId, - address voter - ) external view returns (bool); + function canVote(uint256 proposalId, address voter) external view returns (bool); /// @notice Registers an approval vote for the given proposal. /// @param proposalId The ID of the proposal to vote on. /// @param voter The address of the account whose vote will be registered /// @param newVotingPower The new balance that should be allocated to the voter. It can only be bigger. /// @dev newVotingPower updates any prior voting power, it does not add to the existing amount. - function vote( - uint256 proposalId, - address voter, - uint newVotingPower - ) external; + function vote(uint256 proposalId, address voter, uint256 newVotingPower) external; /// @notice Reverts the existing voter's vote, if any. /// @param proposalId The ID of the proposal. @@ -89,16 +82,11 @@ interface ILockToVote { /// @param proposalId The ID of the proposal. /// @param voter The account address to be checked. /// @return The amount of balance that has been allocated to the proposal by the given account. - function usedVotingPower( - uint256 proposalId, - address voter - ) external view returns (uint256); + function usedVotingPower(uint256 proposalId, address voter) external view returns (uint256); /// @notice Updates the voting settings, which will be applied to the next proposal being created. /// @param newSettings The new settings, including the minimum approval ratio and the minimum proposal duration. - function updatePluginSettings( - LockToVoteSettings calldata newSettings - ) external; + function updatePluginSettings(LockToVoteSettings calldata newSettings) external; error NoVotingPower(); error ProposalAlreadyExists(uint256 proposalId); diff --git a/src/setup/LockToVotePluginSetup.sol b/src/setup/LockToVotePluginSetup.sol index c04bcf1..960ee79 100644 --- a/src/setup/LockToVotePluginSetup.sol +++ b/src/setup/LockToVotePluginSetup.sol @@ -20,313 +20,313 @@ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /// @notice The setup contract of the `LockToVotePlugin` contract. /// @custom:security-contact sirt@aragon.org contract LockToVotePluginSetup { - // is PluginSetup { - // using Address for address; - // using Clones for address; - // using ERC165Checker for address; - // /// @notice The address of the `LockToVotePlugin` base contract. - // LockToVotePlugin private immutable lockToVotePluginBase; - // /// @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 symbol The token symbol. This parameter is only relevant if the token address is `address(0)`. - // struct TokenSettings { - // address addr; - // string name; - // string symbol; - // } - // struct InstallationParameters { - // LockToVotePlugin.PluginSettings settings; - // TokenSettings tokenSettings; - // // only used for GovernanceERC20 (when token is not passed) - // GovernanceERC20.MintSettings mintSettings; - // uint64 stdProposalMinDuration; - // address stdProposer; - // address emergencyProposer; - // } - // /// @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 deploying the plugin implementation contract and receiving the governance token base contracts to clone from. - // /// @param _governanceERC20Base The base `GovernanceERC20` contract to create clones from. - // /// @param _governanceWrappedERC20Base The base `GovernanceWrappedERC20` contract to create clones from. - // constructor( - // GovernanceERC20 _governanceERC20Base, - // GovernanceWrappedERC20 _governanceWrappedERC20Base - // ) { - // lockToVotePluginBase = new LockToVotePlugin(); - // governanceERC20Base = address(_governanceERC20Base); - // governanceWrappedERC20Base = address(_governanceWrappedERC20Base); - // } - // /// @inheritdoc IPluginSetup - // function prepareInstallation( - // address _dao, - // bytes calldata _installParameters - // ) - // external - // returns (address plugin, PreparedSetupData memory preparedSetupData) - // { - // // Decode `_installParameters` to extract the params needed for deploying and initializing `LockToVotePlugin` contract, - // // and the required helpers - // InstallationParameters - // memory installationParams = decodeInstallationParams( - // _installParameters - // ); - // address token = installationParams.tokenSettings.addr; - // // Prepare helpers. - // address[] memory helpers = new address[](1); - // if (token != address(0x0)) { - // if (!token.isContract()) { - // revert TokenNotContract(token); - // } else if (!_supportsErc20(token)) { - // revert TokenNotERC20(token); - // } - // if ( - // !_supportsIVotes(token) && - // !_supportsIGovernanceWrappedERC20(token) - // ) { - // // Wrap the token - // 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(installationParams.tokenSettings.addr), - // installationParams.tokenSettings.name, - // installationParams.tokenSettings.symbol - // ); - // } - // } else { - // // Create a brand new token - // token = governanceERC20Base.clone(); - // GovernanceERC20(token).initialize( - // IDAO(_dao), - // installationParams.tokenSettings.name, - // installationParams.tokenSettings.symbol, - // installationParams.mintSettings - // ); - // } - // helpers[0] = token; - // // Prepare and deploy plugin proxy. - // plugin = createERC1967Proxy( - // address(lockToVotePluginBase), - // abi.encodeCall( - // LockToVotePlugin.initialize, - // ( - // IDAO(_dao), - // installationParams.settings, - // IVotesUpgradeable(token) - // ) - // ) - // ); - // // Prepare permissions - // PermissionLib.MultiTargetPermission[] - // memory permissions = new PermissionLib.MultiTargetPermission[]( - // installationParams.tokenSettings.addr != address(0) ? 5 : 6 - // ); - // // Request the permissions to be granted - // // The DAO can update the plugin settings - // permissions[0] = PermissionLib.MultiTargetPermission({ - // operation: PermissionLib.Operation.Grant, - // where: plugin, - // who: _dao, - // condition: PermissionLib.NO_CONDITION, - // permissionId: lockToVotePluginBase - // .UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID() - // }); - // // The DAO can upgrade the plugin implementation - // permissions[1] = PermissionLib.MultiTargetPermission({ - // operation: PermissionLib.Operation.Grant, - // where: plugin, - // who: _dao, - // condition: PermissionLib.NO_CONDITION, - // permissionId: lockToVotePluginBase.UPGRADE_PLUGIN_PERMISSION_ID() - // }); - // // The plugin can make the DAO execute actions - // permissions[2] = PermissionLib.MultiTargetPermission({ - // operation: PermissionLib.Operation.Grant, - // where: _dao, - // who: plugin, - // condition: PermissionLib.NO_CONDITION, - // permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() - // }); - // { - // // Deploy the Std proposal condition - // StandardProposalCondition stdProposalCondition = new StandardProposalCondition( - // address(_dao), - // installationParams.stdProposalMinDuration - // ); - // // Proposer plugins can create proposals - // permissions[3] = PermissionLib.MultiTargetPermission({ - // operation: PermissionLib.Operation.Grant, - // where: plugin, - // who: installationParams.stdProposer, - // condition: address(stdProposalCondition), - // permissionId: lockToVotePluginBase.PROPOSER_PERMISSION_ID() - // }); - // } - // permissions[4] = PermissionLib.MultiTargetPermission({ - // operation: PermissionLib.Operation.Grant, - // where: plugin, - // who: installationParams.emergencyProposer, - // condition: PermissionLib.NO_CONDITION, - // permissionId: lockToVotePluginBase.PROPOSER_PERMISSION_ID() - // }); - // if (installationParams.tokenSettings.addr == address(0x0)) { - // // The DAO can mint ERC20 tokens - // permissions[5] = PermissionLib.MultiTargetPermission({ - // operation: PermissionLib.Operation.Grant, - // where: token, - // who: _dao, - // condition: PermissionLib.NO_CONDITION, - // permissionId: GovernanceERC20(token).MINT_PERMISSION_ID() - // }); - // } - // 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 isGovernanceERC20 = _supportsErc20(token) && - // _supportsIVotes(token) && - // !_supportsIGovernanceWrappedERC20(token); - // permissions = new PermissionLib.MultiTargetPermission[]( - // isGovernanceERC20 ? 4 : 3 - // ); - // // Set permissions to be Revoked. - // permissions[0] = PermissionLib.MultiTargetPermission({ - // operation: PermissionLib.Operation.Revoke, - // where: _payload.plugin, - // who: _dao, - // condition: PermissionLib.NO_CONDITION, - // permissionId: lockToVotePluginBase - // .UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID() - // }); - // permissions[1] = PermissionLib.MultiTargetPermission({ - // operation: PermissionLib.Operation.Revoke, - // where: _payload.plugin, - // who: _dao, - // condition: PermissionLib.NO_CONDITION, - // permissionId: lockToVotePluginBase.UPGRADE_PLUGIN_PERMISSION_ID() - // }); - // permissions[2] = PermissionLib.MultiTargetPermission({ - // operation: PermissionLib.Operation.Revoke, - // where: _dao, - // who: _payload.plugin, - // condition: PermissionLib.NO_CONDITION, - // permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() - // }); - // // Note: It no longer matters if proposers can still create proposals - // // 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({ - // operation: PermissionLib.Operation.Revoke, - // where: token, - // who: _dao, - // condition: PermissionLib.NO_CONDITION, - // permissionId: GovernanceERC20(token).MINT_PERMISSION_ID() - // }); - // } - // } - // /// @inheritdoc IPluginSetup - // function implementation() external view virtual override returns (address) { - // return address(lockToVotePluginBase); - // } - // /// @notice Encodes the given installation parameters into a byte array - // function encodeInstallationParams( - // InstallationParameters memory installationParams - // ) external pure returns (bytes memory) { - // return abi.encode(installationParams); - // } - // /// @notice Decodes the given byte array into the original installation parameters - // function decodeInstallationParams( - // bytes memory _data - // ) public pure returns (InstallationParameters memory installationParams) { - // installationParams = abi.decode(_data, (InstallationParameters)); - // } - // /// @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 _supportsErc20(address token) private view returns (bool) { - // (bool success, bytes memory data) = token.staticcall( - // abi.encodeCall(IERC20Upgradeable.balanceOf, (address(this))) - // ); - // if (!success || data.length != 0x20) return false; - // (success, data) = token.staticcall( - // abi.encodeCall(IERC20Upgradeable.totalSupply, ()) - // ); - // if (!success || data.length != 0x20) return false; - // (success, data) = token.staticcall( - // abi.encodeCall( - // IERC20Upgradeable.allowance, - // (address(this), address(this)) - // ) - // ); - // if (!success || data.length != 0x20) return false; - // return true; - // } - // /// @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 _supportsIVotes(address token) private view returns (bool) { - // (bool success, bytes memory data) = token.staticcall( - // abi.encodeCall(IVotesUpgradeable.getVotes, (address(this))) - // ); - // if (!success || data.length != 0x20) return false; - // (success, data) = token.staticcall( - // abi.encodeCall(IVotesUpgradeable.getPastVotes, (address(this), 0)) - // ); - // if (!success || data.length != 0x20) return false; - // (success, data) = token.staticcall( - // abi.encodeCall(IVotesUpgradeable.getPastTotalSupply, (0)) - // ); - // if (!success || data.length != 0x20) return false; - // (success, data) = token.staticcall( - // abi.encodeCall(IVotesUpgradeable.delegates, (address(this))) - // ); - // if (!success || data.length != 0x20) return false; - // return true; - // } - // /// @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 _supportsIGovernanceWrappedERC20( - // address token - // ) private view returns (bool) { - // (bool success, bytes memory data) = token.staticcall( - // abi.encodeCall(IERC165.supportsInterface, (bytes4(0))) - // ); - // if (!success || data.length != 0x20) return false; - // return - // IERC165(token).supportsInterface( - // type(IGovernanceWrappedERC20).interfaceId - // ); - // } +// is PluginSetup { +// using Address for address; +// using Clones for address; +// using ERC165Checker for address; +// /// @notice The address of the `LockToVotePlugin` base contract. +// LockToVotePlugin private immutable lockToVotePluginBase; +// /// @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 symbol The token symbol. This parameter is only relevant if the token address is `address(0)`. +// struct TokenSettings { +// address addr; +// string name; +// string symbol; +// } +// struct InstallationParameters { +// LockToVotePlugin.PluginSettings settings; +// TokenSettings tokenSettings; +// // only used for GovernanceERC20 (when token is not passed) +// GovernanceERC20.MintSettings mintSettings; +// uint64 stdProposalMinDuration; +// address stdProposer; +// address emergencyProposer; +// } +// /// @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 deploying the plugin implementation contract and receiving the governance token base contracts to clone from. +// /// @param _governanceERC20Base The base `GovernanceERC20` contract to create clones from. +// /// @param _governanceWrappedERC20Base The base `GovernanceWrappedERC20` contract to create clones from. +// constructor( +// GovernanceERC20 _governanceERC20Base, +// GovernanceWrappedERC20 _governanceWrappedERC20Base +// ) { +// lockToVotePluginBase = new LockToVotePlugin(); +// governanceERC20Base = address(_governanceERC20Base); +// governanceWrappedERC20Base = address(_governanceWrappedERC20Base); +// } +// /// @inheritdoc IPluginSetup +// function prepareInstallation( +// address _dao, +// bytes calldata _installParameters +// ) +// external +// returns (address plugin, PreparedSetupData memory preparedSetupData) +// { +// // Decode `_installParameters` to extract the params needed for deploying and initializing `LockToVotePlugin` contract, +// // and the required helpers +// InstallationParameters +// memory installationParams = decodeInstallationParams( +// _installParameters +// ); +// address token = installationParams.tokenSettings.addr; +// // Prepare helpers. +// address[] memory helpers = new address[](1); +// if (token != address(0x0)) { +// if (!token.isContract()) { +// revert TokenNotContract(token); +// } else if (!_supportsErc20(token)) { +// revert TokenNotERC20(token); +// } +// if ( +// !_supportsIVotes(token) && +// !_supportsIGovernanceWrappedERC20(token) +// ) { +// // Wrap the token +// 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(installationParams.tokenSettings.addr), +// installationParams.tokenSettings.name, +// installationParams.tokenSettings.symbol +// ); +// } +// } else { +// // Create a brand new token +// token = governanceERC20Base.clone(); +// GovernanceERC20(token).initialize( +// IDAO(_dao), +// installationParams.tokenSettings.name, +// installationParams.tokenSettings.symbol, +// installationParams.mintSettings +// ); +// } +// helpers[0] = token; +// // Prepare and deploy plugin proxy. +// plugin = createERC1967Proxy( +// address(lockToVotePluginBase), +// abi.encodeCall( +// LockToVotePlugin.initialize, +// ( +// IDAO(_dao), +// installationParams.settings, +// IVotesUpgradeable(token) +// ) +// ) +// ); +// // Prepare permissions +// PermissionLib.MultiTargetPermission[] +// memory permissions = new PermissionLib.MultiTargetPermission[]( +// installationParams.tokenSettings.addr != address(0) ? 5 : 6 +// ); +// // Request the permissions to be granted +// // The DAO can update the plugin settings +// permissions[0] = PermissionLib.MultiTargetPermission({ +// operation: PermissionLib.Operation.Grant, +// where: plugin, +// who: _dao, +// condition: PermissionLib.NO_CONDITION, +// permissionId: lockToVotePluginBase +// .UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID() +// }); +// // The DAO can upgrade the plugin implementation +// permissions[1] = PermissionLib.MultiTargetPermission({ +// operation: PermissionLib.Operation.Grant, +// where: plugin, +// who: _dao, +// condition: PermissionLib.NO_CONDITION, +// permissionId: lockToVotePluginBase.UPGRADE_PLUGIN_PERMISSION_ID() +// }); +// // The plugin can make the DAO execute actions +// permissions[2] = PermissionLib.MultiTargetPermission({ +// operation: PermissionLib.Operation.Grant, +// where: _dao, +// who: plugin, +// condition: PermissionLib.NO_CONDITION, +// permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() +// }); +// { +// // Deploy the Std proposal condition +// StandardProposalCondition stdProposalCondition = new StandardProposalCondition( +// address(_dao), +// installationParams.stdProposalMinDuration +// ); +// // Proposer plugins can create proposals +// permissions[3] = PermissionLib.MultiTargetPermission({ +// operation: PermissionLib.Operation.Grant, +// where: plugin, +// who: installationParams.stdProposer, +// condition: address(stdProposalCondition), +// permissionId: lockToVotePluginBase.PROPOSER_PERMISSION_ID() +// }); +// } +// permissions[4] = PermissionLib.MultiTargetPermission({ +// operation: PermissionLib.Operation.Grant, +// where: plugin, +// who: installationParams.emergencyProposer, +// condition: PermissionLib.NO_CONDITION, +// permissionId: lockToVotePluginBase.PROPOSER_PERMISSION_ID() +// }); +// if (installationParams.tokenSettings.addr == address(0x0)) { +// // The DAO can mint ERC20 tokens +// permissions[5] = PermissionLib.MultiTargetPermission({ +// operation: PermissionLib.Operation.Grant, +// where: token, +// who: _dao, +// condition: PermissionLib.NO_CONDITION, +// permissionId: GovernanceERC20(token).MINT_PERMISSION_ID() +// }); +// } +// 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 isGovernanceERC20 = _supportsErc20(token) && +// _supportsIVotes(token) && +// !_supportsIGovernanceWrappedERC20(token); +// permissions = new PermissionLib.MultiTargetPermission[]( +// isGovernanceERC20 ? 4 : 3 +// ); +// // Set permissions to be Revoked. +// permissions[0] = PermissionLib.MultiTargetPermission({ +// operation: PermissionLib.Operation.Revoke, +// where: _payload.plugin, +// who: _dao, +// condition: PermissionLib.NO_CONDITION, +// permissionId: lockToVotePluginBase +// .UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID() +// }); +// permissions[1] = PermissionLib.MultiTargetPermission({ +// operation: PermissionLib.Operation.Revoke, +// where: _payload.plugin, +// who: _dao, +// condition: PermissionLib.NO_CONDITION, +// permissionId: lockToVotePluginBase.UPGRADE_PLUGIN_PERMISSION_ID() +// }); +// permissions[2] = PermissionLib.MultiTargetPermission({ +// operation: PermissionLib.Operation.Revoke, +// where: _dao, +// who: _payload.plugin, +// condition: PermissionLib.NO_CONDITION, +// permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() +// }); +// // Note: It no longer matters if proposers can still create proposals +// // 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({ +// operation: PermissionLib.Operation.Revoke, +// where: token, +// who: _dao, +// condition: PermissionLib.NO_CONDITION, +// permissionId: GovernanceERC20(token).MINT_PERMISSION_ID() +// }); +// } +// } +// /// @inheritdoc IPluginSetup +// function implementation() external view virtual override returns (address) { +// return address(lockToVotePluginBase); +// } +// /// @notice Encodes the given installation parameters into a byte array +// function encodeInstallationParams( +// InstallationParameters memory installationParams +// ) external pure returns (bytes memory) { +// return abi.encode(installationParams); +// } +// /// @notice Decodes the given byte array into the original installation parameters +// function decodeInstallationParams( +// bytes memory _data +// ) public pure returns (InstallationParameters memory installationParams) { +// installationParams = abi.decode(_data, (InstallationParameters)); +// } +// /// @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 _supportsErc20(address token) private view returns (bool) { +// (bool success, bytes memory data) = token.staticcall( +// abi.encodeCall(IERC20Upgradeable.balanceOf, (address(this))) +// ); +// if (!success || data.length != 0x20) return false; +// (success, data) = token.staticcall( +// abi.encodeCall(IERC20Upgradeable.totalSupply, ()) +// ); +// if (!success || data.length != 0x20) return false; +// (success, data) = token.staticcall( +// abi.encodeCall( +// IERC20Upgradeable.allowance, +// (address(this), address(this)) +// ) +// ); +// if (!success || data.length != 0x20) return false; +// return true; +// } +// /// @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 _supportsIVotes(address token) private view returns (bool) { +// (bool success, bytes memory data) = token.staticcall( +// abi.encodeCall(IVotesUpgradeable.getVotes, (address(this))) +// ); +// if (!success || data.length != 0x20) return false; +// (success, data) = token.staticcall( +// abi.encodeCall(IVotesUpgradeable.getPastVotes, (address(this), 0)) +// ); +// if (!success || data.length != 0x20) return false; +// (success, data) = token.staticcall( +// abi.encodeCall(IVotesUpgradeable.getPastTotalSupply, (0)) +// ); +// if (!success || data.length != 0x20) return false; +// (success, data) = token.staticcall( +// abi.encodeCall(IVotesUpgradeable.delegates, (address(this))) +// ); +// if (!success || data.length != 0x20) return false; +// return true; +// } +// /// @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 _supportsIGovernanceWrappedERC20( +// address token +// ) private view returns (bool) { +// (bool success, bytes memory data) = token.staticcall( +// abi.encodeCall(IERC165.supportsInterface, (bytes4(0))) +// ); +// if (!success || data.length != 0x20) return false; +// return +// IERC165(token).supportsInterface( +// type(IGovernanceWrappedERC20).interfaceId +// ); +// } } diff --git a/test/LockManager.t.sol b/test/LockManager.t.sol index 527b99f..9ee3993 100644 --- a/test/LockManager.t.sol +++ b/test/LockManager.t.sol @@ -12,18 +12,12 @@ contract LockManagerTest is AragonTest { _; } - function test_RevertWhen_UpdateSettingsWithoutThePermission() - external - whenCallingUpdateSettings - { + function test_RevertWhen_UpdateSettingsWithoutThePermission() external whenCallingUpdateSettings { // It should revert vm.skip(true); } - function test_WhenUpdateSettingsWithThePermission() - external - whenCallingUpdateSettings - { + function test_WhenUpdateSettingsWithThePermission() external whenCallingUpdateSettings { // It should update the mode vm.skip(true); } @@ -60,29 +54,17 @@ contract LockManagerTest is AragonTest { _; } - function test_RevertWhen_NoTokenBalance() - external - whenLockingAndOrVoting - givenValidLockToVotePlugin - { + function test_RevertWhen_NoTokenBalance() external whenLockingAndOrVoting givenValidLockToVotePlugin { // It Should revert vm.skip(true); } - function test_RevertWhen_NoTokenAllowance() - external - whenLockingAndOrVoting - givenValidLockToVotePlugin - { + function test_RevertWhen_NoTokenAllowance() external whenLockingAndOrVoting givenValidLockToVotePlugin { // It Should revert vm.skip(true); } - function test_WhenInvalidOrInactiveProposal() - external - whenLockingAndOrVoting - givenValidLockToVotePlugin - { + function test_WhenInvalidOrInactiveProposal() external whenLockingAndOrVoting givenValidLockToVotePlugin { // It Locking and voting should revert // It Voting should revert vm.skip(true); @@ -92,44 +74,24 @@ contract LockManagerTest is AragonTest { _; } - function test_WhenAlreadyVoted() - external - whenLockingAndOrVoting - givenValidLockToVotePlugin - whenValidProposal - { + function test_WhenAlreadyVoted() external whenLockingAndOrVoting givenValidLockToVotePlugin whenValidProposal { // It Should update the voting balance and the proposal tally // It Should increase the voting power by the full allowance vm.skip(true); } - function test_WhenNotVotedYet() - external - whenLockingAndOrVoting - givenValidLockToVotePlugin - whenValidProposal - { + function test_WhenNotVotedYet() external whenLockingAndOrVoting givenValidLockToVotePlugin whenValidProposal { // It Should allow any token holder to vote // It Should use the full allowance to vote vm.skip(true); } - function test_WhenCallingGetTokens() - external - whenLockingAndOrVoting - givenValidLockToVotePlugin - whenValidProposal - { + function test_WhenCallingGetTokens() external whenLockingAndOrVoting givenValidLockToVotePlugin whenValidProposal { // It Should return the token addresses where votes have been cast vm.skip(true); } - function test_GivenCallingGetLocks() - external - whenLockingAndOrVoting - givenValidLockToVotePlugin - whenValidProposal - { + function test_GivenCallingGetLocks() external whenLockingAndOrVoting givenValidLockToVotePlugin whenValidProposal { // It Should return the active proposals with 1+ locks vm.skip(true); } @@ -142,11 +104,7 @@ contract LockManagerTest is AragonTest { _; } - function test_WhenTryingToUnlock1Strict() - external - givenStrictModeIsSet - givenDidntLockAnythingStrict - { + function test_WhenTryingToUnlock1Strict() external givenStrictModeIsSet givenDidntLockAnythingStrict { // It Should do nothing vm.skip(true); } @@ -155,11 +113,7 @@ contract LockManagerTest is AragonTest { _; } - function test_WhenTryingToUnlock2Strict() - external - givenStrictModeIsSet - givenLockedButDidntVoteAnywhereStrict - { + function test_WhenTryingToUnlock2Strict() external givenStrictModeIsSet givenLockedButDidntVoteAnywhereStrict { // It Should unlock and refund the full amount right away vm.skip(true); } @@ -198,11 +152,7 @@ contract LockManagerTest is AragonTest { _; } - function test_WhenTryingToUnlock1Flexible() - external - givenFlexibleModeIsSet - givenDidntLockAnythingFlexible - { + function test_WhenTryingToUnlock1Flexible() external givenFlexibleModeIsSet givenDidntLockAnythingFlexible { // It Should do nothing vm.skip(true); } @@ -293,11 +243,7 @@ contract LockManagerTest is AragonTest { _; } - function test_WhenProposalVoterCallsUnlockReleased() - external - givenAProposalHasEnded - whenAfterReleaseLockIsCalled - { + function test_WhenProposalVoterCallsUnlockReleased() external givenAProposalHasEnded whenAfterReleaseLockIsCalled { // It Should allow voters from that proposal to unlock right away // It Should revert on voters who have any other unreleased proposal votes vm.skip(true); diff --git a/test/LockToVote.t.sol b/test/LockToVote.t.sol index eabd8a9..f9560bd 100644 --- a/test/LockToVote.t.sol +++ b/test/LockToVote.t.sol @@ -28,10 +28,7 @@ contract LockToVoteTest is AragonTest { _; } - function test_RevertWhen_UpdateSettingsWithoutThePermission() - external - whenCallingUpdateSettings - { + function test_RevertWhen_UpdateSettingsWithoutThePermission() external whenCallingUpdateSettings { // It should revert vm.skip(true); } diff --git a/test/constants.sol b/test/constants.sol index eb493f5..276178b 100644 --- a/test/constants.sol +++ b/test/constants.sol @@ -3,12 +3,8 @@ pragma solidity ^0.8.17; bytes32 constant PROPOSER_PERMISSION_ID = keccak256("PROPOSER_PERMISSION"); bytes32 constant EXECUTE_PERMISSION_ID = keccak256("EXECUTE_PERMISSION"); -bytes32 constant UPDATE_SETTINGS_PERMISSION_ID = keccak256( - "UPDATE_SETTINGS_PERMISSION" -); -bytes32 constant UPGRADE_PLUGIN_PERMISSION_ID = keccak256( - "UPGRADE_PLUGIN_PERMISSION" -); +bytes32 constant UPDATE_SETTINGS_PERMISSION_ID = keccak256("UPDATE_SETTINGS_PERMISSION"); +bytes32 constant UPGRADE_PLUGIN_PERMISSION_ID = keccak256("UPGRADE_PLUGIN_PERMISSION"); bytes32 constant ROOT_PERMISSION_ID = keccak256("ROOT_PERMISSION"); uint64 constant MAX_UINT64 = uint64(2 ** 64 - 1); @@ -16,15 +12,7 @@ address constant ADDRESS_ZERO = address(0x0); address constant NO_CONDITION = ADDRESS_ZERO; // Actors -address constant ALICE_ADDRESS = address( - 0xa11ce00000000a11ce00000000a11ce0000000 -); -address constant BOB_ADDRESS = address( - 0xB0B00000000B0B00000000B0B00000000B0B00 -); -address constant CAROL_ADDRESS = address( - 0xc460100000000c460100000000c46010000000 -); -address constant DAVID_ADDRESS = address( - 0xd471d00000000d471d00000000d471d0000000 -); +address constant ALICE_ADDRESS = address(0xa11ce00000000a11ce00000000a11ce0000000); +address constant BOB_ADDRESS = address(0xB0B00000000B0B00000000B0B00000000B0B00); +address constant CAROL_ADDRESS = address(0xc460100000000c460100000000c46010000000); +address constant DAVID_ADDRESS = address(0xd471d00000000d471d00000000d471d0000000); diff --git a/test/mocks/TestToken.sol b/test/mocks/TestToken.sol index 3fb648d..e484c04 100644 --- a/test/mocks/TestToken.sol +++ b/test/mocks/TestToken.sol @@ -12,11 +12,7 @@ contract TestToken is ERC20, ERC20Permit, ERC20Votes { // The following functions are overrides required by Solidity. - function _afterTokenTransfer( - address from, - address to, - uint256 amount - ) internal override(ERC20, ERC20Votes) { + function _afterTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) { super._afterTokenTransfer(from, to, amount); } @@ -28,17 +24,11 @@ contract TestToken is ERC20, ERC20Permit, ERC20Votes { _burn(account, amount); } - function _mint( - address to, - uint256 amount - ) internal override(ERC20, ERC20Votes) { + function _mint(address to, uint256 amount) internal override(ERC20, ERC20Votes) { super._mint(to, amount); } - function _burn( - address account, - uint256 amount - ) internal override(ERC20, ERC20Votes) { + function _burn(address account, uint256 amount) internal override(ERC20, ERC20Votes) { super._burn(account, amount); } } diff --git a/test/mocks/osx/MockPSP.sol b/test/mocks/osx/MockPSP.sol index eaa1604..c5624ac 100644 --- a/test/mocks/osx/MockPSP.sol +++ b/test/mocks/osx/MockPSP.sol @@ -11,7 +11,15 @@ import {IPlugin} from "@aragon/osx-commons-contracts/src/plugin/IPlugin.sol"; import {PluginRepo} from "@aragon/osx/src/framework/plugin/repo/PluginRepo.sol"; import {PluginSetup, IPluginSetup} from "@aragon/osx-commons-contracts/src/plugin/setup/PluginSetup.sol"; -import {PluginSetupRef, hashHelpers, hashPermissions, _getPreparedSetupId, _getAppliedSetupId, _getPluginInstallationId, PreparationType} from "@aragon/osx/src/framework/plugin/setup/PluginSetupProcessorHelpers.sol"; +import { + PluginSetupRef, + hashHelpers, + hashPermissions, + _getPreparedSetupId, + _getAppliedSetupId, + _getPluginInstallationId, + PreparationType +} from "@aragon/osx/src/framework/plugin/setup/PluginSetupProcessorHelpers.sol"; /// @title PluginSetupProcessor /// @author Aragon Association - 2022-2023 @@ -21,26 +29,21 @@ contract MockPluginSetupProcessor { using ERC165Checker for address; /// @notice The ID of the permission required to call the `applyInstallation` function. - bytes32 public constant APPLY_INSTALLATION_PERMISSION_ID = - keccak256("APPLY_INSTALLATION_PERMISSION"); + bytes32 public constant APPLY_INSTALLATION_PERMISSION_ID = keccak256("APPLY_INSTALLATION_PERMISSION"); /// @notice The ID of the permission required to call the `applyUpdate` function. - bytes32 public constant APPLY_UPDATE_PERMISSION_ID = - keccak256("APPLY_UPDATE_PERMISSION"); + bytes32 public constant APPLY_UPDATE_PERMISSION_ID = keccak256("APPLY_UPDATE_PERMISSION"); /// @notice The ID of the permission required to call the `applyUninstallation` function. - bytes32 public constant APPLY_UNINSTALLATION_PERMISSION_ID = - keccak256("APPLY_UNINSTALLATION_PERMISSION"); + bytes32 public constant APPLY_UNINSTALLATION_PERMISSION_ID = keccak256("APPLY_UNINSTALLATION_PERMISSION"); /// @notice The hash obtained from the bytes-encoded empty array to be used for UI updates being required to submit an empty permission array. /// @dev The hash is computed via `keccak256(abi.encode([]))`. - bytes32 private constant EMPTY_ARRAY_HASH = - 0x569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd; + bytes32 private constant EMPTY_ARRAY_HASH = 0x569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd; /// @notice The hash obtained from the bytes-encoded zero value. /// @dev The hash is computed via `keccak256(abi.encode(0))`. - bytes32 private constant ZERO_BYTES_HASH = - 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563; + bytes32 private constant ZERO_BYTES_HASH = 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563; /// @notice A struct containing information related to plugin setups that have been applied. /// @param blockNumber The block number at which the `applyInstallation`, `applyUpdate` or `applyUninstallation` was executed. @@ -130,11 +133,7 @@ contract MockPluginSetupProcessor { /// @param caller The address (EOA or contract) that requested the application of a setup on the associated DAO. /// @param permissionId The permission identifier. /// @dev This is thrown if the `APPLY_INSTALLATION_PERMISSION_ID`, `APPLY_UPDATE_PERMISSION_ID`, or APPLY_UNINSTALLATION_PERMISSION_ID is missing. - error SetupApplicationUnauthorized( - address dao, - address caller, - bytes32 permissionId - ); + error SetupApplicationUnauthorized(address dao, address caller, bytes32 permissionId); /// @notice Thrown if a plugin is not upgradeable. /// @param plugin The address of the plugin contract. @@ -144,11 +143,7 @@ contract MockPluginSetupProcessor { /// @param proxy The address of the proxy. /// @param implementation The address of the implementation contract. /// @param initData The initialization data to be passed to the upgradeable plugin contract via `upgradeToAndCall`. - error PluginProxyUpgradeFailed( - address proxy, - address implementation, - bytes initData - ); + error PluginProxyUpgradeFailed(address proxy, address implementation, bytes initData); /// @notice Thrown if a contract does not support the `IPlugin` interface. /// @param plugin The address of the contract. @@ -168,10 +163,7 @@ contract MockPluginSetupProcessor { /// @notice Thrown if the update version is invalid. /// @param currentVersionTag The tag of the current version to update from. /// @param newVersionTag The tag of the new version to update to. - error InvalidUpdateVersion( - PluginRepo.Tag currentVersionTag, - PluginRepo.Tag newVersionTag - ); + error InvalidUpdateVersion(PluginRepo.Tag currentVersionTag, PluginRepo.Tag newVersionTag); /// @notice Thrown if plugin is already installed and one tries to prepare or apply install on it. error PluginAlreadyInstalled(); @@ -179,10 +171,7 @@ contract MockPluginSetupProcessor { /// @notice Thrown if the applied setup ID resulting from the supplied setup payload does not match with the current applied setup ID. /// @param currentAppliedSetupId The current applied setup ID with which the data in the supplied payload must match. /// @param appliedSetupId The applied setup ID obtained from the data in the supplied setup payload. - error InvalidAppliedSetupId( - bytes32 currentAppliedSetupId, - bytes32 appliedSetupId - ); + error InvalidAppliedSetupId(bytes32 currentAppliedSetupId, bytes32 appliedSetupId); /// @notice Emitted with a prepared plugin installation to store data relevant for the application step. /// @param sender The sender that prepared the plugin installation. @@ -210,10 +199,7 @@ contract MockPluginSetupProcessor { /// @param preparedSetupId The prepared setup ID. /// @param appliedSetupId The applied setup ID. event InstallationApplied( - address indexed dao, - address indexed plugin, - bytes32 preparedSetupId, - bytes32 appliedSetupId + address indexed dao, address indexed plugin, bytes32 preparedSetupId, bytes32 appliedSetupId ); /// @notice Emitted with a prepared plugin update to store data relevant for the application step. @@ -241,12 +227,7 @@ contract MockPluginSetupProcessor { /// @param plugin The address of the plugin contract. /// @param preparedSetupId The prepared setup ID. /// @param appliedSetupId The applied setup ID. - event UpdateApplied( - address indexed dao, - address indexed plugin, - bytes32 preparedSetupId, - bytes32 appliedSetupId - ); + event UpdateApplied(address indexed dao, address indexed plugin, bytes32 preparedSetupId, bytes32 appliedSetupId); /// @notice Emitted with a prepared plugin uninstallation to store data relevant for the application step. /// @param sender The sender that prepared the plugin uninstallation. @@ -270,11 +251,7 @@ contract MockPluginSetupProcessor { /// @param dao The address of the DAO to which the plugin belongs. /// @param plugin The address of the plugin contract. /// @param preparedSetupId The prepared setup ID. - event UninstallationApplied( - address indexed dao, - address indexed plugin, - bytes32 preparedSetupId - ); + event UninstallationApplied(address indexed dao, address indexed plugin, bytes32 preparedSetupId); /// @notice A modifier to check if a caller has the permission to apply a prepared setup. /// @param _dao The address of the DAO. @@ -311,15 +288,9 @@ contract MockPluginSetupProcessor { /// @param _params The struct containing the parameters for the `prepareInstallation` function. /// @return plugin The prepared plugin contract address. /// @return preparedSetupData The data struct containing the array of helper contracts and permissions that the setup has prepared. - function prepareInstallation( - address _dao, - PrepareInstallationParams calldata _params - ) + function prepareInstallation(address _dao, PrepareInstallationParams calldata _params) external - returns ( - address plugin, - IPluginSetup.PreparedSetupData memory preparedSetupData - ) + returns (address plugin, IPluginSetup.PreparedSetupData memory preparedSetupData) { // PluginRepo pluginSetupRepo = _params.pluginSetupRef.pluginSetupRepo; @@ -335,10 +306,7 @@ contract MockPluginSetupProcessor { // Prepare the installation address setup = popSetup(); - (plugin, preparedSetupData) = PluginSetup(setup).prepareInstallation( - _dao, - _params.data - ); + (plugin, preparedSetupData) = PluginSetup(setup).prepareInstallation(_dao, _params.data); // bytes32 pluginInstallationId = _getPluginInstallationId(_dao, plugin); @@ -381,10 +349,10 @@ contract MockPluginSetupProcessor { /// @notice Applies the permissions of a prepared installation to a DAO. /// @param _dao The address of the installing DAO. /// @param _params The struct containing the parameters for the `applyInstallation` function. - function applyInstallation( - address _dao, - ApplyInstallationParams calldata _params - ) external canApply(_dao, APPLY_INSTALLATION_PERMISSION_ID) { + function applyInstallation(address _dao, ApplyInstallationParams calldata _params) + external + canApply(_dao, APPLY_INSTALLATION_PERMISSION_ID) + { // bytes32 pluginInstallationId = _getPluginInstallationId(_dao, _params.plugin); // PluginState storage pluginState = states[pluginInstallationId]; @@ -428,20 +396,13 @@ contract MockPluginSetupProcessor { /// @return initData The initialization data to be passed to upgradeable contracts when the update is applied /// @return preparedSetupData The data struct containing the array of helper contracts and permissions that the setup has prepared. /// @dev The list of `_params.setupPayload.currentHelpers` has to be specified in the same order as they were returned from previous setups preparation steps (the latest `prepareInstallation` or `prepareUpdate` step that has happend) on which the update is prepared for. - function prepareUpdate( - address _dao, - PrepareUpdateParams calldata _params - ) + function prepareUpdate(address _dao, PrepareUpdateParams calldata _params) external - returns ( - bytes memory initData, - IPluginSetup.PreparedSetupData memory preparedSetupData - ) + returns (bytes memory initData, IPluginSetup.PreparedSetupData memory preparedSetupData) { if ( - _params.currentVersionTag.release != - _params.newVersionTag.release || - _params.currentVersionTag.build >= _params.newVersionTag.build + _params.currentVersionTag.release != _params.newVersionTag.release + || _params.currentVersionTag.build >= _params.newVersionTag.build ) { revert InvalidUpdateVersion({ currentVersionTag: _params.currentVersionTag, @@ -449,21 +410,14 @@ contract MockPluginSetupProcessor { }); } - bytes32 pluginInstallationId = _getPluginInstallationId( - _dao, - _params.setupPayload.plugin - ); + bytes32 pluginInstallationId = _getPluginInstallationId(_dao, _params.setupPayload.plugin); PluginState storage pluginState = states[pluginInstallationId]; - bytes32 currentHelpersHash = hashHelpers( - _params.setupPayload.currentHelpers - ); + bytes32 currentHelpersHash = hashHelpers(_params.setupPayload.currentHelpers); - bytes32 appliedSetupId = _getAppliedSetupId( - PluginSetupRef(_params.currentVersionTag, _params.pluginSetupRepo), - currentHelpersHash - ); + bytes32 appliedSetupId = + _getAppliedSetupId(PluginSetupRef(_params.currentVersionTag, _params.pluginSetupRepo), currentHelpersHash); // The following check implicitly confirms that plugin is currently installed. // Otherwise, `currentAppliedSetupId` would not be set. @@ -474,13 +428,9 @@ contract MockPluginSetupProcessor { }); } - PluginRepo.Version memory currentVersion = _params - .pluginSetupRepo - .getVersion(_params.currentVersionTag); + PluginRepo.Version memory currentVersion = _params.pluginSetupRepo.getVersion(_params.currentVersionTag); - PluginRepo.Version memory newVersion = _params - .pluginSetupRepo - .getVersion(_params.newVersionTag); + PluginRepo.Version memory newVersion = _params.pluginSetupRepo.getVersion(_params.newVersionTag); bytes32 preparedSetupId; @@ -502,31 +452,17 @@ contract MockPluginSetupProcessor { preparedSetupData.helpers = _params.setupPayload.currentHelpers; } else { // Check that plugin is `PluginUUPSUpgradable`. - if ( - !_params.setupPayload.plugin.supportsInterface( - type(IPlugin).interfaceId - ) - ) { - revert IPluginNotSupported({ - plugin: _params.setupPayload.plugin - }); + if (!_params.setupPayload.plugin.supportsInterface(type(IPlugin).interfaceId)) { + revert IPluginNotSupported({plugin: _params.setupPayload.plugin}); } - if ( - IPlugin(_params.setupPayload.plugin).pluginType() != - IPlugin.PluginType.UUPS - ) { - revert PluginNonupgradeable({ - plugin: _params.setupPayload.plugin - }); + if (IPlugin(_params.setupPayload.plugin).pluginType() != IPlugin.PluginType.UUPS) { + revert PluginNonupgradeable({plugin: _params.setupPayload.plugin}); } // Prepare the update. - (initData, preparedSetupData) = PluginSetup(newVersion.pluginSetup) - .prepareUpdate( - _dao, - _params.currentVersionTag.build, - _params.setupPayload - ); + (initData, preparedSetupData) = PluginSetup(newVersion.pluginSetup).prepareUpdate( + _dao, _params.currentVersionTag.build, _params.setupPayload + ); preparedSetupId = _getPreparedSetupId( PluginSetupRef(_params.newVersionTag, _params.pluginSetupRepo), @@ -538,24 +474,14 @@ contract MockPluginSetupProcessor { } // Check if this setup has already been prepared before and is pending. - if ( - pluginState.blockNumber < - pluginState.preparedSetupIdToBlockNumber[preparedSetupId] - ) { + if (pluginState.blockNumber < pluginState.preparedSetupIdToBlockNumber[preparedSetupId]) { revert SetupAlreadyPrepared({preparedSetupId: preparedSetupId}); } - pluginState.preparedSetupIdToBlockNumber[preparedSetupId] = block - .number; + pluginState.preparedSetupIdToBlockNumber[preparedSetupId] = block.number; // Avoid stack too deep. - emitPrepareUpdateEvent( - _dao, - preparedSetupId, - _params, - preparedSetupData, - initData - ); + emitPrepareUpdateEvent(_dao, preparedSetupId, _params, preparedSetupData, initData); return (initData, preparedSetupData); } @@ -563,14 +489,11 @@ contract MockPluginSetupProcessor { /// @notice Applies the permissions of a prepared update of an UUPS upgradeable proxy contract to a DAO. /// @param _dao The address of the updating DAO. /// @param _params The struct containing the parameters for the `applyInstallation` function. - function applyUpdate( - address _dao, - ApplyUpdateParams calldata _params - ) external canApply(_dao, APPLY_UPDATE_PERMISSION_ID) { - bytes32 pluginInstallationId = _getPluginInstallationId( - _dao, - _params.plugin - ); + function applyUpdate(address _dao, ApplyUpdateParams calldata _params) + external + canApply(_dao, APPLY_UPDATE_PERMISSION_ID) + { + bytes32 pluginInstallationId = _getPluginInstallationId(_dao, _params.plugin); PluginState storage pluginState = states[pluginInstallationId]; @@ -584,23 +507,16 @@ contract MockPluginSetupProcessor { validatePreparedSetupId(pluginInstallationId, preparedSetupId); - bytes32 appliedSetupId = _getAppliedSetupId( - _params.pluginSetupRef, - _params.helpersHash - ); + bytes32 appliedSetupId = _getAppliedSetupId(_params.pluginSetupRef, _params.helpersHash); pluginState.blockNumber = block.number; pluginState.currentAppliedSetupId = appliedSetupId; - PluginRepo.Version memory version = _params - .pluginSetupRef - .pluginSetupRepo - .getVersion(_params.pluginSetupRef.versionTag); + PluginRepo.Version memory version = + _params.pluginSetupRef.pluginSetupRepo.getVersion(_params.pluginSetupRef.versionTag); - address currentImplementation = PluginUUPSUpgradeable(_params.plugin) - .implementation(); - address newImplementation = PluginSetup(version.pluginSetup) - .implementation(); + address currentImplementation = PluginUUPSUpgradeable(_params.plugin).implementation(); + address newImplementation = PluginSetup(version.pluginSetup).implementation(); if (currentImplementation != newImplementation) { _upgradeProxy(_params.plugin, newImplementation, _params.initData); @@ -624,10 +540,7 @@ contract MockPluginSetupProcessor { /// @param _params The struct containing the parameters for the `prepareUninstallation` function. /// @return permissions The list of multi-targeted permission operations to be applied to the uninstalling DAO. /// @dev The list of `_params.setupPayload.currentHelpers` has to be specified in the same order as they were returned from previous setups preparation steps (the latest `prepareInstallation` or `prepareUpdate` step that has happend) on which the uninstallation was prepared for. - function prepareUninstallation( - address _dao, - PrepareUninstallationParams calldata _params - ) + function prepareUninstallation(address _dao, PrepareUninstallationParams calldata _params) external returns (PermissionLib.MultiTargetPermission[] memory permissions) { @@ -651,10 +564,7 @@ contract MockPluginSetupProcessor { // _params.pluginSetupRef.versionTag // ); - permissions = PluginSetup(popSetup()).prepareUninstallation( - _dao, - _params.setupPayload - ); + permissions = PluginSetup(popSetup()).prepareUninstallation(_dao, _params.setupPayload); // bytes32 preparedSetupId = _getPreparedSetupId( // _params.pluginSetupRef, @@ -687,10 +597,10 @@ contract MockPluginSetupProcessor { /// @param _dao The address of the uninstalling DAO. /// @param _params The struct containing the parameters for the `applyUninstallation` function. /// @dev The list of `_params.setupPayload.currentHelpers` has to be specified in the same order as they were returned from previous setups preparation steps (the latest `prepareInstallation` or `prepareUpdate` step that has happend) on which the uninstallation was prepared for. - function applyUninstallation( - address _dao, - ApplyUninstallationParams calldata _params - ) external canApply(_dao, APPLY_UNINSTALLATION_PERMISSION_ID) { + function applyUninstallation(address _dao, ApplyUninstallationParams calldata _params) + external + canApply(_dao, APPLY_UNINSTALLATION_PERMISSION_ID) + { // bytes32 pluginInstallationId = _getPluginInstallationId(_dao, _params.plugin); // PluginState storage pluginState = states[pluginInstallationId]; @@ -725,15 +635,9 @@ contract MockPluginSetupProcessor { /// @param pluginInstallationId The plugin installation ID obtained from the hash of `abi.encode(daoAddress, pluginAddress)`. /// @param preparedSetupId The prepared setup ID to be validated. /// @dev If the block number stored in `states[pluginInstallationId].blockNumber` exceeds the one stored in `pluginState.preparedSetupIdToBlockNumber[preparedSetupId]`, the prepared setup with `preparedSetupId` is outdated and not applicable anymore. - function validatePreparedSetupId( - bytes32 pluginInstallationId, - bytes32 preparedSetupId - ) public view { + function validatePreparedSetupId(bytes32 pluginInstallationId, bytes32 preparedSetupId) public view { PluginState storage pluginState = states[pluginInstallationId]; - if ( - pluginState.blockNumber >= - pluginState.preparedSetupIdToBlockNumber[preparedSetupId] - ) { + if (pluginState.blockNumber >= pluginState.preparedSetupIdToBlockNumber[preparedSetupId]) { revert SetupNotApplicable({preparedSetupId: preparedSetupId}); } } @@ -742,37 +646,20 @@ contract MockPluginSetupProcessor { /// @param _proxy The address of the proxy. /// @param _implementation The address of the implementation contract. /// @param _initData The initialization data to be passed to the upgradeable plugin contract via `upgradeToAndCall`. - function _upgradeProxy( - address _proxy, - address _implementation, - bytes memory _initData - ) private { + function _upgradeProxy(address _proxy, address _implementation, bytes memory _initData) private { if (_initData.length > 0) { - try - PluginUUPSUpgradeable(_proxy).upgradeToAndCall( - _implementation, - _initData - ) - {} catch Error(string memory reason) { + try PluginUUPSUpgradeable(_proxy).upgradeToAndCall(_implementation, _initData) {} + catch Error(string memory reason) { revert(reason); } catch (bytes memory) /*lowLevelData*/ { - revert PluginProxyUpgradeFailed({ - proxy: _proxy, - implementation: _implementation, - initData: _initData - }); + revert PluginProxyUpgradeFailed({proxy: _proxy, implementation: _implementation, initData: _initData}); } } else { - try - PluginUUPSUpgradeable(_proxy).upgradeTo(_implementation) - {} catch Error(string memory reason) { + try PluginUUPSUpgradeable(_proxy).upgradeTo(_implementation) {} + catch Error(string memory reason) { revert(reason); } catch (bytes memory) /*lowLevelData*/ { - revert PluginProxyUpgradeFailed({ - proxy: _proxy, - implementation: _implementation, - initData: _initData - }); + revert PluginProxyUpgradeFailed({proxy: _proxy, implementation: _implementation, initData: _initData}); } } } @@ -782,19 +669,9 @@ contract MockPluginSetupProcessor { /// @param _permissionId The permission ID. function _canApply(address _dao, bytes32 _permissionId) private view { if ( - msg.sender != _dao && - !DAO(payable(_dao)).hasPermission( - address(this), - msg.sender, - _permissionId, - bytes("") - ) + msg.sender != _dao && !DAO(payable(_dao)).hasPermission(address(this), msg.sender, _permissionId, bytes("")) ) { - revert SetupApplicationUnauthorized({ - dao: _dao, - caller: msg.sender, - permissionId: _permissionId - }); + revert SetupApplicationUnauthorized({dao: _dao, caller: msg.sender, permissionId: _permissionId}); } } diff --git a/test/util/AragonTest.sol b/test/util/AragonTest.sol index 2c24c66..152353f 100644 --- a/test/util/AragonTest.sol +++ b/test/util/AragonTest.sol @@ -29,9 +29,7 @@ contract AragonTest is Test { /// @param name The name to get the address and private key for. /// @return addr The address associated with the name. /// @return pk The private key associated with the name. - function getWallet( - string memory name - ) internal returns (address addr, uint256 pk) { + function getWallet(string memory name) internal returns (address addr, uint256 pk) { pk = uint256(keccak256(abi.encodePacked(name))); addr = vm.addr(pk); vm.label(addr, name); diff --git a/test/util/DaoBuilder.sol b/test/util/DaoBuilder.sol index 0e0cfec..2d3f5ac 100644 --- a/test/util/DaoBuilder.sol +++ b/test/util/DaoBuilder.sol @@ -9,185 +9,185 @@ import {LockToVotePlugin} from "../../src/LockToVotePlugin.sol"; import {LockManager} from "../../src/LockManager.sol"; contract DaoBuilder is Test { - // address immutable DAO_BASE = address(new DAO()); - - // struct MintEntry { - // address tokenHolder; - // uint256 amount; - // } - - // address public owner = ALICE_ADDRESS; - - // address[] public proposers; - // MintEntry[] public tokenHolders; - - // bool public onlyListed = true; - // uint16 public minApprovals = 1; - // uint32 public proposalDuration = 10 days; - - // function withDaoOwner(address newOwner) public returns (DaoBuilder) { - // owner = newOwner; - // return this; - // } - - // function withTokenHolder( - // address newTokenHolder, - // uint256 amount - // ) public returns (DaoBuilder) { - // tokenHolders.push( - // MintEntry({tokenHolder: newTokenHolder, amount: amount}) - // ); - // return this; - // } - - // function withMinVetoRatio( - // uint32 newMinVetoRatio - // ) public returns (DaoBuilder) { - // if (newMinVetoRatio > RATIO_BASE) revert("Veto rate above 100%"); - // minVetoRatio = newMinVetoRatio; - // return this; - // } - - // function withMinDuration( - // uint32 newMinDuration - // ) public returns (DaoBuilder) { - // minDuration = newMinDuration; - // return this; - // } - - // function withDuration(uint32 newDuration) public returns (DaoBuilder) { - // proposalDuration = newDuration; - // return this; - // } - - // function withTimelock(uint32 newTimeLock) public returns (DaoBuilder) { - // timelockPeriod = newTimeLock; - // return this; - // } - - // function withExpiration( - // uint32 newExpirationPeriod - // ) public returns (DaoBuilder) { - // multisigProposalExpirationPeriod = newExpirationPeriod; - // return this; - // } - - // function withOnlyListed() public returns (DaoBuilder) { - // onlyListed = true; - // return this; - // } - - // function withoutOnlyListed() public returns (DaoBuilder) { - // onlyListed = false; - // return this; - // } - - // function withMultisigMember(address newMember) public returns (DaoBuilder) { - // multisigMembers.push(newMember); - // return this; - // } - - // function withProposer(address newProposer) public returns (DaoBuilder) { - // proposers.push(newProposer); - // return this; - // } - - // function withMinApprovals( - // uint16 newMinApprovals - // ) public returns (DaoBuilder) { - // if (newMinApprovals > multisigMembers.length) { - // revert("You should add enough multisig members first"); - // } - // minApprovals = newMinApprovals; - // return this; - // } - - // /// @dev Creates a DAO with the given orchestration settings. - // /// @dev The setup is done on block/timestamp 0 and tests should be made on block/timestamp 1 or later. - // function build() - // public - // returns (DAO dao, LockToVotePlugin plugin, LockManager helper) - // { - // // Deploy the DAO with `this` as root - // dao = DAO( - // payable( - // createProxyAndCall( - // address(DAO_BASE), - // abi.encodeCall( - // DAO.initialize, - // ("", address(this), address(0x0), "") - // ) - // ) - // ) - // ); - - // // Deploy ERC20 token - // votingToken = new GovernanceERC20Mock(address(dao)); - - // if (tokenHolders.length > 0) { - // for (uint256 i = 0; i < tokenHolders.length; i++) { - // votingToken.mintAndDelegate( - // tokenHolders[i].tokenHolder, - // tokenHolders[i].amount - // ); - // } - // } else { - // votingToken.mintAndDelegate(owner, 10 ether); - // } - - // { - // LockToVote.PluginSettings memory targetContractSettings = LockToVote - // .PluginSettings({ - // minVetoRatio: minVetoRatio, - // minDuration: minDuration, - // timelockPeriod: timelockPeriod, - // l2InactivityPeriod: l2InactivityPeriod, - // l2AggregationGracePeriod: l2AggregationGracePeriod, - // skipL2: skipL2 - // }); - - // plugin = LockToVote( - // createProxyAndCall( - // address(OPTIMISTIC_BASE), - // abi.encodeCall( - // LockToVote.initialize, - // ( - // dao, - // targetContractSettings, - // votingToken, - // ) - // ) - // ) - // ); - // } - - // // The plugin can execute on the DAO - // dao.grant(address(dao), address(plugin), dao.EXECUTE_PERMISSION_ID()); - - // if (proposers.length > 0) { - // for (uint256 i = 0; i < proposers.length; i++) { - // dao.grant( - // address(plugin), - // proposers[i], - // plugin.PROPOSER_PERMISSION_ID() - // ); - // } - // } else { - // // Ensure that at least the owner can propose - // dao.grant(address(plugin), owner, plugin.PROPOSER_PERMISSION_ID()); - // } - - // // Revoke transfer ownership to the owner - // dao.grant(address(dao), owner, dao.ROOT_PERMISSION_ID()); - // dao.revoke(address(dao), address(this), dao.ROOT_PERMISSION_ID()); - - // // Labels - // vm.label(address(dao), "DAO"); - // vm.label(address(plugin), "LockToVote plugin"); - // vm.label(address(votingToken), "VotingToken"); - - // // Moving forward to avoid proposal creations failing or getVotes() giving inconsistent values - // vm.roll(block.number + 1); - // vm.warp(block.timestamp + 1); - // } +// address immutable DAO_BASE = address(new DAO()); + +// struct MintEntry { +// address tokenHolder; +// uint256 amount; +// } + +// address public owner = ALICE_ADDRESS; + +// address[] public proposers; +// MintEntry[] public tokenHolders; + +// bool public onlyListed = true; +// uint16 public minApprovals = 1; +// uint32 public proposalDuration = 10 days; + +// function withDaoOwner(address newOwner) public returns (DaoBuilder) { +// owner = newOwner; +// return this; +// } + +// function withTokenHolder( +// address newTokenHolder, +// uint256 amount +// ) public returns (DaoBuilder) { +// tokenHolders.push( +// MintEntry({tokenHolder: newTokenHolder, amount: amount}) +// ); +// return this; +// } + +// function withMinVetoRatio( +// uint32 newMinVetoRatio +// ) public returns (DaoBuilder) { +// if (newMinVetoRatio > RATIO_BASE) revert("Veto rate above 100%"); +// minVetoRatio = newMinVetoRatio; +// return this; +// } + +// function withMinDuration( +// uint32 newMinDuration +// ) public returns (DaoBuilder) { +// minDuration = newMinDuration; +// return this; +// } + +// function withDuration(uint32 newDuration) public returns (DaoBuilder) { +// proposalDuration = newDuration; +// return this; +// } + +// function withTimelock(uint32 newTimeLock) public returns (DaoBuilder) { +// timelockPeriod = newTimeLock; +// return this; +// } + +// function withExpiration( +// uint32 newExpirationPeriod +// ) public returns (DaoBuilder) { +// multisigProposalExpirationPeriod = newExpirationPeriod; +// return this; +// } + +// function withOnlyListed() public returns (DaoBuilder) { +// onlyListed = true; +// return this; +// } + +// function withoutOnlyListed() public returns (DaoBuilder) { +// onlyListed = false; +// return this; +// } + +// function withMultisigMember(address newMember) public returns (DaoBuilder) { +// multisigMembers.push(newMember); +// return this; +// } + +// function withProposer(address newProposer) public returns (DaoBuilder) { +// proposers.push(newProposer); +// return this; +// } + +// function withMinApprovals( +// uint16 newMinApprovals +// ) public returns (DaoBuilder) { +// if (newMinApprovals > multisigMembers.length) { +// revert("You should add enough multisig members first"); +// } +// minApprovals = newMinApprovals; +// return this; +// } + +// /// @dev Creates a DAO with the given orchestration settings. +// /// @dev The setup is done on block/timestamp 0 and tests should be made on block/timestamp 1 or later. +// function build() +// public +// returns (DAO dao, LockToVotePlugin plugin, LockManager helper) +// { +// // Deploy the DAO with `this` as root +// dao = DAO( +// payable( +// createProxyAndCall( +// address(DAO_BASE), +// abi.encodeCall( +// DAO.initialize, +// ("", address(this), address(0x0), "") +// ) +// ) +// ) +// ); + +// // Deploy ERC20 token +// votingToken = new GovernanceERC20Mock(address(dao)); + +// if (tokenHolders.length > 0) { +// for (uint256 i = 0; i < tokenHolders.length; i++) { +// votingToken.mintAndDelegate( +// tokenHolders[i].tokenHolder, +// tokenHolders[i].amount +// ); +// } +// } else { +// votingToken.mintAndDelegate(owner, 10 ether); +// } + +// { +// LockToVote.PluginSettings memory targetContractSettings = LockToVote +// .PluginSettings({ +// minVetoRatio: minVetoRatio, +// minDuration: minDuration, +// timelockPeriod: timelockPeriod, +// l2InactivityPeriod: l2InactivityPeriod, +// l2AggregationGracePeriod: l2AggregationGracePeriod, +// skipL2: skipL2 +// }); + +// plugin = LockToVote( +// createProxyAndCall( +// address(OPTIMISTIC_BASE), +// abi.encodeCall( +// LockToVote.initialize, +// ( +// dao, +// targetContractSettings, +// votingToken, +// ) +// ) +// ) +// ); +// } + +// // The plugin can execute on the DAO +// dao.grant(address(dao), address(plugin), dao.EXECUTE_PERMISSION_ID()); + +// if (proposers.length > 0) { +// for (uint256 i = 0; i < proposers.length; i++) { +// dao.grant( +// address(plugin), +// proposers[i], +// plugin.PROPOSER_PERMISSION_ID() +// ); +// } +// } else { +// // Ensure that at least the owner can propose +// dao.grant(address(plugin), owner, plugin.PROPOSER_PERMISSION_ID()); +// } + +// // Revoke transfer ownership to the owner +// dao.grant(address(dao), owner, dao.ROOT_PERMISSION_ID()); +// dao.revoke(address(dao), address(this), dao.ROOT_PERMISSION_ID()); + +// // Labels +// vm.label(address(dao), "DAO"); +// vm.label(address(plugin), "LockToVote plugin"); +// vm.label(address(votingToken), "VotingToken"); + +// // Moving forward to avoid proposal creations failing or getVotes() giving inconsistent values +// vm.roll(block.number + 1); +// vm.warp(block.timestamp + 1); +// } } diff --git a/test/util/proxy.sol b/test/util/proxy.sol index 4eec965..b916ba1 100644 --- a/test/util/proxy.sol +++ b/test/util/proxy.sol @@ -3,9 +3,6 @@ pragma solidity ^0.8.17; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -function createProxyAndCall( - address _logic, - bytes memory _data -) returns (address) { +function createProxyAndCall(address _logic, bytes memory _data) returns (address) { return address(new ERC1967Proxy(_logic, _data)); }