From 06ec9dfe8d42432c6cf146f2ce99ea29b3b049bd Mon Sep 17 00:00:00 2001 From: Alberto Granzotto Date: Tue, 14 Nov 2023 16:12:31 +0100 Subject: [PATCH] WIP --- .../ResolutionManager/IResolutionManager.sol | 4 + .../ResolutionManagerBase.sol | 2 +- .../ShareholderRegistry.sol | 14 ++-- contracts/Voting/Voting.sol | 73 +++---------------- contracts/Voting/VotingBase.sol | 37 +++------- contracts/extensions/DAORegistry.sol | 42 ++++------- contracts/extensions/DAORegistryProxy.sol | 2 +- contracts/mocks/HasRoleMock.sol | 16 ---- contracts/mocks/NeokingdomTokenV2Mock.sol | 1 - contracts/mocks/ResolutionManagerV2Mock.sol | 1 - 10 files changed, 44 insertions(+), 148 deletions(-) create mode 100644 contracts/ResolutionManager/IResolutionManager.sol delete mode 100644 contracts/mocks/HasRoleMock.sol diff --git a/contracts/ResolutionManager/IResolutionManager.sol b/contracts/ResolutionManager/IResolutionManager.sol new file mode 100644 index 0000000..9314e7a --- /dev/null +++ b/contracts/ResolutionManager/IResolutionManager.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +interface IResolutionManager {} diff --git a/contracts/ResolutionManager/ResolutionManagerBase.sol b/contracts/ResolutionManager/ResolutionManagerBase.sol index 5449f69..d19563a 100644 --- a/contracts/ResolutionManager/ResolutionManagerBase.sol +++ b/contracts/ResolutionManager/ResolutionManagerBase.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.16; import "../extensions/DAORegistryProxy.sol"; -contract ResolutionManagerBase is DAORegistryProxy { +abstract contract ResolutionManagerBase is DAORegistryProxy { event ResolutionCreated(address indexed from, uint256 indexed resolutionId); event ResolutionUpdated(address indexed from, uint256 indexed resolutionId); diff --git a/contracts/ShareholderRegistry/ShareholderRegistry.sol b/contracts/ShareholderRegistry/ShareholderRegistry.sol index 9831853..c187318 100644 --- a/contracts/ShareholderRegistry/ShareholderRegistry.sol +++ b/contracts/ShareholderRegistry/ShareholderRegistry.sol @@ -41,7 +41,7 @@ contract ShareholderRegistry is Initializable, ShareholderRegistrySnapshot { public virtual override - onlyRole(Roles.RESOLUTION_ROLE) + onlyResolutionManager returns (uint256) { return _snapshot(); @@ -56,7 +56,7 @@ contract ShareholderRegistry is Initializable, ShareholderRegistrySnapshot { function setStatus( bytes32 status, address account - ) public virtual onlyRole(Roles.RESOLUTION_ROLE) { + ) public virtual onlyResolutionManager { _setStatus(status, account); } @@ -69,7 +69,7 @@ contract ShareholderRegistry is Initializable, ShareholderRegistrySnapshot { function mint( address account, uint256 amount - ) public virtual onlyRole(Roles.RESOLUTION_ROLE) { + ) public virtual onlyResolutionManager { _mint(account, amount); } @@ -82,7 +82,7 @@ contract ShareholderRegistry is Initializable, ShareholderRegistrySnapshot { function burn( address account, uint256 amount - ) external virtual onlyRole(Roles.RESOLUTION_ROLE) { + ) external virtual onlyResolutionManager { _burn(account, amount); } @@ -93,7 +93,7 @@ contract ShareholderRegistry is Initializable, ShareholderRegistrySnapshot { */ function batchTransferFromDAO( address[] memory recipients - ) public virtual onlyRole(Roles.RESOLUTION_ROLE) { + ) public virtual onlyResolutionManager { super._batchTransferFromDAO(recipients); } @@ -109,7 +109,7 @@ contract ShareholderRegistry is Initializable, ShareholderRegistrySnapshot { address from, address to, uint256 amount - ) public virtual override onlyRole(Roles.RESOLUTION_ROLE) returns (bool) { + ) public virtual override onlyResolutionManager returns (bool) { _transfer(from, to, amount); return true; } @@ -124,7 +124,7 @@ contract ShareholderRegistry is Initializable, ShareholderRegistrySnapshot { function transfer( address to, uint256 amount - ) public virtual override onlyRole(Roles.RESOLUTION_ROLE) returns (bool) { + ) public virtual override onlyResolutionManager returns (bool) { return super.transfer(to, amount); } } diff --git a/contracts/Voting/Voting.sol b/contracts/Voting/Voting.sol index 000df4f..8910f14 100644 --- a/contracts/Voting/Voting.sol +++ b/contracts/Voting/Voting.sol @@ -4,78 +4,23 @@ pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "../ShareholderRegistry/IShareholderRegistry.sol"; import "./VotingSnapshot.sol"; -import { Roles } from "../extensions/Roles.sol"; -import "../extensions/DAORoles.sol"; -import "../extensions/HasRole.sol"; /** * @title Voting * @notice The smart contract handles voting power delegation and manages voting snapshots. */ -contract Voting is VotingSnapshot, Initializable, HasRole { +contract Voting is VotingSnapshot, Initializable { /** * @notice Initializes the contract with given DAO roles. - * @param roles Instance of a DAORoles contract. + * @param daoRegistry Instance of a DAORoles contract. */ - function initialize(DAORoles roles) public initializer { - require(address(roles) != address(0), "Voting: 0x0 not allowed"); - _setRoles(roles); + function initialize(DAORegistry daoRegistry) public initializer { + __DAORegistryProxy_init(daoRegistry); } /// @custom:oz-upgrades-unsafe-allow constructor constructor() initializer {} - /** - * @dev Modifier that restricts access to only the token contract. - */ - modifier onlyToken() virtual { - require( - msg.sender == address(_token) || - msg.sender == address(_shareholderRegistry), - "Voting: only Token contract can call this method." - ); - _; - } - - modifier zeroCheck(address address_) { - require(address_ != address(0), "Voting: 0x0 not allowed"); - _; - } - - // Dependencies - - /** - * @notice Sets the token contract address. - * @param token Address of the token contract. - */ - function setToken( - IERC20Upgradeable token - ) - external - virtual - override - onlyRole(Roles.OPERATOR_ROLE) - zeroCheck(address(token)) - { - super._setToken(token); - } - - /** - * @notice Sets the shareholder registry contract address. - * @param shareholderRegistry Address of the shareholder registry contract. - */ - function setShareholderRegistry( - IShareholderRegistry shareholderRegistry - ) - external - virtual - override - onlyRole(Roles.OPERATOR_ROLE) - zeroCheck(address(shareholderRegistry)) - { - _setShareholderRegistry(shareholderRegistry); - } - // Snapshottable /** @@ -86,7 +31,7 @@ contract Voting is VotingSnapshot, Initializable, HasRole { public virtual override - onlyRole(Roles.RESOLUTION_ROLE) + onlyResolutionManager returns (uint256) { return _snapshot(); @@ -105,7 +50,7 @@ contract Voting is VotingSnapshot, Initializable, HasRole { address from, address to, uint256 amount - ) external virtual override onlyToken { + ) external virtual override onlyGovernanceToken { _afterTokenTransfer(from, to, amount); } @@ -115,7 +60,7 @@ contract Voting is VotingSnapshot, Initializable, HasRole { */ function beforeRemoveContributor( address account - ) external virtual override onlyRole(Roles.SHAREHOLDER_REGISTRY_ROLE) { + ) external virtual override onlyShareholderRegistry { _beforeRemoveContributor(account); } @@ -125,7 +70,7 @@ contract Voting is VotingSnapshot, Initializable, HasRole { */ function afterAddContributor( address account - ) external virtual override onlyRole(Roles.SHAREHOLDER_REGISTRY_ROLE) { + ) external virtual override onlyShareholderRegistry { _afterAddContributor(account); } @@ -149,7 +94,7 @@ contract Voting is VotingSnapshot, Initializable, HasRole { function delegateFrom( address delegator, address newDelegate - ) public virtual override onlyRole(Roles.RESOLUTION_ROLE) { + ) public virtual override onlyResolutionManager { _delegate(delegator, newDelegate); } } diff --git a/contracts/Voting/VotingBase.sol b/contracts/Voting/VotingBase.sol index fc37a67..241e1d9 100644 --- a/contracts/Voting/VotingBase.sol +++ b/contracts/Voting/VotingBase.sol @@ -1,11 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.16; +import "../extensions/DAORegistryProxy.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "../ShareholderRegistry/IShareholderRegistry.sol"; import "./IVoting.sol"; -abstract contract VotingBase is IVoting { +abstract contract VotingBase is IVoting, DAORegistryProxy { event DelegateChanged( address indexed delegator, address currentDelegate, @@ -18,9 +19,6 @@ abstract contract VotingBase is IVoting { uint256 newVotingPower ); - IShareholderRegistry internal _shareholderRegistry; - IERC20Upgradeable internal _token; - bytes32 internal _contributorRole; mapping(address => address) internal _delegates; @@ -29,17 +27,10 @@ abstract contract VotingBase is IVoting { uint256 internal _totalVotingPower; - // Abstract - function setToken(IERC20Upgradeable token) external virtual; - function beforeRemoveContributor(address account) external virtual; function afterAddContributor(address account) external virtual; - function setShareholderRegistry( - IShareholderRegistry shareholderRegistry - ) external virtual; - function canVote(address account) public view virtual returns (bool) { return getDelegate(account) != address(0); } @@ -75,17 +66,6 @@ abstract contract VotingBase is IVoting { // Internal - function _setToken(IERC20Upgradeable token) internal virtual { - _token = token; - } - - function _setShareholderRegistry( - IShareholderRegistry shareholderRegistry - ) internal virtual { - _shareholderRegistry = shareholderRegistry; - _contributorRole = _shareholderRegistry.CONTRIBUTOR_STATUS(); - } - function _afterTokenTransfer( address from, address to, @@ -106,11 +86,11 @@ abstract contract VotingBase is IVoting { // - participants are contributors // (this automatically enforces also that the address is not 0) require( - _shareholderRegistry.isAtLeast(_contributorRole, delegator), + getShareholderRegistry().isAtLeast(_contributorRole, delegator), "Voting: only contributors can delegate." ); require( - _shareholderRegistry.isAtLeast(_contributorRole, newDelegate), + getShareholderRegistry().isAtLeast(_contributorRole, newDelegate), "Voting: only contributors can be delegated." ); // - no sub delegation allowed @@ -138,8 +118,8 @@ abstract contract VotingBase is IVoting { _beforeDelegate(delegator); - uint256 delegatorBalance = _token.balanceOf(delegator) + - _shareholderRegistry.balanceOf(delegator); + uint256 delegatorBalance = getGovernanceToken().balanceOf(delegator) + + getShareholderRegistry().balanceOf(delegator); _delegates[delegator] = newDelegate; if (delegator != newDelegate && newDelegate != address(0)) { @@ -197,8 +177,9 @@ abstract contract VotingBase is IVoting { delete _delegates[account]; - uint256 individualVotingPower = _token.balanceOf(account) + - _shareholderRegistry.balanceOf(account); + uint256 individualVotingPower = getGovernanceToken().balanceOf( + account + ) + getShareholderRegistry().balanceOf(account); if (individualVotingPower > 0) { _moveVotingPower(account, address(0), individualVotingPower); } diff --git a/contracts/extensions/DAORegistry.sol b/contracts/extensions/DAORegistry.sol index cacb736..6f9d7b7 100644 --- a/contracts/extensions/DAORegistry.sol +++ b/contracts/extensions/DAORegistry.sol @@ -2,37 +2,25 @@ pragma solidity 0.8.16; -import "@openzeppelin/contracts/access/AccessControl.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; import "../NeokingdomToken/INeokingdomToken.sol"; import "../GovernanceToken/IGovernanceToken.sol"; import "../ShareholderRegistry/IShareholderRegistry.sol"; import "../Voting/IVoting.sol"; import "../RedemptionController/IRedemptionController.sol"; -import "../ResolutionManager/ResolutionManager.sol"; +import "../ResolutionManager/IResolutionManager.sol"; import "../InternalMarket/InternalMarket.sol"; -contract DAORegistry is AccessControl { +contract DAORegistry is Ownable { INeokingdomToken internal _neokingdomToken; IGovernanceToken internal _governanceToken; IShareholderRegistry internal _shareholderRegistry; IVoting internal _voting; IRedemptionController internal _redemptionController; - ResolutionManager internal _resolutionManager; + IResolutionManager internal _resolutionManager; InternalMarket internal _internalMarket; - constructor() { - _grantRole(DEFAULT_ADMIN_ROLE, _msgSender()); - } - - /* - function initialize() { - - } - */ - - function setNeokingdomToken( - INeokingdomToken neokingdomToken - ) public onlyRole(Roles.OPERATOR_ROLE) { + function setNeokingdomToken(INeokingdomToken neokingdomToken) public owner { _neokingdomToken = neokingdomToken; } @@ -48,9 +36,7 @@ contract DAORegistry is AccessControl { ); } - function setGovernanceToken( - IGovernanceToken governanceToken - ) public onlyRole(Roles.OPERATOR_ROLE) { + function setGovernanceToken(IGovernanceToken governanceToken) public owner { _governanceToken = governanceToken; } @@ -68,7 +54,7 @@ contract DAORegistry is AccessControl { function setShareholderRegistry( IShareholderRegistry shareholderRegistry - ) public onlyRole(Roles.OPERATOR_ROLE) { + ) public owner { _shareholderRegistry = shareholderRegistry; } @@ -88,7 +74,7 @@ contract DAORegistry is AccessControl { ); } - function setVoting(IVoting voting) public onlyRole(Roles.OPERATOR_ROLE) { + function setVoting(IVoting voting) public owner { _voting = voting; } @@ -103,7 +89,7 @@ contract DAORegistry is AccessControl { function setRedemptionController( IRedemptionController redemptionController - ) public onlyRole(Roles.OPERATOR_ROLE) { + ) public owner { _redemptionController = redemptionController; } @@ -124,12 +110,12 @@ contract DAORegistry is AccessControl { } function setResolutionManager( - ResolutionManager resolutionManager - ) public onlyRole(Roles.OPERATOR_ROLE) { + IResolutionManager resolutionManager + ) public owner { _resolutionManager = resolutionManager; } - function getResolutionManager() public view returns (ResolutionManager) { + function getResolutionManager() public view returns (IResolutionManager) { return _resolutionManager; } @@ -141,9 +127,7 @@ contract DAORegistry is AccessControl { ); } - function setInternalMarket( - InternalMarket internalMarket - ) public onlyRole(Roles.OPERATOR_ROLE) { + function setInternalMarket(InternalMarket internalMarket) public owner { _internalMarket = internalMarket; } diff --git a/contracts/extensions/DAORegistryProxy.sol b/contracts/extensions/DAORegistryProxy.sol index 3feb9d5..463b4d6 100644 --- a/contracts/extensions/DAORegistryProxy.sol +++ b/contracts/extensions/DAORegistryProxy.sol @@ -86,7 +86,7 @@ contract DAORegistryProxy is ContextUpgradeable { // Resolution Manager contract - function getResolutionManager() public view returns (ResolutionManager) { + function getResolutionManager() public view returns (IResolutionManager) { return _daoRegistry.getResolutionManager(); } diff --git a/contracts/mocks/HasRoleMock.sol b/contracts/mocks/HasRoleMock.sol deleted file mode 100644 index 65912c8..0000000 --- a/contracts/mocks/HasRoleMock.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.16; - -import "../extensions/HasRole.sol"; - -contract HasRoleMock is Initializable, HasRole { - function initialize(DAORoles roles) public initializer { - _setRoles(roles); - } - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor() initializer {} - - function checkOnlyRole(bytes32 role) public onlyRole(role) {} -} diff --git a/contracts/mocks/NeokingdomTokenV2Mock.sol b/contracts/mocks/NeokingdomTokenV2Mock.sol index b65d5f3..814c226 100644 --- a/contracts/mocks/NeokingdomTokenV2Mock.sol +++ b/contracts/mocks/NeokingdomTokenV2Mock.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.16; import "../GovernanceToken/GovernanceToken.sol"; -import "../extensions/Roles.sol"; contract GovernanceTokenV2Mock is GovernanceToken { function transfer(address, uint256) public virtual override returns (bool) { diff --git a/contracts/mocks/ResolutionManagerV2Mock.sol b/contracts/mocks/ResolutionManagerV2Mock.sol index 4f60444..ea4d1a5 100644 --- a/contracts/mocks/ResolutionManagerV2Mock.sol +++ b/contracts/mocks/ResolutionManagerV2Mock.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.16; import "../ResolutionManager/ResolutionManager.sol"; -import "../extensions/Roles.sol"; contract ResolutionManagerV2Mock is ResolutionManager { function reinitialize() public reinitializer(2) {