Commit 473aeda9 by github-actions

Transpile a56e3a72

parent fcda8652
# Changelog # Changelog
## Unreleased ## Unreleased
* `GovernorExtendedVoting`: add new module to ensure a minimum voting duration is available after the quorum is reached. ([#2973](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2973))
## Unreleased
* `GovernorTimelockControl`: improve the `state()` function to have it reflect cases where a proposal has been canceled directly on the timelock. ([#2977](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2977)) * `GovernorTimelockControl`: improve the `state()` function to have it reflect cases where a proposal has been canceled directly on the timelock. ([#2977](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2977))
* `Math`: add a `abs(int256)` method that returns the unsigned absolute value of a signed value. ([#2984](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2984)) * `Math`: add a `abs(int256)` method that returns the unsigned absolute value of a signed value. ([#2984](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2984))
......
...@@ -119,23 +119,36 @@ abstract contract GovernorUpgradeable is Initializable, ContextUpgradeable, ERC1 ...@@ -119,23 +119,36 @@ abstract contract GovernorUpgradeable is Initializable, ContextUpgradeable, ERC1
* @dev See {IGovernor-state}. * @dev See {IGovernor-state}.
*/ */
function state(uint256 proposalId) public view virtual override returns (ProposalState) { function state(uint256 proposalId) public view virtual override returns (ProposalState) {
ProposalCore memory proposal = _proposals[proposalId]; ProposalCore storage proposal = _proposals[proposalId];
if (proposal.executed) { if (proposal.executed) {
return ProposalState.Executed; return ProposalState.Executed;
} else if (proposal.canceled) { }
if (proposal.canceled) {
return ProposalState.Canceled; return ProposalState.Canceled;
} else if (proposal.voteStart.getDeadline() >= block.number) { }
uint256 snapshot = proposalSnapshot(proposalId);
if (snapshot == 0) {
revert("Governor: unknown proposal id");
}
if (snapshot >= block.number) {
return ProposalState.Pending; return ProposalState.Pending;
} else if (proposal.voteEnd.getDeadline() >= block.number) { }
uint256 deadline = proposalDeadline(proposalId);
if (deadline >= block.number) {
return ProposalState.Active; return ProposalState.Active;
} else if (proposal.voteEnd.isExpired()) { }
return
_quorumReached(proposalId) && _voteSucceeded(proposalId) if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) {
? ProposalState.Succeeded return ProposalState.Succeeded;
: ProposalState.Defeated;
} else { } else {
revert("Governor: unknown proposal id"); return ProposalState.Defeated;
} }
} }
......
...@@ -42,6 +42,8 @@ Other extensions can customize the behavior or interface in multiple ways. ...@@ -42,6 +42,8 @@ Other extensions can customize the behavior or interface in multiple ways.
* {GovernorSettings}: Manages some of the settings (voting delay, voting period duration, and proposal threshold) in a way that can be updated through a governance proposal, without requiering an upgrade. * {GovernorSettings}: Manages some of the settings (voting delay, voting period duration, and proposal threshold) in a way that can be updated through a governance proposal, without requiering an upgrade.
* {GovernorPreventLateQuorum}: Ensures there is a minimum voting period after quorum is reached as a security protection against large voters.
In addition to modules and extensions, the core contract requires a few virtual functions to be implemented to your particular specifications: In addition to modules and extensions, the core contract requires a few virtual functions to be implemented to your particular specifications:
* <<Governor-votingDelay-,`votingDelay()`>>: Delay (in number of blocks) since the proposal is submitted until voting power is fixed and voting starts. This can be used to enforce a delay after a proposal is published for users to buy tokens, or delegate their votes. * <<Governor-votingDelay-,`votingDelay()`>>: Delay (in number of blocks) since the proposal is submitted until voting power is fixed and voting starts. This can be used to enforce a delay after a proposal is published for users to buy tokens, or delegate their votes.
...@@ -74,6 +76,8 @@ NOTE: Functions of the `Governor` contract do not include access control. If you ...@@ -74,6 +76,8 @@ NOTE: Functions of the `Governor` contract do not include access control. If you
{{GovernorSettings}} {{GovernorSettings}}
{{GovernorPreventLateQuorum}}
{{GovernorCompatibilityBravo}} {{GovernorCompatibilityBravo}}
=== Deprecated === Deprecated
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../GovernorUpgradeable.sol";
import "../../utils/math/MathUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev A module that ensures there is a minimum voting period after quorum is reached. This prevents a large voter from
* swaying a vote and triggering quorum at the last minute, by ensuring there is always time for other voters to react
* and try to oppose the decision.
*
* If a vote causes quorum to be reached, the proposal's voting period may be extended so that it does not end before at
* least a given number of blocks have passed (the "vote extension" parameter). This parameter can be set by the
* governance executor (e.g. through a governance proposal).
*
* _Available since v4.5._
*/
abstract contract GovernorPreventLateQuorumUpgradeable is Initializable, GovernorUpgradeable {
using SafeCastUpgradeable for uint256;
using TimersUpgradeable for TimersUpgradeable.BlockNumber;
uint64 private _voteExtension;
mapping(uint256 => TimersUpgradeable.BlockNumber) private _extendedDeadlines;
/// @dev Emitted when a proposal deadline is pushed back due to reaching quorum late in its voting period.
event ProposalExtended(uint256 indexed proposalId, uint64 extendedDeadline);
/// @dev Emitted when the {lateQuorumVoteExtension} parameter is changed.
event LateQuorumVoteExtensionSet(uint64 oldVoteExtension, uint64 newVoteExtension);
/**
* @dev Initializes the vote extension parameter: the number of blocks that are required to pass since a proposal
* reaches quorum until its voting period ends. If necessary the voting period will be extended beyond the one set
* at proposal creation.
*/
function __GovernorPreventLateQuorum_init(uint64 initialVoteExtension) internal initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__EIP712_init_unchained(name_, version());
__IGovernor_init_unchained();
__GovernorPreventLateQuorum_init_unchained(initialVoteExtension);
}
function __GovernorPreventLateQuorum_init_unchained(uint64 initialVoteExtension) internal initializer {
_setLateQuorumVoteExtension(initialVoteExtension);
}
/**
* @dev Returns the proposal deadline, which may have been extended beyond that set at proposal creation, if the
* proposal reached quorum late in the voting period. See {Governor-proposalDeadline}.
*/
function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) {
return MathUpgradeable.max(super.proposalDeadline(proposalId), _extendedDeadlines[proposalId].getDeadline());
}
/**
* @dev Casts a vote and detects if it caused quorum to be reached, potentially extending the voting period. See
* {Governor-_castVote}.
*
* May emit a {ProposalExtended} event.
*/
function _castVote(
uint256 proposalId,
address account,
uint8 support,
string memory reason
) internal virtual override returns (uint256) {
uint256 result = super._castVote(proposalId, account, support, reason);
TimersUpgradeable.BlockNumber storage extendedDeadline = _extendedDeadlines[proposalId];
if (extendedDeadline.isUnset() && _quorumReached(proposalId)) {
uint64 extendedDeadlineValue = block.number.toUint64() + lateQuorumVoteExtension();
if (extendedDeadlineValue > proposalDeadline(proposalId)) {
emit ProposalExtended(proposalId, extendedDeadlineValue);
}
extendedDeadline.setDeadline(extendedDeadlineValue);
}
return result;
}
/**
* @dev Returns the current value of the vote extension parameter: the number of blocks that are required to pass
* from the time a proposal reaches quorum until its voting period ends.
*/
function lateQuorumVoteExtension() public view virtual returns (uint64) {
return _voteExtension;
}
/**
* @dev Changes the {lateQuorumVoteExtension}. This operation can only be performed by the governance executor,
* generally through a governance proposal.
*
* Emits a {LateQuorumVoteExtensionSet} event.
*/
function setLateQuorumVoteExtension(uint64 newVoteExtension) public virtual onlyGovernance {
_setLateQuorumVoteExtension(newVoteExtension);
}
/**
* @dev Changes the {lateQuorumVoteExtension}. This is an internal function that can be exposed in a public function
* like {setLateQuorumVoteExtension} if another access control mechanism is needed.
*
* Emits a {LateQuorumVoteExtensionSet} event.
*/
function _setLateQuorumVoteExtension(uint64 newVoteExtension) internal virtual {
emit LateQuorumVoteExtensionSet(_voteExtension, newVoteExtension);
_voteExtension = newVoteExtension;
}
uint256[48] private __gap;
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../governance/extensions/GovernorPreventLateQuorumUpgradeable.sol";
import "../governance/extensions/GovernorSettingsUpgradeable.sol";
import "../governance/extensions/GovernorCountingSimpleUpgradeable.sol";
import "../governance/extensions/GovernorVotesUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
contract GovernorPreventLateQuorumMockUpgradeable is
Initializable, GovernorSettingsUpgradeable,
GovernorVotesUpgradeable,
GovernorCountingSimpleUpgradeable,
GovernorPreventLateQuorumUpgradeable
{
uint256 private _quorum;
function __GovernorPreventLateQuorumMock_init(
string memory name_,
ERC20VotesUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 quorum_,
uint64 voteExtension_
) internal initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__EIP712_init_unchained(name_, version());
__IGovernor_init_unchained();
__Governor_init_unchained(name_);
__GovernorSettings_init_unchained(votingDelay_, votingPeriod_, 0);
__GovernorVotes_init_unchained(token_);
__GovernorCountingSimple_init_unchained();
__GovernorPreventLateQuorum_init_unchained(voteExtension_);
__GovernorPreventLateQuorumMock_init_unchained(name_, token_, votingDelay_, votingPeriod_, quorum_, voteExtension_);
}
function __GovernorPreventLateQuorumMock_init_unchained(
string memory name_,
ERC20VotesUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 quorum_,
uint64 voteExtension_
) internal initializer {
_quorum = quorum_;
}
function quorum(uint256) public view virtual override returns (uint256) {
return _quorum;
}
function proposalDeadline(uint256 proposalId)
public
view
virtual
override(GovernorUpgradeable, GovernorPreventLateQuorumUpgradeable)
returns (uint256)
{
return super.proposalDeadline(proposalId);
}
function proposalThreshold() public view virtual override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint256) {
return super.proposalThreshold();
}
function _castVote(
uint256 proposalId,
address account,
uint8 support,
string memory reason
) internal virtual override(GovernorUpgradeable, GovernorPreventLateQuorumUpgradeable) returns (uint256) {
return super._castVote(proposalId, account, support, reason);
}
uint256[49] private __gap;
}
...@@ -168,26 +168,141 @@ contract MathMockUpgradeableWithInit is MathMockUpgradeable { ...@@ -168,26 +168,141 @@ contract MathMockUpgradeableWithInit is MathMockUpgradeable {
__MathMock_init(); __MathMock_init();
} }
} }
import "../finance/VestingWalletUpgradeable.sol"; import "./GovernorPreventLateQuorumMockUpgradeable.sol";
contract VestingWalletUpgradeableWithInit is VestingWalletUpgradeable { contract GovernorPreventLateQuorumMockUpgradeableWithInit is GovernorPreventLateQuorumMockUpgradeable {
constructor( constructor(
address beneficiaryAddress, string memory name_,
uint64 startTimestamp, ERC20VotesUpgradeable token_,
uint64 durationSeconds uint256 votingDelay_,
uint256 votingPeriod_,
uint256 quorum_,
uint64 voteExtension_
) public payable { ) public payable {
__VestingWallet_init(beneficiaryAddress, startTimestamp, durationSeconds); __GovernorPreventLateQuorumMock_init(name_, token_, votingDelay_, votingPeriod_, quorum_, voteExtension_);
} }
} }
import "../token/ERC20/utils/TokenTimelockUpgradeable.sol"; import "./GovernorMockUpgradeable.sol";
contract TokenTimelockUpgradeableWithInit is TokenTimelockUpgradeable { contract GovernorMockUpgradeableWithInit is GovernorMockUpgradeable {
constructor( constructor(
IERC20Upgradeable token_, string memory name_,
address beneficiary_, ERC20VotesUpgradeable token_,
uint256 releaseTime_ uint256 votingDelay_,
uint256 votingPeriod_,
uint256 quorumNumerator_
) public payable { ) public payable {
__TokenTimelock_init(token_, beneficiary_, releaseTime_); __GovernorMock_init(name_, token_, votingDelay_, votingPeriod_, quorumNumerator_);
}
}
import "./SafeCastMockUpgradeable.sol";
contract SafeCastMockUpgradeableWithInit is SafeCastMockUpgradeable {
constructor() public payable {
__SafeCastMock_init();
}
}
import "./ERC1155ReceiverMockUpgradeable.sol";
contract ERC1155ReceiverMockUpgradeableWithInit is ERC1155ReceiverMockUpgradeable {
constructor(
bytes4 recRetval,
bool recReverts,
bytes4 batRetval,
bool batReverts
) public payable {
__ERC1155ReceiverMock_init(recRetval, recReverts, batRetval, batReverts);
}
}
import "../token/ERC1155/ERC1155Upgradeable.sol";
contract ERC1155UpgradeableWithInit is ERC1155Upgradeable {
constructor(string memory uri_) public payable {
__ERC1155_init(uri_);
}
}
import "../token/ERC1155/presets/ERC1155PresetMinterPauserUpgradeable.sol";
contract ERC1155PresetMinterPauserUpgradeableWithInit is ERC1155PresetMinterPauserUpgradeable {
constructor(string memory uri) public payable {
__ERC1155PresetMinterPauser_init(uri);
}
}
import "./AccessControlEnumerableMockUpgradeable.sol";
contract AccessControlEnumerableMockUpgradeableWithInit is AccessControlEnumerableMockUpgradeable {
constructor() public payable {
__AccessControlEnumerableMock_init();
}
}
import "./EnumerableSetMockUpgradeable.sol";
contract EnumerableBytes32SetMockUpgradeableWithInit is EnumerableBytes32SetMockUpgradeable {
constructor() public payable {
__EnumerableBytes32SetMock_init();
}
}
import "./EnumerableSetMockUpgradeable.sol";
contract EnumerableAddressSetMockUpgradeableWithInit is EnumerableAddressSetMockUpgradeable {
constructor() public payable {
__EnumerableAddressSetMock_init();
}
}
import "./EnumerableSetMockUpgradeable.sol";
contract EnumerableUintSetMockUpgradeableWithInit is EnumerableUintSetMockUpgradeable {
constructor() public payable {
__EnumerableUintSetMock_init();
}
}
import "./EnumerableMapMockUpgradeable.sol";
contract EnumerableMapMockUpgradeableWithInit is EnumerableMapMockUpgradeable {
constructor() public payable {
__EnumerableMapMock_init();
}
}
import "./PausableMockUpgradeable.sol";
contract PausableMockUpgradeableWithInit is PausableMockUpgradeable {
constructor() public payable {
__PausableMock_init();
}
}
import "./ERC721URIStorageMockUpgradeable.sol";
contract ERC721URIStorageMockUpgradeableWithInit is ERC721URIStorageMockUpgradeable {
constructor(string memory name, string memory symbol) public payable {
__ERC721URIStorageMock_init(name, symbol);
}
}
import "./ERC721MockUpgradeable.sol";
contract ERC721MockUpgradeableWithInit is ERC721MockUpgradeable {
constructor(string memory name, string memory symbol) public payable {
__ERC721Mock_init(name, symbol);
}
}
import "./ERC165CheckerMockUpgradeable.sol";
contract ERC165CheckerMockUpgradeableWithInit is ERC165CheckerMockUpgradeable {
constructor() public payable {
__ERC165CheckerMock_init();
}
}
import "./ERC165/ERC165InterfacesSupportedUpgradeable.sol";
contract SupportsInterfaceWithLookupMockUpgradeableWithInit is SupportsInterfaceWithLookupMockUpgradeable {
constructor() public payable {
__SupportsInterfaceWithLookupMock_init();
}
}
import "./ERC165/ERC165InterfacesSupportedUpgradeable.sol";
contract ERC165InterfacesSupportedUpgradeableWithInit is ERC165InterfacesSupportedUpgradeable {
constructor(bytes4[] memory interfaceIds) public payable {
__ERC165InterfacesSupported_init(interfaceIds);
} }
} }
import "./SafeERC20HelperUpgradeable.sol"; import "./SafeERC20HelperUpgradeable.sol";
...@@ -218,6 +333,46 @@ contract SafeERC20WrapperUpgradeableWithInit is SafeERC20WrapperUpgradeable { ...@@ -218,6 +333,46 @@ contract SafeERC20WrapperUpgradeableWithInit is SafeERC20WrapperUpgradeable {
__SafeERC20Wrapper_init(token); __SafeERC20Wrapper_init(token);
} }
} }
import "../token/ERC20/utils/TokenTimelockUpgradeable.sol";
contract TokenTimelockUpgradeableWithInit is TokenTimelockUpgradeable {
constructor(
IERC20Upgradeable token_,
address beneficiary_,
uint256 releaseTime_
) public payable {
__TokenTimelock_init(token_, beneficiary_, releaseTime_);
}
}
import "./ERC20WrapperMockUpgradeable.sol";
contract ERC20WrapperMockUpgradeableWithInit is ERC20WrapperMockUpgradeable {
constructor(
IERC20Upgradeable _underlyingToken,
string memory name,
string memory symbol
) public payable {
__ERC20WrapperMock_init(_underlyingToken, name, symbol);
}
}
import "../finance/VestingWalletUpgradeable.sol";
contract VestingWalletUpgradeableWithInit is VestingWalletUpgradeable {
constructor(
address beneficiaryAddress,
uint64 startTimestamp,
uint64 durationSeconds
) public payable {
__VestingWallet_init(beneficiaryAddress, startTimestamp, durationSeconds);
}
}
import "../finance/PaymentSplitterUpgradeable.sol";
contract PaymentSplitterUpgradeableWithInit is PaymentSplitterUpgradeable {
constructor(address[] memory payees, uint256[] memory shares_) public payable {
__PaymentSplitter_init(payees, shares_);
}
}
import "../token/ERC777/ERC777Upgradeable.sol"; import "../token/ERC777/ERC777Upgradeable.sol";
contract ERC777UpgradeableWithInit is ERC777Upgradeable { contract ERC777UpgradeableWithInit is ERC777Upgradeable {
...@@ -302,39 +457,46 @@ contract ERC20FlashMintMockUpgradeableWithInit is ERC20FlashMintMockUpgradeable ...@@ -302,39 +457,46 @@ contract ERC20FlashMintMockUpgradeableWithInit is ERC20FlashMintMockUpgradeable
__ERC20FlashMintMock_init(name, symbol, initialAccount, initialBalance); __ERC20FlashMintMock_init(name, symbol, initialAccount, initialBalance);
} }
} }
import "./ERC165CheckerMockUpgradeable.sol"; import "./ERC721EnumerableMockUpgradeable.sol";
contract ERC165CheckerMockUpgradeableWithInit is ERC165CheckerMockUpgradeable { contract ERC721EnumerableMockUpgradeableWithInit is ERC721EnumerableMockUpgradeable {
constructor(string memory name, string memory symbol) public payable {
__ERC721EnumerableMock_init(name, symbol);
}
}
import "./StringsMockUpgradeable.sol";
contract StringsMockUpgradeableWithInit is StringsMockUpgradeable {
constructor() public payable { constructor() public payable {
__ERC165CheckerMock_init(); __StringsMock_init();
} }
} }
import "./ERC165/ERC165InterfacesSupportedUpgradeable.sol"; import "../token/ERC721/utils/ERC721HolderUpgradeable.sol";
contract SupportsInterfaceWithLookupMockUpgradeableWithInit is SupportsInterfaceWithLookupMockUpgradeable { contract ERC721HolderUpgradeableWithInit is ERC721HolderUpgradeable {
constructor() public payable { constructor() public payable {
__SupportsInterfaceWithLookupMock_init(); __ERC721Holder_init();
} }
} }
import "./ERC165/ERC165InterfacesSupportedUpgradeable.sol"; import "./ERC721ReceiverMockUpgradeable.sol";
contract ERC165InterfacesSupportedUpgradeableWithInit is ERC165InterfacesSupportedUpgradeable { contract ERC721ReceiverMockUpgradeableWithInit is ERC721ReceiverMockUpgradeable {
constructor(bytes4[] memory interfaceIds) public payable { constructor(bytes4 retval, Error error) public payable {
__ERC165InterfacesSupported_init(interfaceIds); __ERC721ReceiverMock_init(retval, error);
} }
} }
import "./ERC721URIStorageMockUpgradeable.sol"; import "./ERC721BurnableMockUpgradeable.sol";
contract ERC721URIStorageMockUpgradeableWithInit is ERC721URIStorageMockUpgradeable { contract ERC721BurnableMockUpgradeableWithInit is ERC721BurnableMockUpgradeable {
constructor(string memory name, string memory symbol) public payable { constructor(string memory name, string memory symbol) public payable {
__ERC721URIStorageMock_init(name, symbol); __ERC721BurnableMock_init(name, symbol);
} }
} }
import "./PausableMockUpgradeable.sol"; import "./ERC721PausableMockUpgradeable.sol";
contract PausableMockUpgradeableWithInit is PausableMockUpgradeable { contract ERC721PausableMockUpgradeableWithInit is ERC721PausableMockUpgradeable {
constructor() public payable { constructor(string memory name, string memory symbol) public payable {
__PausableMock_init(); __ERC721PausableMock_init(name, symbol);
} }
} }
import "./ERC20PausableMockUpgradeable.sol"; import "./ERC20PausableMockUpgradeable.sol";
...@@ -349,60 +511,11 @@ contract ERC20PausableMockUpgradeableWithInit is ERC20PausableMockUpgradeable { ...@@ -349,60 +511,11 @@ contract ERC20PausableMockUpgradeableWithInit is ERC20PausableMockUpgradeable {
__ERC20PausableMock_init(name, symbol, initialAccount, initialBalance); __ERC20PausableMock_init(name, symbol, initialAccount, initialBalance);
} }
} }
import "../token/ERC1155/ERC1155Upgradeable.sol"; import "./ERC1155PausableMockUpgradeable.sol";
contract ERC1155UpgradeableWithInit is ERC1155Upgradeable {
constructor(string memory uri_) public payable {
__ERC1155_init(uri_);
}
}
import "../token/ERC1155/presets/ERC1155PresetMinterPauserUpgradeable.sol";
contract ERC1155PresetMinterPauserUpgradeableWithInit is ERC1155PresetMinterPauserUpgradeable {
constructor(string memory uri) public payable {
__ERC1155PresetMinterPauser_init(uri);
}
}
import "./AccessControlEnumerableMockUpgradeable.sol";
contract AccessControlEnumerableMockUpgradeableWithInit is AccessControlEnumerableMockUpgradeable {
constructor() public payable {
__AccessControlEnumerableMock_init();
}
}
import "./EnumerableSetMockUpgradeable.sol";
contract EnumerableBytes32SetMockUpgradeableWithInit is EnumerableBytes32SetMockUpgradeable {
constructor() public payable {
__EnumerableBytes32SetMock_init();
}
}
import "./EnumerableSetMockUpgradeable.sol";
contract EnumerableAddressSetMockUpgradeableWithInit is EnumerableAddressSetMockUpgradeable {
constructor() public payable {
__EnumerableAddressSetMock_init();
}
}
import "./EnumerableSetMockUpgradeable.sol";
contract EnumerableUintSetMockUpgradeableWithInit is EnumerableUintSetMockUpgradeable {
constructor() public payable {
__EnumerableUintSetMock_init();
}
}
import "./EnumerableMapMockUpgradeable.sol";
contract EnumerableMapMockUpgradeableWithInit is EnumerableMapMockUpgradeable {
constructor() public payable {
__EnumerableMapMock_init();
}
}
import "./ERC1155SupplyMockUpgradeable.sol";
contract ERC1155SupplyMockUpgradeableWithInit is ERC1155SupplyMockUpgradeable { contract ERC1155PausableMockUpgradeableWithInit is ERC1155PausableMockUpgradeable {
constructor(string memory uri) public payable { constructor(string memory uri) public payable {
__ERC1155SupplyMock_init(uri); __ERC1155PausableMock_init(uri);
} }
} }
import "./ERC1155MockUpgradeable.sol"; import "./ERC1155MockUpgradeable.sol";
...@@ -412,23 +525,18 @@ contract ERC1155MockUpgradeableWithInit is ERC1155MockUpgradeable { ...@@ -412,23 +525,18 @@ contract ERC1155MockUpgradeableWithInit is ERC1155MockUpgradeable {
__ERC1155Mock_init(uri); __ERC1155Mock_init(uri);
} }
} }
import "./ERC1155PausableMockUpgradeable.sol"; import "./ERC1155SupplyMockUpgradeable.sol";
contract ERC1155PausableMockUpgradeableWithInit is ERC1155PausableMockUpgradeable { contract ERC1155SupplyMockUpgradeableWithInit is ERC1155SupplyMockUpgradeable {
constructor(string memory uri) public payable { constructor(string memory uri) public payable {
__ERC1155PausableMock_init(uri); __ERC1155SupplyMock_init(uri);
} }
} }
import "./ERC1155ReceiverMockUpgradeable.sol"; import "./ERC1155BurnableMockUpgradeable.sol";
contract ERC1155ReceiverMockUpgradeableWithInit is ERC1155ReceiverMockUpgradeable { contract ERC1155BurnableMockUpgradeableWithInit is ERC1155BurnableMockUpgradeable {
constructor( constructor(string memory uri) public payable {
bytes4 recRetval, __ERC1155BurnableMock_init(uri);
bool recReverts,
bytes4 batRetval,
bool batReverts
) public payable {
__ERC1155ReceiverMock_init(recRetval, recReverts, batRetval, batReverts);
} }
} }
import "../token/ERC1155/utils/ERC1155HolderUpgradeable.sol"; import "../token/ERC1155/utils/ERC1155HolderUpgradeable.sol";
...@@ -452,26 +560,6 @@ contract ERC165MockUpgradeableWithInit is ERC165MockUpgradeable { ...@@ -452,26 +560,6 @@ contract ERC165MockUpgradeableWithInit is ERC165MockUpgradeable {
__ERC165Mock_init(); __ERC165Mock_init();
} }
} }
import "./GovernorMockUpgradeable.sol";
contract GovernorMockUpgradeableWithInit is GovernorMockUpgradeable {
constructor(
string memory name_,
ERC20VotesUpgradeable token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 quorumNumerator_
) public payable {
__GovernorMock_init(name_, token_, votingDelay_, votingPeriod_, quorumNumerator_);
}
}
import "./SafeCastMockUpgradeable.sol";
contract SafeCastMockUpgradeableWithInit is SafeCastMockUpgradeable {
constructor() public payable {
__SafeCastMock_init();
}
}
import "./TimersTimestampImplUpgradeable.sol"; import "./TimersTimestampImplUpgradeable.sol";
contract TimersTimestampImplUpgradeableWithInit is TimersTimestampImplUpgradeable { contract TimersTimestampImplUpgradeableWithInit is TimersTimestampImplUpgradeable {
...@@ -512,80 +600,6 @@ contract ERC20PermitMockUpgradeableWithInit is ERC20PermitMockUpgradeable { ...@@ -512,80 +600,6 @@ contract ERC20PermitMockUpgradeableWithInit is ERC20PermitMockUpgradeable {
__ERC20PermitMock_init(name, symbol, initialAccount, initialBalance); __ERC20PermitMock_init(name, symbol, initialAccount, initialBalance);
} }
} }
import "./ERC1155BurnableMockUpgradeable.sol";
contract ERC1155BurnableMockUpgradeableWithInit is ERC1155BurnableMockUpgradeable {
constructor(string memory uri) public payable {
__ERC1155BurnableMock_init(uri);
}
}
import "./ERC721PausableMockUpgradeable.sol";
contract ERC721PausableMockUpgradeableWithInit is ERC721PausableMockUpgradeable {
constructor(string memory name, string memory symbol) public payable {
__ERC721PausableMock_init(name, symbol);
}
}
import "./ERC721MockUpgradeable.sol";
contract ERC721MockUpgradeableWithInit is ERC721MockUpgradeable {
constructor(string memory name, string memory symbol) public payable {
__ERC721Mock_init(name, symbol);
}
}
import "./ERC721EnumerableMockUpgradeable.sol";
contract ERC721EnumerableMockUpgradeableWithInit is ERC721EnumerableMockUpgradeable {
constructor(string memory name, string memory symbol) public payable {
__ERC721EnumerableMock_init(name, symbol);
}
}
import "./StringsMockUpgradeable.sol";
contract StringsMockUpgradeableWithInit is StringsMockUpgradeable {
constructor() public payable {
__StringsMock_init();
}
}
import "../token/ERC721/utils/ERC721HolderUpgradeable.sol";
contract ERC721HolderUpgradeableWithInit is ERC721HolderUpgradeable {
constructor() public payable {
__ERC721Holder_init();
}
}
import "./ERC721ReceiverMockUpgradeable.sol";
contract ERC721ReceiverMockUpgradeableWithInit is ERC721ReceiverMockUpgradeable {
constructor(bytes4 retval, Error error) public payable {
__ERC721ReceiverMock_init(retval, error);
}
}
import "./ERC721BurnableMockUpgradeable.sol";
contract ERC721BurnableMockUpgradeableWithInit is ERC721BurnableMockUpgradeable {
constructor(string memory name, string memory symbol) public payable {
__ERC721BurnableMock_init(name, symbol);
}
}
import "./ERC20WrapperMockUpgradeable.sol";
contract ERC20WrapperMockUpgradeableWithInit is ERC20WrapperMockUpgradeable {
constructor(
IERC20Upgradeable _underlyingToken,
string memory name,
string memory symbol
) public payable {
__ERC20WrapperMock_init(_underlyingToken, name, symbol);
}
}
import "../finance/PaymentSplitterUpgradeable.sol";
contract PaymentSplitterUpgradeableWithInit is PaymentSplitterUpgradeable {
constructor(address[] memory payees, uint256[] memory shares_) public payable {
__PaymentSplitter_init(payees, shares_);
}
}
import "./ArraysImplUpgradeable.sol"; import "./ArraysImplUpgradeable.sol";
contract ArraysImplUpgradeableWithInit is ArraysImplUpgradeable { contract ArraysImplUpgradeableWithInit is ArraysImplUpgradeable {
......
...@@ -65,7 +65,7 @@ function runGovernorWorkflow () { ...@@ -65,7 +65,7 @@ function runGovernorWorkflow () {
// vote // vote
if (tryGet(this.settings, 'voters')) { if (tryGet(this.settings, 'voters')) {
this.receipts.castVote = []; this.receipts.castVote = [];
for (const voter of this.settings.voters) { for (const voter of this.settings.voters.filter(({ support }) => !!support)) {
if (!voter.signature) { if (!voter.signature) {
this.receipts.castVote.push( this.receipts.castVote.push(
await getReceiptOrRevert( await getReceiptOrRevert(
......
const { BN, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers');
const Enums = require('../../helpers/enums');
const {
runGovernorWorkflow,
} = require('../GovernorWorkflow.behavior');
const Token = artifacts.require('ERC20VotesCompMock');
const Governor = artifacts.require('GovernorPreventLateQuorumMock');
const CallReceiver = artifacts.require('CallReceiverMock');
contract('GovernorPreventLateQuorum', function (accounts) {
const [ owner, proposer, voter1, voter2, voter3, voter4 ] = accounts;
const name = 'OZ-Governor';
// const version = '1';
const tokenName = 'MockToken';
const tokenSymbol = 'MTKN';
const tokenSupply = web3.utils.toWei('100');
const votingDelay = new BN(4);
const votingPeriod = new BN(16);
const lateQuorumVoteExtension = new BN(8);
const quorum = web3.utils.toWei('1');
beforeEach(async function () {
this.owner = owner;
this.token = await Token.new(tokenName, tokenSymbol);
this.mock = await Governor.new(
name,
this.token.address,
votingDelay,
votingPeriod,
quorum,
lateQuorumVoteExtension,
);
this.receiver = await CallReceiver.new();
await this.token.mint(owner, tokenSupply);
await this.token.delegate(voter1, { from: voter1 });
await this.token.delegate(voter2, { from: voter2 });
await this.token.delegate(voter3, { from: voter3 });
await this.token.delegate(voter4, { from: voter4 });
});
it('deployment check', async function () {
expect(await this.mock.name()).to.be.equal(name);
expect(await this.mock.token()).to.be.equal(this.token.address);
expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay);
expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod);
expect(await this.mock.quorum(0)).to.be.bignumber.equal(quorum);
expect(await this.mock.lateQuorumVoteExtension()).to.be.bignumber.equal(lateQuorumVoteExtension);
});
describe('nominal is unaffected', function () {
beforeEach(async function () {
this.settings = {
proposal: [
[ this.receiver.address ],
[ 0 ],
[ this.receiver.contract.methods.mockFunction().encodeABI() ],
'<proposal description>',
],
proposer,
tokenHolder: owner,
voters: [
{ voter: voter1, weight: web3.utils.toWei('1'), support: Enums.VoteType.For, reason: 'This is nice' },
{ voter: voter2, weight: web3.utils.toWei('7'), support: Enums.VoteType.For },
{ voter: voter3, weight: web3.utils.toWei('5'), support: Enums.VoteType.Against },
{ voter: voter4, weight: web3.utils.toWei('2'), support: Enums.VoteType.Abstain },
],
};
});
afterEach(async function () {
expect(await this.mock.hasVoted(this.id, owner)).to.be.equal(false);
expect(await this.mock.hasVoted(this.id, voter1)).to.be.equal(true);
expect(await this.mock.hasVoted(this.id, voter2)).to.be.equal(true);
await this.mock.proposalVotes(this.id).then(result => {
for (const [key, value] of Object.entries(Enums.VoteType)) {
expect(result[`${key.toLowerCase()}Votes`]).to.be.bignumber.equal(
Object.values(this.settings.voters).filter(({ support }) => support === value).reduce(
(acc, { weight }) => acc.add(new BN(weight)),
new BN('0'),
),
);
}
});
const startBlock = new BN(this.receipts.propose.blockNumber).add(votingDelay);
const endBlock = new BN(this.receipts.propose.blockNumber).add(votingDelay).add(votingPeriod);
expect(await this.mock.proposalSnapshot(this.id)).to.be.bignumber.equal(startBlock);
expect(await this.mock.proposalDeadline(this.id)).to.be.bignumber.equal(endBlock);
expectEvent(
this.receipts.propose,
'ProposalCreated',
{
proposalId: this.id,
proposer,
targets: this.settings.proposal[0],
// values: this.settings.proposal[1].map(value => new BN(value)),
signatures: this.settings.proposal[2].map(() => ''),
calldatas: this.settings.proposal[2],
startBlock,
endBlock,
description: this.settings.proposal[3],
},
);
this.receipts.castVote.filter(Boolean).forEach(vote => {
const { voter } = vote.logs.find(Boolean).args;
expectEvent(
vote,
'VoteCast',
this.settings.voters.find(({ address }) => address === voter),
);
expectEvent.notEmitted(
vote,
'ProposalExtended',
);
});
expectEvent(
this.receipts.execute,
'ProposalExecuted',
{ proposalId: this.id },
);
await expectEvent.inTransaction(
this.receipts.execute.transactionHash,
this.receiver,
'MockFunctionCalled',
);
});
runGovernorWorkflow();
});
describe('Delay is extended to prevent last minute take-over', function () {
beforeEach(async function () {
this.settings = {
proposal: [
[ this.receiver.address ],
[ 0 ],
[ this.receiver.contract.methods.mockFunction().encodeABI() ],
'<proposal description>',
],
proposer,
tokenHolder: owner,
voters: [
{ voter: voter1, weight: web3.utils.toWei('0.2'), support: Enums.VoteType.Against },
{ voter: voter2, weight: web3.utils.toWei('1.0') }, // do not actually vote, only getting tokens
{ voter: voter3, weight: web3.utils.toWei('0.9') }, // do not actually vote, only getting tokens
],
steps: {
wait: { enable: false },
execute: { enable: false },
},
};
});
afterEach(async function () {
expect(await this.mock.state(this.id)).to.be.bignumber.equal(Enums.ProposalState.Active);
const startBlock = new BN(this.receipts.propose.blockNumber).add(votingDelay);
const endBlock = new BN(this.receipts.propose.blockNumber).add(votingDelay).add(votingPeriod);
expect(await this.mock.proposalSnapshot(this.id)).to.be.bignumber.equal(startBlock);
expect(await this.mock.proposalDeadline(this.id)).to.be.bignumber.equal(endBlock);
// wait until the vote is almost over
await time.advanceBlockTo(endBlock.subn(1));
expect(await this.mock.state(this.id)).to.be.bignumber.equal(Enums.ProposalState.Active);
// try to overtake the vote at the last minute
const tx = await this.mock.castVote(this.id, Enums.VoteType.For, { from: voter2 });
// vote duration is extended
const extendedBlock = new BN(tx.receipt.blockNumber).add(lateQuorumVoteExtension);
expect(await this.mock.proposalDeadline(this.id)).to.be.bignumber.equal(extendedBlock);
expectEvent(
tx,
'ProposalExtended',
{ proposalId: this.id, extendedDeadline: extendedBlock },
);
// vote is still active after expected end
await time.advanceBlockTo(endBlock.addn(1));
expect(await this.mock.state(this.id)).to.be.bignumber.equal(Enums.ProposalState.Active);
// Still possible to vote
await this.mock.castVote(this.id, Enums.VoteType.Against, { from: voter3 });
// proposal fails
await time.advanceBlockTo(extendedBlock.addn(1));
expect(await this.mock.state(this.id)).to.be.bignumber.equal(Enums.ProposalState.Defeated);
});
runGovernorWorkflow();
});
describe('setLateQuorumVoteExtension', function () {
beforeEach(async function () {
this.newVoteExtension = new BN(0); // disable voting delay extension
});
it('protected', async function () {
await expectRevert(
this.mock.setLateQuorumVoteExtension(this.newVoteExtension),
'Governor: onlyGovernance',
);
});
describe('using workflow', function () {
beforeEach(async function () {
this.settings = {
proposal: [
[ this.mock.address ],
[ web3.utils.toWei('0') ],
[ this.mock.contract.methods.setLateQuorumVoteExtension(this.newVoteExtension).encodeABI() ],
'<proposal description>',
],
proposer,
tokenHolder: owner,
voters: [
{ voter: voter1, weight: web3.utils.toWei('1.0'), support: Enums.VoteType.For },
],
};
});
afterEach(async function () {
expectEvent(
this.receipts.propose,
'ProposalCreated',
{ proposalId: this.id },
);
expectEvent(
this.receipts.execute,
'ProposalExecuted',
{ proposalId: this.id },
);
expectEvent(
this.receipts.execute,
'LateQuorumVoteExtensionSet',
{ oldVoteExtension: lateQuorumVoteExtension, newVoteExtension: this.newVoteExtension },
);
expect(await this.mock.lateQuorumVoteExtension()).to.be.bignumber.equal(this.newVoteExtension);
});
runGovernorWorkflow();
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment