From 4025063e6a62cf10f2a979a652afd98db7a4c4b8 Mon Sep 17 00:00:00 2001 From: Nicola Miotto Date: Wed, 30 Aug 2023 13:12:23 +0200 Subject: [PATCH 1/5] Add zero check on initialization (#117) Close #96 --- contracts/GovernanceToken/GovernanceToken.sol | 4 ++++ contracts/InternalMarket/InternalMarket.sol | 5 +++++ contracts/RedemptionController/RedemptionController.sol | 4 ++++ contracts/ResolutionManager/ResolutionManager.sol | 7 +++++++ contracts/ShareholderRegistry/ShareholderRegistry.sol | 4 ++++ contracts/Voting/Voting.sol | 1 + 6 files changed, 25 insertions(+) diff --git a/contracts/GovernanceToken/GovernanceToken.sol b/contracts/GovernanceToken/GovernanceToken.sol index e438e1a..da45042 100644 --- a/contracts/GovernanceToken/GovernanceToken.sol +++ b/contracts/GovernanceToken/GovernanceToken.sol @@ -46,6 +46,10 @@ contract GovernanceToken is Initializable, HasRole, GovernanceTokenSnapshot { string memory name, string memory symbol ) public initializer { + require( + address(roles) != address(0), + "GovernanceToken: 0x0 not allowed" + ); _initialize(name, symbol); _setRoles(roles); } diff --git a/contracts/InternalMarket/InternalMarket.sol b/contracts/InternalMarket/InternalMarket.sol index 6ea3ca3..1a445bd 100644 --- a/contracts/InternalMarket/InternalMarket.sol +++ b/contracts/InternalMarket/InternalMarket.sol @@ -25,6 +25,11 @@ contract InternalMarket is Initializable, HasRole, InternalMarketBase { DAORoles roles, IGovernanceToken governanceToken ) public initializer { + require( + address(roles) != address(0) && + address(governanceToken) != address(0), + "InternalMarket: 0x0 not allowed" + ); _initialize(governanceToken, 7 days); _setRoles(roles); } diff --git a/contracts/RedemptionController/RedemptionController.sol b/contracts/RedemptionController/RedemptionController.sol index 79197d4..076bc75 100644 --- a/contracts/RedemptionController/RedemptionController.sol +++ b/contracts/RedemptionController/RedemptionController.sol @@ -35,6 +35,10 @@ contract RedemptionController is * @param roles The addresses of DAORoles for this contract. */ function initialize(DAORoles roles) public initializer { + require( + address(roles) != address(0), + "RedemptionController: 0x0 not allowed" + ); _setRoles(roles); _initialize(); } diff --git a/contracts/ResolutionManager/ResolutionManager.sol b/contracts/ResolutionManager/ResolutionManager.sol index 367e15e..e884cd6 100644 --- a/contracts/ResolutionManager/ResolutionManager.sol +++ b/contracts/ResolutionManager/ResolutionManager.sol @@ -26,6 +26,13 @@ contract ResolutionManager is Initializable, ResolutionManagerBase, HasRole { IGovernanceToken governanceToken, IVoting voting ) public initializer { + require( + address(roles) != address(0) && + address(shareholderRegistry) != address(0) && + address(governanceToken) != address(0) && + address(voting) != address(0), + "ResolutionManager: 0x0 not allowed" + ); _setRoles(roles); _initialize(shareholderRegistry, governanceToken, voting); } diff --git a/contracts/ShareholderRegistry/ShareholderRegistry.sol b/contracts/ShareholderRegistry/ShareholderRegistry.sol index e11c63e..735c36d 100644 --- a/contracts/ShareholderRegistry/ShareholderRegistry.sol +++ b/contracts/ShareholderRegistry/ShareholderRegistry.sol @@ -28,6 +28,10 @@ contract ShareholderRegistry is string memory name, string memory symbol ) public initializer { + require( + address(roles) != address(0), + "ShareholderRegistry: 0x0 not allowed" + ); _initialize(name, symbol); _setRoles(roles); } diff --git a/contracts/Voting/Voting.sol b/contracts/Voting/Voting.sol index d12cd71..5141b8e 100644 --- a/contracts/Voting/Voting.sol +++ b/contracts/Voting/Voting.sol @@ -18,6 +18,7 @@ contract Voting is VotingSnapshot, Initializable, HasRole { * @param roles Instance of a DAORoles contract. */ function initialize(DAORoles roles) public initializer { + require(address(roles) != address(0), "Voting: 0x0 not allowed"); _setRoles(roles); } From 8ce849b8b3521065151a42bbb9af0929159ea1b3 Mon Sep 17 00:00:00 2001 From: Nicola Miotto Date: Wed, 30 Aug 2023 13:12:34 +0200 Subject: [PATCH 2/5] Fix comments (#118) close #94 --- contracts/ShareholderRegistry/ShareholderRegistryBase.sol | 5 ++++- contracts/Voting/Voting.sol | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/contracts/ShareholderRegistry/ShareholderRegistryBase.sol b/contracts/ShareholderRegistry/ShareholderRegistryBase.sol index 74343f0..49b877d 100644 --- a/contracts/ShareholderRegistry/ShareholderRegistryBase.sol +++ b/contracts/ShareholderRegistry/ShareholderRegistryBase.sol @@ -84,7 +84,10 @@ contract ShareholderRegistryBase is ERC20Upgradeable { ) internal view virtual returns (bool) { return balance > 0 && - // shareholder < investor < contributor < managing board + // investor < contributor < managing board + // TODO: shareholder is currently equivalent to investor. + // We need to verify with the lawyer whether we can remove it + // completely from the smart contracts. (status == INVESTOR_STATUS || status == SHAREHOLDER_STATUS || status == accountStatus || diff --git a/contracts/Voting/Voting.sol b/contracts/Voting/Voting.sol index 5141b8e..171cdd0 100644 --- a/contracts/Voting/Voting.sol +++ b/contracts/Voting/Voting.sol @@ -96,7 +96,7 @@ contract Voting is VotingSnapshot, Initializable, HasRole { /** * @notice Hook called on every governance token transfer. - * @dev Only the governance token can call this method. + * @dev Called by GovernanceToken and ShareholderRegistry. * @param from The sender's address. * @param to The receiver's address. * @param amount The amount transferred. From ef47ca4c6791dbbf5f568e439daac35ea2c68ba6 Mon Sep 17 00:00:00 2001 From: Alberto Granzotto Date: Tue, 5 Sep 2023 13:59:49 +0200 Subject: [PATCH 3/5] Pin Solidity version 0.8.16 --- contracts/GovernanceToken/GovernanceToken.sol | 2 +- contracts/GovernanceToken/GovernanceTokenBase.sol | 2 +- contracts/GovernanceToken/GovernanceTokenSnapshot.sol | 2 +- contracts/GovernanceToken/IGovernanceToken.sol | 2 +- contracts/InternalMarket/InternalMarket.sol | 2 +- contracts/InternalMarket/InternalMarketBase.sol | 2 +- contracts/NeokingdomToken/INeokingdomToken.sol | 2 +- contracts/NeokingdomToken/NeokingdomToken.sol | 2 +- contracts/PriceOracle/IStdReference.sol | 2 +- contracts/PriceOracle/PriceOracle.sol | 2 +- contracts/RedemptionController/IRedemptionController.sol | 2 +- contracts/RedemptionController/RedemptionController.sol | 2 +- contracts/RedemptionController/RedemptionControllerBase.sol | 2 +- contracts/ResolutionManager/ResolutionManager.sol | 2 +- contracts/ResolutionManager/ResolutionManagerBase.sol | 2 +- contracts/ShareholderRegistry/IShareholderRegistry.sol | 2 +- contracts/ShareholderRegistry/ShareholderRegistry.sol | 2 +- contracts/ShareholderRegistry/ShareholderRegistryBase.sol | 2 +- contracts/ShareholderRegistry/ShareholderRegistrySnapshot.sol | 2 +- contracts/Voting/IVoting.sol | 2 +- contracts/Voting/Voting.sol | 2 +- contracts/Voting/VotingBase.sol | 2 +- contracts/Voting/VotingSnapshot.sol | 2 +- contracts/extensions/DAORoles.sol | 2 +- contracts/extensions/HasRole.sol | 2 +- contracts/extensions/ISnapshot.sol | 2 +- contracts/extensions/Roles.sol | 2 +- contracts/extensions/Snapshottable.sol | 2 +- contracts/mocks/ERC20Mock.sol | 2 +- contracts/mocks/HasRoleMock.sol | 2 +- contracts/mocks/NeokingdomTokenMock.sol | 2 +- contracts/mocks/NeokingdomTokenV2Mock.sol | 2 +- contracts/mocks/NewTelediskoTokenMock.sol | 2 +- contracts/mocks/ResolutionExecutorMock.sol | 2 +- contracts/mocks/ResolutionManagerV2Mock.sol | 2 +- contracts/mocks/ShareholderRegistryMock.sol | 2 +- contracts/mocks/TokenMock.sol | 2 +- contracts/mocks/VotingMock.sol | 2 +- echidna/proxies/InternalMarketProxy.sol | 2 +- echidna/proxies/RedemptionControllerProxy.sol | 2 +- echidna/proxies/TokenMock.sol | 2 +- 41 files changed, 41 insertions(+), 41 deletions(-) diff --git a/contracts/GovernanceToken/GovernanceToken.sol b/contracts/GovernanceToken/GovernanceToken.sol index da45042..edce1dc 100644 --- a/contracts/GovernanceToken/GovernanceToken.sol +++ b/contracts/GovernanceToken/GovernanceToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; diff --git a/contracts/GovernanceToken/GovernanceTokenBase.sol b/contracts/GovernanceToken/GovernanceTokenBase.sol index 5082437..fe33fcc 100644 --- a/contracts/GovernanceToken/GovernanceTokenBase.sol +++ b/contracts/GovernanceToken/GovernanceTokenBase.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import "../RedemptionController/IRedemptionController.sol"; diff --git a/contracts/GovernanceToken/GovernanceTokenSnapshot.sol b/contracts/GovernanceToken/GovernanceTokenSnapshot.sol index a12400c..0bab57e 100644 --- a/contracts/GovernanceToken/GovernanceTokenSnapshot.sol +++ b/contracts/GovernanceToken/GovernanceTokenSnapshot.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts/utils/Arrays.sol"; import "./IGovernanceToken.sol"; diff --git a/contracts/GovernanceToken/IGovernanceToken.sol b/contracts/GovernanceToken/IGovernanceToken.sol index 47d96d2..e910116 100644 --- a/contracts/GovernanceToken/IGovernanceToken.sol +++ b/contracts/GovernanceToken/IGovernanceToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "../extensions/ISnapshot.sol"; diff --git a/contracts/InternalMarket/InternalMarket.sol b/contracts/InternalMarket/InternalMarket.sol index 1a445bd..05d00ed 100644 --- a/contracts/InternalMarket/InternalMarket.sol +++ b/contracts/InternalMarket/InternalMarket.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; diff --git a/contracts/InternalMarket/InternalMarketBase.sol b/contracts/InternalMarket/InternalMarketBase.sol index 6701df0..f449b45 100644 --- a/contracts/InternalMarket/InternalMarketBase.sol +++ b/contracts/InternalMarket/InternalMarketBase.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "../ShareholderRegistry/IShareholderRegistry.sol"; diff --git a/contracts/NeokingdomToken/INeokingdomToken.sol b/contracts/NeokingdomToken/INeokingdomToken.sol index 10c2608..aeea5a4 100644 --- a/contracts/NeokingdomToken/INeokingdomToken.sol +++ b/contracts/NeokingdomToken/INeokingdomToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; diff --git a/contracts/NeokingdomToken/NeokingdomToken.sol b/contracts/NeokingdomToken/NeokingdomToken.sol index 9989a0a..e2dd53e 100644 --- a/contracts/NeokingdomToken/NeokingdomToken.sol +++ b/contracts/NeokingdomToken/NeokingdomToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; diff --git a/contracts/PriceOracle/IStdReference.sol b/contracts/PriceOracle/IStdReference.sol index aad6a6c..8c62e1f 100644 --- a/contracts/PriceOracle/IStdReference.sol +++ b/contracts/PriceOracle/IStdReference.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; interface IStdReference { /// A structure returned whenever someone requests for standard reference data. diff --git a/contracts/PriceOracle/PriceOracle.sol b/contracts/PriceOracle/PriceOracle.sol index 3d45253..fea52c1 100644 --- a/contracts/PriceOracle/PriceOracle.sol +++ b/contracts/PriceOracle/PriceOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "./IStdReference.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; diff --git a/contracts/RedemptionController/IRedemptionController.sol b/contracts/RedemptionController/IRedemptionController.sol index d219a5d..9b23419 100644 --- a/contracts/RedemptionController/IRedemptionController.sol +++ b/contracts/RedemptionController/IRedemptionController.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; diff --git a/contracts/RedemptionController/RedemptionController.sol b/contracts/RedemptionController/RedemptionController.sol index 076bc75..155c6cc 100644 --- a/contracts/RedemptionController/RedemptionController.sol +++ b/contracts/RedemptionController/RedemptionController.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./RedemptionControllerBase.sol"; diff --git a/contracts/RedemptionController/RedemptionControllerBase.sol b/contracts/RedemptionController/RedemptionControllerBase.sol index 69883ea..40e7f03 100644 --- a/contracts/RedemptionController/RedemptionControllerBase.sol +++ b/contracts/RedemptionController/RedemptionControllerBase.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "./IRedemptionController.sol"; diff --git a/contracts/ResolutionManager/ResolutionManager.sol b/contracts/ResolutionManager/ResolutionManager.sol index e884cd6..0ef7e19 100644 --- a/contracts/ResolutionManager/ResolutionManager.sol +++ b/contracts/ResolutionManager/ResolutionManager.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import { Roles } from "../extensions/Roles.sol"; diff --git a/contracts/ResolutionManager/ResolutionManagerBase.sol b/contracts/ResolutionManager/ResolutionManagerBase.sol index 323e078..3fb760e 100644 --- a/contracts/ResolutionManager/ResolutionManagerBase.sol +++ b/contracts/ResolutionManager/ResolutionManagerBase.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "../ShareholderRegistry/IShareholderRegistry.sol"; import "../GovernanceToken/IGovernanceToken.sol"; diff --git a/contracts/ShareholderRegistry/IShareholderRegistry.sol b/contracts/ShareholderRegistry/IShareholderRegistry.sol index 224db9e..bde3f59 100644 --- a/contracts/ShareholderRegistry/IShareholderRegistry.sol +++ b/contracts/ShareholderRegistry/IShareholderRegistry.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "../extensions/ISnapshot.sol"; diff --git a/contracts/ShareholderRegistry/ShareholderRegistry.sol b/contracts/ShareholderRegistry/ShareholderRegistry.sol index 735c36d..42265d2 100644 --- a/contracts/ShareholderRegistry/ShareholderRegistry.sol +++ b/contracts/ShareholderRegistry/ShareholderRegistry.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./ShareholderRegistrySnapshot.sol"; diff --git a/contracts/ShareholderRegistry/ShareholderRegistryBase.sol b/contracts/ShareholderRegistry/ShareholderRegistryBase.sol index 49b877d..9df6737 100644 --- a/contracts/ShareholderRegistry/ShareholderRegistryBase.sol +++ b/contracts/ShareholderRegistry/ShareholderRegistryBase.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import "@openzeppelin/contracts/utils/Address.sol"; diff --git a/contracts/ShareholderRegistry/ShareholderRegistrySnapshot.sol b/contracts/ShareholderRegistry/ShareholderRegistrySnapshot.sol index df81a44..84ee78b 100644 --- a/contracts/ShareholderRegistry/ShareholderRegistrySnapshot.sol +++ b/contracts/ShareholderRegistry/ShareholderRegistrySnapshot.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "./ShareholderRegistryBase.sol"; import "../extensions/Snapshottable.sol"; diff --git a/contracts/Voting/IVoting.sol b/contracts/Voting/IVoting.sol index 4f60874..cab918a 100644 --- a/contracts/Voting/IVoting.sol +++ b/contracts/Voting/IVoting.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "../extensions/ISnapshot.sol"; diff --git a/contracts/Voting/Voting.sol b/contracts/Voting/Voting.sol index 171cdd0..000df4f 100644 --- a/contracts/Voting/Voting.sol +++ b/contracts/Voting/Voting.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "../ShareholderRegistry/IShareholderRegistry.sol"; diff --git a/contracts/Voting/VotingBase.sol b/contracts/Voting/VotingBase.sol index 2cb6667..fc37a67 100644 --- a/contracts/Voting/VotingBase.sol +++ b/contracts/Voting/VotingBase.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "../ShareholderRegistry/IShareholderRegistry.sol"; diff --git a/contracts/Voting/VotingSnapshot.sol b/contracts/Voting/VotingSnapshot.sol index 2b6b407..35c3ac1 100644 --- a/contracts/Voting/VotingSnapshot.sol +++ b/contracts/Voting/VotingSnapshot.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts/utils/Arrays.sol"; import "../extensions/Snapshottable.sol"; diff --git a/contracts/extensions/DAORoles.sol b/contracts/extensions/DAORoles.sol index fdfe27a..7d2d9c8 100644 --- a/contracts/extensions/DAORoles.sol +++ b/contracts/extensions/DAORoles.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts/access/AccessControl.sol"; diff --git a/contracts/extensions/HasRole.sol b/contracts/extensions/HasRole.sol index ae23559..2c760d6 100644 --- a/contracts/extensions/HasRole.sol +++ b/contracts/extensions/HasRole.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; diff --git a/contracts/extensions/ISnapshot.sol b/contracts/extensions/ISnapshot.sol index c98c272..0b639ad 100644 --- a/contracts/extensions/ISnapshot.sol +++ b/contracts/extensions/ISnapshot.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; interface ISnapshot { function snapshot() external returns (uint256); diff --git a/contracts/extensions/Roles.sol b/contracts/extensions/Roles.sol index 257c19e..5ca5b28 100644 --- a/contracts/extensions/Roles.sol +++ b/contracts/extensions/Roles.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; library Roles { bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE"); diff --git a/contracts/extensions/Snapshottable.sol b/contracts/extensions/Snapshottable.sol index 96eca8f..3bd7017 100644 --- a/contracts/extensions/Snapshottable.sol +++ b/contracts/extensions/Snapshottable.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts/utils/Arrays.sol"; diff --git a/contracts/mocks/ERC20Mock.sol b/contracts/mocks/ERC20Mock.sol index bf5cd38..61e1b11 100644 --- a/contracts/mocks/ERC20Mock.sol +++ b/contracts/mocks/ERC20Mock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; diff --git a/contracts/mocks/HasRoleMock.sol b/contracts/mocks/HasRoleMock.sol index 6e5bdf7..65912c8 100644 --- a/contracts/mocks/HasRoleMock.sol +++ b/contracts/mocks/HasRoleMock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "../extensions/HasRole.sol"; diff --git a/contracts/mocks/NeokingdomTokenMock.sol b/contracts/mocks/NeokingdomTokenMock.sol index 8209f4b..71ffc0f 100644 --- a/contracts/mocks/NeokingdomTokenMock.sol +++ b/contracts/mocks/NeokingdomTokenMock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; contract GovernanceTokenMock { mapping(address => uint256) mockResult_balanceOfAt; diff --git a/contracts/mocks/NeokingdomTokenV2Mock.sol b/contracts/mocks/NeokingdomTokenV2Mock.sol index 07e1d30..b65d5f3 100644 --- a/contracts/mocks/NeokingdomTokenV2Mock.sol +++ b/contracts/mocks/NeokingdomTokenV2Mock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "../GovernanceToken/GovernanceToken.sol"; import "../extensions/Roles.sol"; diff --git a/contracts/mocks/NewTelediskoTokenMock.sol b/contracts/mocks/NewTelediskoTokenMock.sol index 2a7aa38..fe4d3cb 100644 --- a/contracts/mocks/NewTelediskoTokenMock.sol +++ b/contracts/mocks/NewTelediskoTokenMock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts/utils/Arrays.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; diff --git a/contracts/mocks/ResolutionExecutorMock.sol b/contracts/mocks/ResolutionExecutorMock.sol index 6f97a8e..a9dabb8 100644 --- a/contracts/mocks/ResolutionExecutorMock.sol +++ b/contracts/mocks/ResolutionExecutorMock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; contract ResolutionExecutorMock { event MockExecutionSimple(uint256 a); diff --git a/contracts/mocks/ResolutionManagerV2Mock.sol b/contracts/mocks/ResolutionManagerV2Mock.sol index 4e0c5c2..4f60444 100644 --- a/contracts/mocks/ResolutionManagerV2Mock.sol +++ b/contracts/mocks/ResolutionManagerV2Mock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "../ResolutionManager/ResolutionManager.sol"; import "../extensions/Roles.sol"; diff --git a/contracts/mocks/ShareholderRegistryMock.sol b/contracts/mocks/ShareholderRegistryMock.sol index 171a01b..9c909f7 100644 --- a/contracts/mocks/ShareholderRegistryMock.sol +++ b/contracts/mocks/ShareholderRegistryMock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "../ShareholderRegistry/IShareholderRegistry.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; diff --git a/contracts/mocks/TokenMock.sol b/contracts/mocks/TokenMock.sol index c97b39b..c6f0b2c 100644 --- a/contracts/mocks/TokenMock.sol +++ b/contracts/mocks/TokenMock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; diff --git a/contracts/mocks/VotingMock.sol b/contracts/mocks/VotingMock.sol index 0cef53c..8634780 100644 --- a/contracts/mocks/VotingMock.sol +++ b/contracts/mocks/VotingMock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; contract VotingMock { event AfterTokenTransferCalled(address from, address to, uint256 amount); diff --git a/echidna/proxies/InternalMarketProxy.sol b/echidna/proxies/InternalMarketProxy.sol index 361d61a..cf31924 100644 --- a/echidna/proxies/InternalMarketProxy.sol +++ b/echidna/proxies/InternalMarketProxy.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "./TokenMock.sol"; import "../../contracts/InternalMarket/InternalMarket.sol"; diff --git a/echidna/proxies/RedemptionControllerProxy.sol b/echidna/proxies/RedemptionControllerProxy.sol index 2f1c9d9..213e626 100644 --- a/echidna/proxies/RedemptionControllerProxy.sol +++ b/echidna/proxies/RedemptionControllerProxy.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "../../contracts/RedemptionController/RedemptionController.sol"; diff --git a/echidna/proxies/TokenMock.sol b/echidna/proxies/TokenMock.sol index 0ddea86..33cdbb4 100644 --- a/echidna/proxies/TokenMock.sol +++ b/echidna/proxies/TokenMock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.16; +pragma solidity 0.8.16; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; From 62528762063efc13f001940b1dc16d4cab301228 Mon Sep 17 00:00:00 2001 From: Nicola Miotto Date: Tue, 12 Sep 2023 10:59:58 +0200 Subject: [PATCH 4/5] add tests triggering bug #119 --- test/GovernanceToken.ts | 13 +++++++++++-- test/Integration.ts | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/test/GovernanceToken.ts b/test/GovernanceToken.ts index e36e07b..30747fe 100644 --- a/test/GovernanceToken.ts +++ b/test/GovernanceToken.ts @@ -105,6 +105,7 @@ describe("GovernanceToken", () => { shareholderRegistry.isAtLeast.reset(); neokingdomToken.transfer.reset(); neokingdomToken.transferFrom.reset(); + neokingdomToken.mint.reset(); }); describe("transfer hooks", async () => { @@ -262,7 +263,7 @@ describe("GovernanceToken", () => { "GovernanceToken: transfer failed" ); }); - + it("should fail wrapping 0 tokens", async () => { await expect( governanceToken.connect(contributor).wrap(contributor.address, 0) @@ -400,7 +401,7 @@ describe("GovernanceToken", () => { expect(result).equal(41); }); - it("should only not mint non cooled tokens", async () => { + it("should not mint non cooled tokens", async () => { await governanceToken.wrap(contributor.address, 42); await governanceToken.settleTokens(contributor.address); @@ -442,6 +443,14 @@ describe("GovernanceToken", () => { await governanceToken.settleTokens(contributor.address); expect(redemption.afterMint).not.called; }); + + it("should not mint an equivalent amount of neok tokens to the governance contract", async () => { + await governanceToken.wrap(contributor.address, 42); + await timeTravel(7); + await governanceToken.settleTokens(contributor.address); + + expect(neokingdomToken.mint).to.not.have.been.called; + }); }); }); diff --git a/test/Integration.ts b/test/Integration.ts index c36708d..eb15ec9 100644 --- a/test/Integration.ts +++ b/test/Integration.ts @@ -1332,6 +1332,13 @@ describe("Integration", async () => { }); it("back and forth NEOK <-> Governance", async () => { + async function _expectWrapped(count: number) { + let wrappedNEOKs = await neokingdomToken.balanceOf( + governanceToken.address + ); + expect(wrappedNEOKs).equal(count); + } + await governanceToken.setSettlementPeriod(3600 * 24 * 7); const share = parseEther("1"); await shareholderRegistry.mint(user1.address, parseEther("1")); @@ -1339,18 +1346,25 @@ describe("Integration", async () => { await shareholderRegistry.setStatus(contributorStatus, user1.address); await shareholderRegistry.setStatus(contributorStatus, user2.address); + await _expectWrapped(0); + // 15 Governance Tokens to user2 await governanceToken.mint(user2.address, 15); + await _expectWrapped(15); + // 5 Governance tokens minted to user1 await governanceToken.mint(user1.address, 5); + await _expectWrapped(20); // user2 withdraws 10 Governance tokens to user1 await internalMarket.connect(user2).makeOffer(10); await timeTravel(7, true); await internalMarket.connect(user2).withdraw(user1.address, 10); + await _expectWrapped(10); // user1 deposit 4 NEOK await internalMarket.connect(user1).deposit(4); + await _expectWrapped(14); // user1 voting power is 5 expect(await voting.getVotingPower(user1.address)).equal(share.add(5)); // user1 offers 3 NEOK @@ -1365,6 +1379,7 @@ describe("Integration", async () => { ); // user1 deposit 3 NEOK await internalMarket.connect(user1).deposit(3); + await _expectWrapped(17); // user1 voting power is 2 expect(await voting.getVotingPower(user1.address)).equal(share.add(2)); // deposit is finalized @@ -1377,6 +1392,8 @@ describe("Integration", async () => { await governanceToken.settleTokens(user1.address); // user1 voting power is 9 expect(await voting.getVotingPower(user1.address)).equal(share.add(9)); + + await _expectWrapped(17); }); it("internal and external token amounts", async () => { From d139cd81b922490a7d64f561db311a607e0d4478 Mon Sep 17 00:00:00 2001 From: Alberto Granzotto Date: Fri, 15 Sep 2023 15:24:59 +0200 Subject: [PATCH 5/5] Fix #119 --- contracts/GovernanceToken/GovernanceToken.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/GovernanceToken/GovernanceToken.sol b/contracts/GovernanceToken/GovernanceToken.sol index edce1dc..33a69ff 100644 --- a/contracts/GovernanceToken/GovernanceToken.sol +++ b/contracts/GovernanceToken/GovernanceToken.sol @@ -368,7 +368,7 @@ contract GovernanceToken is Initializable, HasRole, GovernanceTokenSnapshot { DepositedTokens storage tokens = depositedTokens[from][i - 1]; if (block.timestamp >= tokens.settlementTimestamp) { if (tokens.amount > 0) { - _mint(from, tokens.amount); + ERC20Upgradeable._mint(from, tokens.amount); tokens.amount = 0; } else { break;