Browse Source

Merge pull request #1 from OpenZeppelin/master

Synced Forked Repo
Michael Morami 3 years ago
parent
commit
f2c352366a
100 changed files with 952 additions and 295 deletions
  1. 18 3
      CHANGELOG.md
  2. 2 0
      SECURITY.md
  3. 1 0
      contracts/access/AccessControl.sol
  4. 7 22
      contracts/access/AccessControlEnumerable.sol
  5. 1 0
      contracts/access/IAccessControl.sol
  6. 1 0
      contracts/access/IAccessControlEnumerable.sol
  7. 1 0
      contracts/access/Ownable.sol
  8. 62 4
      contracts/finance/PaymentSplitter.sol
  9. 12 2
      contracts/finance/README.adoc
  10. 135 0
      contracts/finance/VestingWallet.sol
  11. 15 2
      contracts/governance/Governor.sol
  12. 10 6
      contracts/governance/IGovernor.sol
  13. 6 2
      contracts/governance/README.adoc
  14. 1 0
      contracts/governance/TimelockController.sol
  15. 3 18
      contracts/governance/compatibility/GovernorCompatibilityBravo.sol
  16. 1 5
      contracts/governance/compatibility/IGovernorCompatibilityBravo.sol
  17. 1 0
      contracts/governance/extensions/GovernorCountingSimple.sol
  18. 2 13
      contracts/governance/extensions/GovernorProposalThreshold.sol
  19. 114 0
      contracts/governance/extensions/GovernorSettings.sol
  20. 1 0
      contracts/governance/extensions/GovernorTimelockCompound.sol
  21. 1 0
      contracts/governance/extensions/GovernorTimelockControl.sol
  22. 1 0
      contracts/governance/extensions/GovernorVotes.sol
  23. 1 0
      contracts/governance/extensions/GovernorVotesComp.sol
  24. 1 0
      contracts/governance/extensions/GovernorVotesQuorumFraction.sol
  25. 1 0
      contracts/governance/extensions/IGovernorTimelock.sol
  26. 1 0
      contracts/interfaces/IERC1155.sol
  27. 1 0
      contracts/interfaces/IERC1155MetadataURI.sol
  28. 1 0
      contracts/interfaces/IERC1155Receiver.sol
  29. 1 0
      contracts/interfaces/IERC1271.sol
  30. 1 0
      contracts/interfaces/IERC1363.sol
  31. 1 0
      contracts/interfaces/IERC1363Receiver.sol
  32. 1 0
      contracts/interfaces/IERC1363Spender.sol
  33. 1 0
      contracts/interfaces/IERC165.sol
  34. 1 0
      contracts/interfaces/IERC1820Implementer.sol
  35. 1 0
      contracts/interfaces/IERC1820Registry.sol
  36. 1 0
      contracts/interfaces/IERC20.sol
  37. 1 0
      contracts/interfaces/IERC20Metadata.sol
  38. 1 0
      contracts/interfaces/IERC2981.sol
  39. 1 0
      contracts/interfaces/IERC3156.sol
  40. 1 0
      contracts/interfaces/IERC3156FlashBorrower.sol
  41. 1 0
      contracts/interfaces/IERC3156FlashLender.sol
  42. 1 0
      contracts/interfaces/IERC721.sol
  43. 1 0
      contracts/interfaces/IERC721Enumerable.sol
  44. 1 0
      contracts/interfaces/IERC721Metadata.sol
  45. 1 0
      contracts/interfaces/IERC721Receiver.sol
  46. 1 0
      contracts/interfaces/IERC777.sol
  47. 1 0
      contracts/interfaces/IERC777Recipient.sol
  48. 1 0
      contracts/interfaces/IERC777Sender.sol
  49. 1 0
      contracts/interfaces/draft-IERC2612.sol
  50. 1 0
      contracts/metatx/ERC2771Context.sol
  51. 1 0
      contracts/metatx/MinimalForwarder.sol
  52. 5 0
      contracts/mocks/ECDSAMock.sol
  53. 4 27
      contracts/mocks/ERC1155SupplyMock.sol
  54. 8 20
      contracts/mocks/GovernorCompMock.sol
  55. 18 23
      contracts/mocks/GovernorCompatibilityBravoMock.sol
  56. 27 17
      contracts/mocks/GovernorMock.sol
  57. 13 16
      contracts/mocks/GovernorTimelockCompoundMock.sol
  58. 13 16
      contracts/mocks/GovernorTimelockControlMock.sol
  59. 4 0
      contracts/mocks/MerkleProofWrapper.sol
  60. 96 0
      contracts/mocks/wizard/MyGovernor1.sol
  61. 102 0
      contracts/mocks/wizard/MyGovernor2.sol
  62. 105 0
      contracts/mocks/wizard/MyGovernor3.sol
  63. 1 0
      contracts/proxy/Clones.sol
  64. 1 0
      contracts/proxy/ERC1967/ERC1967Proxy.sol
  65. 1 0
      contracts/proxy/ERC1967/ERC1967Upgrade.sol
  66. 1 0
      contracts/proxy/Proxy.sol
  67. 1 0
      contracts/proxy/beacon/BeaconProxy.sol
  68. 1 0
      contracts/proxy/beacon/IBeacon.sol
  69. 1 0
      contracts/proxy/beacon/UpgradeableBeacon.sol
  70. 1 0
      contracts/proxy/transparent/ProxyAdmin.sol
  71. 1 0
      contracts/proxy/transparent/TransparentUpgradeableProxy.sol
  72. 1 0
      contracts/proxy/utils/Initializable.sol
  73. 1 0
      contracts/proxy/utils/UUPSUpgradeable.sol
  74. 1 0
      contracts/security/Pausable.sol
  75. 1 0
      contracts/security/PullPayment.sol
  76. 1 0
      contracts/security/ReentrancyGuard.sol
  77. 43 30
      contracts/token/ERC1155/ERC1155.sol
  78. 1 0
      contracts/token/ERC1155/IERC1155.sol
  79. 30 24
      contracts/token/ERC1155/IERC1155Receiver.sol
  80. 2 0
      contracts/token/ERC1155/README.adoc
  81. 1 0
      contracts/token/ERC1155/extensions/ERC1155Burnable.sol
  82. 1 0
      contracts/token/ERC1155/extensions/ERC1155Pausable.sol
  83. 16 43
      contracts/token/ERC1155/extensions/ERC1155Supply.sol
  84. 1 0
      contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol
  85. 1 0
      contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol
  86. 6 0
      contracts/token/ERC1155/utils/ERC1155Holder.sol
  87. 1 0
      contracts/token/ERC1155/utils/ERC1155Receiver.sol
  88. 1 0
      contracts/token/ERC20/ERC20.sol
  89. 1 0
      contracts/token/ERC20/IERC20.sol
  90. 1 0
      contracts/token/ERC20/extensions/ERC20Burnable.sol
  91. 1 0
      contracts/token/ERC20/extensions/ERC20Capped.sol
  92. 1 0
      contracts/token/ERC20/extensions/ERC20FlashMint.sol
  93. 1 0
      contracts/token/ERC20/extensions/ERC20Pausable.sol
  94. 1 0
      contracts/token/ERC20/extensions/ERC20Snapshot.sol
  95. 3 2
      contracts/token/ERC20/extensions/ERC20Votes.sol
  96. 1 0
      contracts/token/ERC20/extensions/ERC20VotesComp.sol
  97. 1 0
      contracts/token/ERC20/extensions/ERC20Wrapper.sol
  98. 1 0
      contracts/token/ERC20/extensions/IERC20Metadata.sol
  99. 1 0
      contracts/token/ERC20/extensions/draft-ERC20Permit.sol
  100. 1 0
      contracts/token/ERC20/extensions/draft-IERC20Permit.sol

+ 18 - 3
CHANGELOG.md

@@ -2,9 +2,24 @@
 
 
 ## Unreleased
 ## Unreleased
 
 
- * `Ownable`: add an internal `_transferOwnership(address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/#2568))
- * `AccessControl`: add internal `_grantRole(bytes32,address)` and `_revokeRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/#2568))
- * `AccessControl`: mark `_setupRole(bytes32,address)` as deprecated in favor of `_grantRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/#2568))
+ * `Ownable`: add an internal `_transferOwnership(address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568))
+ * `AccessControl`: add internal `_grantRole(bytes32,address)` and `_revokeRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568))
+ * `AccessControl`: mark `_setupRole(bytes32,address)` as deprecated in favor of `_grantRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568))
+ * `AccessControlEnumerable`: hook into `_grantRole(bytes32,address)` and `_revokeRole(bytes32,address)`. ([#2946](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2946))
+ * `EIP712`: cache `address(this)` to immutable storage to avoid potential issues if a vanilla contract is used in a delegatecall context. ([#2852](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2852))
+ * Add internal `_setApprovalForAll` to `ERC721` and `ERC1155`. ([#2834](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2834))
+ * `Governor`: shift vote start and end by one block to better match Compound's GovernorBravo and prevent voting at the Governor level if the voting snapshot is not ready. ([#2892](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2892))
+ * `GovernorSettings`: a new governor module that manages voting settings updatable through governance actions. ([#2904](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2904))
+ * `PaymentSplitter`: now supports ERC20 assets in addition to Ether. ([#2858](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2858))
+ * `ECDSA`: add a variant of `toEthSignedMessageHash` for arbitrary length message hashing. ([#2865](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2865))
+ * `MerkleProof`: add a `processProof` function that returns the rebuilt root hash given a leaf and a proof. ([#2841](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2841))
+ * `VestingWallet`: new contract that handles the vesting of Ether and ERC20 tokens following a customizable vesting schedule. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2748))
+ * `Governor`: enable receiving Ether when a Timelock contract is not used. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2849))
+ * `GovernorTimelockCompound`: fix ability to use Ether stored in the Timelock contract. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2849))
+
+## 4.3.3
+
+ * `ERC1155Supply`: Handle `totalSupply` changes by hooking into `_beforeTokenTransfer` to ensure consistency of balances and supply during `IERC1155Receiver.onERC1155Received` calls.
 
 
 ## 4.3.2 (2021-09-14)
 ## 4.3.2 (2021-09-14)
 
 

+ 2 - 0
SECURITY.md

@@ -11,6 +11,8 @@ The recommendation is to use the latest version available.
 | 2.5     | :white_check_mark:                   |
 | 2.5     | :white_check_mark:                   |
 | < 2.0   | :x:                                  |
 | < 2.0   | :x:                                  |
 
 
+Note that the Solidity language itself only guarantees security updates for the latest release.
+
 ## Reporting a Vulnerability
 ## Reporting a Vulnerability
 
 
 Please report any security issues you find to security@openzeppelin.org.
 Please report any security issues you find to security@openzeppelin.org.

+ 1 - 0
contracts/access/AccessControl.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (access/AccessControl.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 7 - 22
contracts/access/AccessControlEnumerable.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (access/AccessControlEnumerable.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
@@ -46,34 +47,18 @@ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessCon
     }
     }
 
 
     /**
     /**
-     * @dev Overload {grantRole} to track enumerable memberships
+     * @dev Overload {_grantRole} to track enumerable memberships
      */
      */
-    function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
-        super.grantRole(role, account);
+    function _grantRole(bytes32 role, address account) internal virtual override {
+        super._grantRole(role, account);
         _roleMembers[role].add(account);
         _roleMembers[role].add(account);
     }
     }
 
 
     /**
     /**
-     * @dev Overload {revokeRole} to track enumerable memberships
+     * @dev Overload {_revokeRole} to track enumerable memberships
      */
      */
-    function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
-        super.revokeRole(role, account);
+    function _revokeRole(bytes32 role, address account) internal virtual override {
+        super._revokeRole(role, account);
         _roleMembers[role].remove(account);
         _roleMembers[role].remove(account);
     }
     }
-
-    /**
-     * @dev Overload {renounceRole} to track enumerable memberships
-     */
-    function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
-        super.renounceRole(role, account);
-        _roleMembers[role].remove(account);
-    }
-
-    /**
-     * @dev Overload {_setupRole} to track enumerable memberships
-     */
-    function _setupRole(bytes32 role, address account) internal virtual override {
-        super._setupRole(role, account);
-        _roleMembers[role].add(account);
-    }
 }
 }

+ 1 - 0
contracts/access/IAccessControl.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (access/IAccessControl.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/access/IAccessControlEnumerable.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (access/IAccessControlEnumerable.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/access/Ownable.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (access/Ownable.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 62 - 4
contracts/finance/PaymentSplitter.sol

@@ -1,7 +1,9 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (finance/PaymentSplitter.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
+import "../token/ERC20/utils/SafeERC20.sol";
 import "../utils/Address.sol";
 import "../utils/Address.sol";
 import "../utils/Context.sol";
 import "../utils/Context.sol";
 
 
@@ -17,10 +19,15 @@ import "../utils/Context.sol";
  * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
  * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
  * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
  * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
  * function.
  * function.
+ *
+ * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and
+ * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you
+ * to run tests before sending real value to this contract.
  */
  */
 contract PaymentSplitter is Context {
 contract PaymentSplitter is Context {
     event PayeeAdded(address account, uint256 shares);
     event PayeeAdded(address account, uint256 shares);
     event PaymentReleased(address to, uint256 amount);
     event PaymentReleased(address to, uint256 amount);
+    event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount);
     event PaymentReceived(address from, uint256 amount);
     event PaymentReceived(address from, uint256 amount);
 
 
     uint256 private _totalShares;
     uint256 private _totalShares;
@@ -30,6 +37,9 @@ contract PaymentSplitter is Context {
     mapping(address => uint256) private _released;
     mapping(address => uint256) private _released;
     address[] private _payees;
     address[] private _payees;
 
 
+    mapping(IERC20 => uint256) private _erc20TotalReleased;
+    mapping(IERC20 => mapping(address => uint256)) private _erc20Released;
+
     /**
     /**
      * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
      * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
      * the matching position in the `shares` array.
      * the matching position in the `shares` array.
@@ -73,6 +83,14 @@ contract PaymentSplitter is Context {
         return _totalReleased;
         return _totalReleased;
     }
     }
 
 
+    /**
+     * @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20
+     * contract.
+     */
+    function totalReleased(IERC20 token) public view returns (uint256) {
+        return _erc20TotalReleased[token];
+    }
+
     /**
     /**
      * @dev Getter for the amount of shares held by an account.
      * @dev Getter for the amount of shares held by an account.
      */
      */
@@ -87,6 +105,14 @@ contract PaymentSplitter is Context {
         return _released[account];
         return _released[account];
     }
     }
 
 
+    /**
+     * @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an
+     * IERC20 contract.
+     */
+    function released(IERC20 token, address account) public view returns (uint256) {
+        return _erc20Released[token][account];
+    }
+
     /**
     /**
      * @dev Getter for the address of the payee number `index`.
      * @dev Getter for the address of the payee number `index`.
      */
      */
@@ -101,18 +127,50 @@ contract PaymentSplitter is Context {
     function release(address payable account) public virtual {
     function release(address payable account) public virtual {
         require(_shares[account] > 0, "PaymentSplitter: account has no shares");
         require(_shares[account] > 0, "PaymentSplitter: account has no shares");
 
 
-        uint256 totalReceived = address(this).balance + _totalReleased;
-        uint256 payment = (totalReceived * _shares[account]) / _totalShares - _released[account];
+        uint256 totalReceived = address(this).balance + totalReleased();
+        uint256 payment = _pendingPayment(account, totalReceived, released(account));
 
 
         require(payment != 0, "PaymentSplitter: account is not due payment");
         require(payment != 0, "PaymentSplitter: account is not due payment");
 
 
-        _released[account] = _released[account] + payment;
-        _totalReleased = _totalReleased + payment;
+        _released[account] += payment;
+        _totalReleased += payment;
 
 
         Address.sendValue(account, payment);
         Address.sendValue(account, payment);
         emit PaymentReleased(account, payment);
         emit PaymentReleased(account, payment);
     }
     }
 
 
+    /**
+     * @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their
+     * percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20
+     * contract.
+     */
+    function release(IERC20 token, address account) public virtual {
+        require(_shares[account] > 0, "PaymentSplitter: account has no shares");
+
+        uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token);
+        uint256 payment = _pendingPayment(account, totalReceived, released(token, account));
+
+        require(payment != 0, "PaymentSplitter: account is not due payment");
+
+        _erc20Released[token][account] += payment;
+        _erc20TotalReleased[token] += payment;
+
+        SafeERC20.safeTransfer(token, account, payment);
+        emit ERC20PaymentReleased(token, account, payment);
+    }
+
+    /**
+     * @dev internal logic for computing the pending payment of an `account` given the token historical balances and
+     * already released amounts.
+     */
+    function _pendingPayment(
+        address account,
+        uint256 totalReceived,
+        uint256 alreadyReleased
+    ) private view returns (uint256) {
+        return (totalReceived * _shares[account]) / _totalShares - alreadyReleased;
+    }
+
     /**
     /**
      * @dev Add a new payee to the contract.
      * @dev Add a new payee to the contract.
      * @param account The address of the payee to add.
      * @param account The address of the payee to add.

+ 12 - 2
contracts/finance/README.adoc

@@ -3,8 +3,18 @@
 [.readme-notice]
 [.readme-notice]
 NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/finance
 NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/finance
 
 
-This directory includes primitives for financial systems. We currently only offer the {PaymentSplitter} contract, but we want to grow this directory so we welcome ideas.
+This directory includes primitives for financial systems:
 
 
-== PaymentSplitter
+- {PaymentSplitter} allows to split Ether and ERC20 payments among a group of accounts. The sender does not need to be
+  aware that the assets will be split in this way, since it is handled transparently by the contract. The split can be
+  in equal parts or in any other arbitrary proportion.
+
+- {VestingWallet} handles the vesting of Ether and ERC20 tokens for a given beneficiary. Custody of multiple tokens can
+  be given to this contract, which will release the token to the beneficiary following a given, customizable, vesting
+  schedule.
+
+== Contracts
 
 
 {{PaymentSplitter}}
 {{PaymentSplitter}}
+
+{{VestingWallet}}

+ 135 - 0
contracts/finance/VestingWallet.sol

@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (finance/VestingWallet.sol)
+pragma solidity ^0.8.0;
+
+import "../token/ERC20/utils/SafeERC20.sol";
+import "../utils/Address.sol";
+import "../utils/Context.sol";
+import "../utils/math/Math.sol";
+
+/**
+ * @title VestingWallet
+ * @dev This contract handles the vesting of Eth and ERC20 tokens for a given beneficiary. Custody of multiple tokens
+ * can be given to this contract, which will release the token to the beneficiary following a given vesting schedule.
+ * The vesting schedule is customizable through the {vestedAmount} function.
+ *
+ * Any token transferred to this contract will follow the vesting schedule as if they were locked from the beginning.
+ * Consequently, if the vesting has already started, any amount of tokens sent to this contract will (at least partly)
+ * be immediately releasable.
+ */
+contract VestingWallet is Context {
+    event EtherReleased(uint256 amount);
+    event ERC20Released(address token, uint256 amount);
+
+    uint256 private _released;
+    mapping(address => uint256) private _erc20Released;
+    address private immutable _beneficiary;
+    uint64 private immutable _start;
+    uint64 private immutable _duration;
+
+    /**
+     * @dev Set the beneficiary, start timestamp and vesting duration of the vesting wallet.
+     */
+    constructor(
+        address beneficiaryAddress,
+        uint64 startTimestamp,
+        uint64 durationSeconds
+    ) {
+        require(beneficiaryAddress != address(0), "VestingWallet: beneficiary is zero address");
+        _beneficiary = beneficiaryAddress;
+        _start = startTimestamp;
+        _duration = durationSeconds;
+    }
+
+    /**
+     * @dev The contract should be able to receive Eth.
+     */
+    receive() external payable virtual {}
+
+    /**
+     * @dev Getter for the beneficiary address.
+     */
+    function beneficiary() public view virtual returns (address) {
+        return _beneficiary;
+    }
+
+    /**
+     * @dev Getter for the start timestamp.
+     */
+    function start() public view virtual returns (uint256) {
+        return _start;
+    }
+
+    /**
+     * @dev Getter for the vesting duration.
+     */
+    function duration() public view virtual returns (uint256) {
+        return _duration;
+    }
+
+    /**
+     * @dev Amount of eth already released
+     */
+    function released() public view virtual returns (uint256) {
+        return _released;
+    }
+
+    /**
+     * @dev Amount of token already released
+     */
+    function released(address token) public view virtual returns (uint256) {
+        return _erc20Released[token];
+    }
+
+    /**
+     * @dev Release the native token (ether) that have already vested.
+     *
+     * Emits a {TokensReleased} event.
+     */
+    function release() public virtual {
+        uint256 releasable = vestedAmount(uint64(block.timestamp)) - released();
+        _released += releasable;
+        emit EtherReleased(releasable);
+        Address.sendValue(payable(beneficiary()), releasable);
+    }
+
+    /**
+     * @dev Release the tokens that have already vested.
+     *
+     * Emits a {TokensReleased} event.
+     */
+    function release(address token) public virtual {
+        uint256 releasable = vestedAmount(token, uint64(block.timestamp)) - released(token);
+        _erc20Released[token] += releasable;
+        emit ERC20Released(token, releasable);
+        SafeERC20.safeTransfer(IERC20(token), beneficiary(), releasable);
+    }
+
+    /**
+     * @dev Calculates the amount of ether that has already vested. Default implementation is a linear vesting curve.
+     */
+    function vestedAmount(uint64 timestamp) public view virtual returns (uint256) {
+        return _vestingSchedule(address(this).balance + released(), timestamp);
+    }
+
+    /**
+     * @dev Calculates the amount of tokens that has already vested. Default implementation is a linear vesting curve.
+     */
+    function vestedAmount(address token, uint64 timestamp) public view virtual returns (uint256) {
+        return _vestingSchedule(IERC20(token).balanceOf(address(this)) + released(token), timestamp);
+    }
+
+    /**
+     * @dev Virtual implementation of the vesting formula. This returns the amout vested, as a function of time, for
+     * an asset given its total historical allocation.
+     */
+    function _vestingSchedule(uint256 totalAllocation, uint64 timestamp) internal view virtual returns (uint256) {
+        if (timestamp < start()) {
+            return 0;
+        } else if (timestamp > start() + duration()) {
+            return totalAllocation;
+        } else {
+            return (totalAllocation * (timestamp - start())) / duration();
+        }
+    }
+}

+ 15 - 2
contracts/governance/Governor.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/Governor.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
@@ -115,9 +116,9 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor {
             return ProposalState.Executed;
             return ProposalState.Executed;
         } else if (proposal.canceled) {
         } else if (proposal.canceled) {
             return ProposalState.Canceled;
             return ProposalState.Canceled;
-        } else if (proposal.voteStart.isPending()) {
+        } else if (proposal.voteStart.getDeadline() >= block.number) {
             return ProposalState.Pending;
             return ProposalState.Pending;
-        } else if (proposal.voteEnd.isPending()) {
+        } else if (proposal.voteEnd.getDeadline() >= block.number) {
             return ProposalState.Active;
             return ProposalState.Active;
         } else if (proposal.voteEnd.isExpired()) {
         } else if (proposal.voteEnd.isExpired()) {
             return
             return
@@ -143,6 +144,13 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor {
         return _proposals[proposalId].voteEnd.getDeadline();
         return _proposals[proposalId].voteEnd.getDeadline();
     }
     }
 
 
+    /**
+     * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_.
+     */
+    function proposalThreshold() public view virtual returns (uint256) {
+        return 0;
+    }
+
     /**
     /**
      * @dev Amount of votes already cast passes the threshold limit.
      * @dev Amount of votes already cast passes the threshold limit.
      */
      */
@@ -174,6 +182,11 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor {
         bytes[] memory calldatas,
         bytes[] memory calldatas,
         string memory description
         string memory description
     ) public virtual override returns (uint256) {
     ) public virtual override returns (uint256) {
+        require(
+            getVotes(msg.sender, block.number - 1) >= proposalThreshold(),
+            "GovernorCompatibilityBravo: proposer votes below proposal threshold"
+        );
+
         uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description)));
         uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description)));
 
 
         require(targets.length == values.length, "Governor: invalid proposal length");
         require(targets.length == values.length, "Governor: invalid proposal length");

+ 10 - 6
contracts/governance/IGovernor.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/IGovernor.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
@@ -73,7 +74,7 @@ abstract contract IGovernor is IERC165 {
      *
      *
      * There are 2 standard keys: `support` and `quorum`.
      * There are 2 standard keys: `support` and `quorum`.
      *
      *
-     * - `support=bravo` refers to the vote options 0 = For, 1 = Against, 2 = Abstain, as in `GovernorBravo`.
+     * - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`.
      * - `quorum=bravo` means that only For votes are counted towards quorum.
      * - `quorum=bravo` means that only For votes are counted towards quorum.
      * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum.
      * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum.
      *
      *
@@ -103,28 +104,31 @@ abstract contract IGovernor is IERC165 {
 
 
     /**
     /**
      * @notice module:core
      * @notice module:core
-     * @dev block number used to retrieve user's votes and quorum.
+     * @dev Block number used to retrieve user's votes and quorum. As per Compound's Comp and OpenZeppelin's
+     * ERC20Votes, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the
+     * beginning of the following block.
      */
      */
     function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256);
     function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256);
 
 
     /**
     /**
      * @notice module:core
      * @notice module:core
-     * @dev timestamp at which votes close.
+     * @dev Block number at which votes close. Votes close at the end of this block, so it is possible to cast a vote
+     * during this block.
      */
      */
     function proposalDeadline(uint256 proposalId) public view virtual returns (uint256);
     function proposalDeadline(uint256 proposalId) public view virtual returns (uint256);
 
 
     /**
     /**
      * @notice module:user-config
      * @notice module:user-config
-     * @dev delay, in number of block, between the proposal is created and the vote starts. This can be increassed to
+     * @dev Delay, in number of block, between the proposal is created and the vote starts. This can be increassed to
      * leave time for users to buy voting power, of delegate it, before the voting of a proposal starts.
      * leave time for users to buy voting power, of delegate it, before the voting of a proposal starts.
      */
      */
     function votingDelay() public view virtual returns (uint256);
     function votingDelay() public view virtual returns (uint256);
 
 
     /**
     /**
      * @notice module:user-config
      * @notice module:user-config
-     * @dev delay, in number of blocks, between the vote start and vote ends.
+     * @dev Delay, in number of blocks, between the vote start and vote ends.
      *
      *
-     * Note: the {votingDelay} can delay the start of the vote. This must be considered when setting the voting
+     * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting
      * duration compared to the voting delay.
      * duration compared to the voting delay.
      */
      */
     function votingPeriod() public view virtual returns (uint256);
     function votingPeriod() public view virtual returns (uint256);

+ 6 - 2
contracts/governance/README.adoc

@@ -40,7 +40,7 @@ Other extensions can customize the behavior or interface in multiple ways.
 
 
 * {GovernorCompatibilityBravo}: Extends the interface to be fully `GovernorBravo`-compatible. Note that events are compatible regardless of whether this extension is included or not.
 * {GovernorCompatibilityBravo}: Extends the interface to be fully `GovernorBravo`-compatible. Note that events are compatible regardless of whether this extension is included or not.
 
 
-* {GovernorProposalThreshold}: Restricts proposals to delegates with a minimum voting power.
+* {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.
 
 
 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:
 
 
@@ -72,10 +72,14 @@ NOTE: Functions of the `Governor` contract do not include access control. If you
 
 
 {{GovernorTimelockCompound}}
 {{GovernorTimelockCompound}}
 
 
-{{GovernorProposalThreshold}}
+{{GovernorSettings}}
 
 
 {{GovernorCompatibilityBravo}}
 {{GovernorCompatibilityBravo}}
 
 
+=== Deprecated
+
+{{GovernorProposalThreshold}}
+
 == Timelock
 == Timelock
 
 
 In a governance system, the {TimelockController} contract is in carge of introducing a delay between a proposal and its execution. It can be used with or without a {Governor}.
 In a governance system, the {TimelockController} contract is in carge of introducing a delay between a proposal and its execution. It can be used with or without a {Governor}.

+ 1 - 0
contracts/governance/TimelockController.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/TimelockController.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 3 - 18
contracts/governance/compatibility/GovernorCompatibilityBravo.sol

@@ -1,11 +1,11 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/compatibility/GovernorCompatibilityBravo.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
 import "../../utils/Counters.sol";
 import "../../utils/Counters.sol";
 import "../../utils/math/SafeCast.sol";
 import "../../utils/math/SafeCast.sol";
 import "../extensions/IGovernorTimelock.sol";
 import "../extensions/IGovernorTimelock.sol";
-import "../extensions/GovernorProposalThreshold.sol";
 import "../Governor.sol";
 import "../Governor.sol";
 import "./IGovernorCompatibilityBravo.sol";
 import "./IGovernorCompatibilityBravo.sol";
 
 
@@ -19,12 +19,7 @@ import "./IGovernorCompatibilityBravo.sol";
  *
  *
  * _Available since v4.3._
  * _Available since v4.3._
  */
  */
-abstract contract GovernorCompatibilityBravo is
-    IGovernorTimelock,
-    IGovernorCompatibilityBravo,
-    Governor,
-    GovernorProposalThreshold
-{
+abstract contract GovernorCompatibilityBravo is IGovernorTimelock, IGovernorCompatibilityBravo, Governor {
     using Counters for Counters.Counter;
     using Counters for Counters.Counter;
     using Timers for Timers.BlockNumber;
     using Timers for Timers.BlockNumber;
 
 
@@ -63,7 +58,7 @@ abstract contract GovernorCompatibilityBravo is
         uint256[] memory values,
         uint256[] memory values,
         bytes[] memory calldatas,
         bytes[] memory calldatas,
         string memory description
         string memory description
-    ) public virtual override(IGovernor, Governor, GovernorProposalThreshold) returns (uint256) {
+    ) public virtual override(IGovernor, Governor) returns (uint256) {
         _storeProposal(_msgSender(), targets, values, new string[](calldatas.length), calldatas, description);
         _storeProposal(_msgSender(), targets, values, new string[](calldatas.length), calldatas, description);
         return super.propose(targets, values, calldatas, description);
         return super.propose(targets, values, calldatas, description);
     }
     }
@@ -169,16 +164,6 @@ abstract contract GovernorCompatibilityBravo is
     }
     }
 
 
     // ==================================================== Views =====================================================
     // ==================================================== Views =====================================================
-    /**
-     * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_.
-     */
-    function proposalThreshold()
-        public
-        view
-        virtual
-        override(IGovernorCompatibilityBravo, GovernorProposalThreshold)
-        returns (uint256);
-
     /**
     /**
      * @dev See {IGovernorCompatibilityBravo-proposals}.
      * @dev See {IGovernorCompatibilityBravo-proposals}.
      */
      */

+ 1 - 5
contracts/governance/compatibility/IGovernorCompatibilityBravo.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/compatibility/IGovernorCompatibilityBravo.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
@@ -110,9 +111,4 @@ abstract contract IGovernorCompatibilityBravo is IGovernor {
      * @dev Part of the Governor Bravo's interface: _"Gets the receipt for a voter on a given proposal"_.
      * @dev Part of the Governor Bravo's interface: _"Gets the receipt for a voter on a given proposal"_.
      */
      */
     function getReceipt(uint256 proposalId, address voter) public view virtual returns (Receipt memory);
     function getReceipt(uint256 proposalId, address voter) public view virtual returns (Receipt memory);
-
-    /**
-     * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_.
-     */
-    function proposalThreshold() public view virtual returns (uint256);
 }
 }

+ 1 - 0
contracts/governance/extensions/GovernorCountingSimple.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/extensions/GovernorCountingSimple.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 2 - 13
contracts/governance/extensions/GovernorProposalThreshold.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/extensions/GovernorProposalThreshold.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
@@ -8,27 +9,15 @@ import "../Governor.sol";
  * @dev Extension of {Governor} for proposal restriction to token holders with a minimum balance.
  * @dev Extension of {Governor} for proposal restriction to token holders with a minimum balance.
  *
  *
  * _Available since v4.3._
  * _Available since v4.3._
+ * _Deprecated since v4.4._
  */
  */
 abstract contract GovernorProposalThreshold is Governor {
 abstract contract GovernorProposalThreshold is Governor {
-    /**
-     * @dev See {IGovernor-propose}.
-     */
     function propose(
     function propose(
         address[] memory targets,
         address[] memory targets,
         uint256[] memory values,
         uint256[] memory values,
         bytes[] memory calldatas,
         bytes[] memory calldatas,
         string memory description
         string memory description
     ) public virtual override returns (uint256) {
     ) public virtual override returns (uint256) {
-        require(
-            getVotes(msg.sender, block.number - 1) >= proposalThreshold(),
-            "GovernorCompatibilityBravo: proposer votes below proposal threshold"
-        );
-
         return super.propose(targets, values, calldatas, description);
         return super.propose(targets, values, calldatas, description);
     }
     }
-
-    /**
-     * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_.
-     */
-    function proposalThreshold() public view virtual returns (uint256);
 }
 }

+ 114 - 0
contracts/governance/extensions/GovernorSettings.sol

@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/extensions/GovernorSettings.sol)
+
+pragma solidity ^0.8.0;
+
+import "../Governor.sol";
+
+/**
+ * @dev Extension of {Governor} for settings updatable through governance.
+ *
+ * _Available since v4.4._
+ */
+abstract contract GovernorSettings is Governor {
+    uint256 private _votingDelay;
+    uint256 private _votingPeriod;
+    uint256 private _proposalThreshold;
+
+    event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);
+    event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);
+    event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold);
+
+    /**
+     * @dev Initialize the governance parameters.
+     */
+    constructor(
+        uint256 initialVotingDelay,
+        uint256 initialVotingPeriod,
+        uint256 initialProposalThreshold
+    ) {
+        _setVotingDelay(initialVotingDelay);
+        _setVotingPeriod(initialVotingPeriod);
+        _setProposalThreshold(initialProposalThreshold);
+    }
+
+    /**
+     * @dev See {IGovernor-votingDelay}.
+     */
+    function votingDelay() public view virtual override returns (uint256) {
+        return _votingDelay;
+    }
+
+    /**
+     * @dev See {IGovernor-votingPeriod}.
+     */
+    function votingPeriod() public view virtual override returns (uint256) {
+        return _votingPeriod;
+    }
+
+    /**
+     * @dev See {Governor-proposalThreshold}.
+     */
+    function proposalThreshold() public view virtual override returns (uint256) {
+        return _proposalThreshold;
+    }
+
+    /**
+     * @dev Update the voting delay. This operation can only be performed through a governance proposal.
+     *
+     * Emits a {VotingDelaySet} event.
+     */
+    function setVotingDelay(uint256 newVotingDelay) public onlyGovernance {
+        _setVotingDelay(newVotingDelay);
+    }
+
+    /**
+     * @dev Update the voting period. This operation can only be performed through a governance proposal.
+     *
+     * Emits a {VotingPeriodSet} event.
+     */
+    function setVotingPeriod(uint256 newVotingPeriod) public onlyGovernance {
+        _setVotingPeriod(newVotingPeriod);
+    }
+
+    /**
+     * @dev Update the proposal threshold. This operation can only be performed through a governance proposal.
+     *
+     * Emits a {ProposalThresholdSet} event.
+     */
+    function setProposalThreshold(uint256 newProposalThreshold) public onlyGovernance {
+        _setProposalThreshold(newProposalThreshold);
+    }
+
+    /**
+     * @dev Internal setter for the voting delay.
+     *
+     * Emits a {VotingDelaySet} event.
+     */
+    function _setVotingDelay(uint256 newVotingDelay) internal virtual {
+        emit VotingDelaySet(_votingDelay, newVotingDelay);
+        _votingDelay = newVotingDelay;
+    }
+
+    /**
+     * @dev Internal setter for the voting period.
+     *
+     * Emits a {VotingPeriodSet} event.
+     */
+    function _setVotingPeriod(uint256 newVotingPeriod) internal virtual {
+        // voting period must be at least one block long
+        require(newVotingPeriod > 0, "GovernorSettings: voting period too low");
+        emit VotingPeriodSet(_votingPeriod, newVotingPeriod);
+        _votingPeriod = newVotingPeriod;
+    }
+
+    /**
+     * @dev Internal setter for the proposal threshold.
+     *
+     * Emits a {ProposalThresholdSet} event.
+     */
+    function _setProposalThreshold(uint256 newProposalThreshold) internal virtual {
+        emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold);
+        _proposalThreshold = newProposalThreshold;
+    }
+}

+ 1 - 0
contracts/governance/extensions/GovernorTimelockCompound.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/extensions/GovernorTimelockCompound.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/governance/extensions/GovernorTimelockControl.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/extensions/GovernorTimelockControl.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/governance/extensions/GovernorVotes.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/extensions/GovernorVotes.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/governance/extensions/GovernorVotesComp.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/extensions/GovernorVotesComp.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/governance/extensions/GovernorVotesQuorumFraction.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/extensions/GovernorVotesQuorumFraction.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/governance/extensions/IGovernorTimelock.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (governance/extensions/IGovernorTimelock.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC1155.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC1155.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC1155MetadataURI.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC1155MetadataURI.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC1155Receiver.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC1155Receiver.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC1271.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC1271.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC1363.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC1363.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC1363Receiver.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC1363Receiver.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC1363Spender.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC1363Spender.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC165.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC165.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC1820Implementer.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC1820Implementer.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC1820Registry.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC1820Registry.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC20.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC20.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC20Metadata.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC20Metadata.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC2981.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC2981.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC3156.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC3156.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC3156FlashBorrower.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC3156FlashBorrower.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC3156FlashLender.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC3156FlashLender.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC721.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC721.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC721Enumerable.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC721Enumerable.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC721Metadata.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC721Metadata.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC721Receiver.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC721Receiver.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC777.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC777.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC777Recipient.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC777Recipient.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/IERC777Sender.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/IERC777Sender.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/interfaces/draft-IERC2612.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (interfaces/draft-IERC2612.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/metatx/ERC2771Context.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (metatx/ERC2771Context.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/metatx/MinimalForwarder.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (metatx/MinimalForwarder.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 5 - 0
contracts/mocks/ECDSAMock.sol

@@ -6,6 +6,7 @@ import "../utils/cryptography/ECDSA.sol";
 
 
 contract ECDSAMock {
 contract ECDSAMock {
     using ECDSA for bytes32;
     using ECDSA for bytes32;
+    using ECDSA for bytes;
 
 
     function recover(bytes32 hash, bytes memory signature) public pure returns (address) {
     function recover(bytes32 hash, bytes memory signature) public pure returns (address) {
         return hash.recover(signature);
         return hash.recover(signature);
@@ -33,4 +34,8 @@ contract ECDSAMock {
     function toEthSignedMessageHash(bytes32 hash) public pure returns (bytes32) {
     function toEthSignedMessageHash(bytes32 hash) public pure returns (bytes32) {
         return hash.toEthSignedMessageHash();
         return hash.toEthSignedMessageHash();
     }
     }
+
+    function toEthSignedMessageHash(bytes memory s) public pure returns (bytes32) {
+        return s.toEthSignedMessageHash();
+    }
 }
 }

+ 4 - 27
contracts/mocks/ERC1155SupplyMock.sol

@@ -8,37 +8,14 @@ import "../token/ERC1155/extensions/ERC1155Supply.sol";
 contract ERC1155SupplyMock is ERC1155Mock, ERC1155Supply {
 contract ERC1155SupplyMock is ERC1155Mock, ERC1155Supply {
     constructor(string memory uri) ERC1155Mock(uri) {}
     constructor(string memory uri) ERC1155Mock(uri) {}
 
 
-    function _mint(
-        address account,
-        uint256 id,
-        uint256 amount,
-        bytes memory data
-    ) internal virtual override(ERC1155, ERC1155Supply) {
-        super._mint(account, id, amount, data);
-    }
-
-    function _mintBatch(
+    function _beforeTokenTransfer(
+        address operator,
+        address from,
         address to,
         address to,
         uint256[] memory ids,
         uint256[] memory ids,
         uint256[] memory amounts,
         uint256[] memory amounts,
         bytes memory data
         bytes memory data
     ) internal virtual override(ERC1155, ERC1155Supply) {
     ) internal virtual override(ERC1155, ERC1155Supply) {
-        super._mintBatch(to, ids, amounts, data);
-    }
-
-    function _burn(
-        address account,
-        uint256 id,
-        uint256 amount
-    ) internal virtual override(ERC1155, ERC1155Supply) {
-        super._burn(account, id, amount);
-    }
-
-    function _burnBatch(
-        address account,
-        uint256[] memory ids,
-        uint256[] memory amounts
-    ) internal virtual override(ERC1155, ERC1155Supply) {
-        super._burnBatch(account, ids, amounts);
+        super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
     }
     }
 }
 }

+ 8 - 20
contracts/mocks/GovernorCompMock.sol

@@ -2,34 +2,22 @@
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
-import "../governance/Governor.sol";
 import "../governance/extensions/GovernorCountingSimple.sol";
 import "../governance/extensions/GovernorCountingSimple.sol";
 import "../governance/extensions/GovernorVotesComp.sol";
 import "../governance/extensions/GovernorVotesComp.sol";
 
 
-contract GovernorCompMock is Governor, GovernorVotesComp, GovernorCountingSimple {
-    uint256 immutable _votingDelay;
-    uint256 immutable _votingPeriod;
-
-    constructor(
-        string memory name_,
-        ERC20VotesComp token_,
-        uint256 votingDelay_,
-        uint256 votingPeriod_
-    ) Governor(name_) GovernorVotesComp(token_) {
-        _votingDelay = votingDelay_;
-        _votingPeriod = votingPeriod_;
-    }
+contract GovernorCompMock is GovernorVotesComp, GovernorCountingSimple {
+    constructor(string memory name_, ERC20VotesComp token_) Governor(name_) GovernorVotesComp(token_) {}
 
 
-    function votingDelay() public view override returns (uint256) {
-        return _votingDelay;
+    function quorum(uint256) public pure override returns (uint256) {
+        return 0;
     }
     }
 
 
-    function votingPeriod() public view override returns (uint256) {
-        return _votingPeriod;
+    function votingDelay() public pure override returns (uint256) {
+        return 4;
     }
     }
 
 
-    function quorum(uint256) public pure override returns (uint256) {
-        return 0;
+    function votingPeriod() public pure override returns (uint256) {
+        return 16;
     }
     }
 
 
     function cancel(
     function cancel(

+ 18 - 23
contracts/mocks/GovernorCompatibilityBravoMock.sol

@@ -3,14 +3,16 @@
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
 import "../governance/compatibility/GovernorCompatibilityBravo.sol";
 import "../governance/compatibility/GovernorCompatibilityBravo.sol";
-import "../governance/extensions/GovernorVotesComp.sol";
 import "../governance/extensions/GovernorTimelockCompound.sol";
 import "../governance/extensions/GovernorTimelockCompound.sol";
+import "../governance/extensions/GovernorSettings.sol";
+import "../governance/extensions/GovernorVotesComp.sol";
 
 
-contract GovernorCompatibilityBravoMock is GovernorCompatibilityBravo, GovernorTimelockCompound, GovernorVotesComp {
-    uint256 immutable _votingDelay;
-    uint256 immutable _votingPeriod;
-    uint256 immutable _proposalThreshold;
-
+contract GovernorCompatibilityBravoMock is
+    GovernorCompatibilityBravo,
+    GovernorSettings,
+    GovernorTimelockCompound,
+    GovernorVotesComp
+{
     constructor(
     constructor(
         string memory name_,
         string memory name_,
         ERC20VotesComp token_,
         ERC20VotesComp token_,
@@ -18,11 +20,12 @@ contract GovernorCompatibilityBravoMock is GovernorCompatibilityBravo, GovernorT
         uint256 votingPeriod_,
         uint256 votingPeriod_,
         uint256 proposalThreshold_,
         uint256 proposalThreshold_,
         ICompoundTimelock timelock_
         ICompoundTimelock timelock_
-    ) Governor(name_) GovernorVotesComp(token_) GovernorTimelockCompound(timelock_) {
-        _votingDelay = votingDelay_;
-        _votingPeriod = votingPeriod_;
-        _proposalThreshold = proposalThreshold_;
-    }
+    )
+        Governor(name_)
+        GovernorTimelockCompound(timelock_)
+        GovernorSettings(votingDelay_, votingPeriod_, proposalThreshold_)
+        GovernorVotesComp(token_)
+    {}
 
 
     function supportsInterface(bytes4 interfaceId)
     function supportsInterface(bytes4 interfaceId)
         public
         public
@@ -34,18 +37,6 @@ contract GovernorCompatibilityBravoMock is GovernorCompatibilityBravo, GovernorT
         return super.supportsInterface(interfaceId);
         return super.supportsInterface(interfaceId);
     }
     }
 
 
-    function votingDelay() public view override returns (uint256) {
-        return _votingDelay;
-    }
-
-    function votingPeriod() public view override returns (uint256) {
-        return _votingPeriod;
-    }
-
-    function proposalThreshold() public view virtual override returns (uint256) {
-        return _proposalThreshold;
-    }
-
     function quorum(uint256) public pure override returns (uint256) {
     function quorum(uint256) public pure override returns (uint256) {
         return 0;
         return 0;
     }
     }
@@ -70,6 +61,10 @@ contract GovernorCompatibilityBravoMock is GovernorCompatibilityBravo, GovernorT
         return super.proposalEta(proposalId);
         return super.proposalEta(proposalId);
     }
     }
 
 
+    function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
+        return super.proposalThreshold();
+    }
+
     function propose(
     function propose(
         address[] memory targets,
         address[] memory targets,
         uint256[] memory values,
         uint256[] memory values,

+ 27 - 17
contracts/mocks/GovernorMock.sol

@@ -2,32 +2,29 @@
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
-import "../governance/Governor.sol";
+import "../governance/extensions/GovernorProposalThreshold.sol";
+import "../governance/extensions/GovernorSettings.sol";
 import "../governance/extensions/GovernorCountingSimple.sol";
 import "../governance/extensions/GovernorCountingSimple.sol";
 import "../governance/extensions/GovernorVotesQuorumFraction.sol";
 import "../governance/extensions/GovernorVotesQuorumFraction.sol";
 
 
-contract GovernorMock is Governor, GovernorVotesQuorumFraction, GovernorCountingSimple {
-    uint256 immutable _votingDelay;
-    uint256 immutable _votingPeriod;
-
+contract GovernorMock is
+    GovernorProposalThreshold,
+    GovernorSettings,
+    GovernorVotesQuorumFraction,
+    GovernorCountingSimple
+{
     constructor(
     constructor(
         string memory name_,
         string memory name_,
         ERC20Votes token_,
         ERC20Votes token_,
         uint256 votingDelay_,
         uint256 votingDelay_,
         uint256 votingPeriod_,
         uint256 votingPeriod_,
         uint256 quorumNumerator_
         uint256 quorumNumerator_
-    ) Governor(name_) GovernorVotes(token_) GovernorVotesQuorumFraction(quorumNumerator_) {
-        _votingDelay = votingDelay_;
-        _votingPeriod = votingPeriod_;
-    }
-
-    function votingDelay() public view override returns (uint256) {
-        return _votingDelay;
-    }
-
-    function votingPeriod() public view override returns (uint256) {
-        return _votingPeriod;
-    }
+    )
+        Governor(name_)
+        GovernorSettings(votingDelay_, votingPeriod_, 0)
+        GovernorVotes(token_)
+        GovernorVotesQuorumFraction(quorumNumerator_)
+    {}
 
 
     function cancel(
     function cancel(
         address[] memory targets,
         address[] memory targets,
@@ -47,4 +44,17 @@ contract GovernorMock is Governor, GovernorVotesQuorumFraction, GovernorCounting
     {
     {
         return super.getVotes(account, blockNumber);
         return super.getVotes(account, blockNumber);
     }
     }
+
+    function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
+        return super.proposalThreshold();
+    }
+
+    function propose(
+        address[] memory targets,
+        uint256[] memory values,
+        bytes[] memory calldatas,
+        string memory description
+    ) public virtual override(Governor, GovernorProposalThreshold) returns (uint256) {
+        return super.propose(targets, values, calldatas, description);
+    }
 }
 }

+ 13 - 16
contracts/mocks/GovernorTimelockCompoundMock.sol

@@ -3,13 +3,16 @@
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
 import "../governance/extensions/GovernorTimelockCompound.sol";
 import "../governance/extensions/GovernorTimelockCompound.sol";
+import "../governance/extensions/GovernorSettings.sol";
 import "../governance/extensions/GovernorCountingSimple.sol";
 import "../governance/extensions/GovernorCountingSimple.sol";
 import "../governance/extensions/GovernorVotesQuorumFraction.sol";
 import "../governance/extensions/GovernorVotesQuorumFraction.sol";
 
 
-contract GovernorTimelockCompoundMock is GovernorTimelockCompound, GovernorVotesQuorumFraction, GovernorCountingSimple {
-    uint256 immutable _votingDelay;
-    uint256 immutable _votingPeriod;
-
+contract GovernorTimelockCompoundMock is
+    GovernorSettings,
+    GovernorTimelockCompound,
+    GovernorVotesQuorumFraction,
+    GovernorCountingSimple
+{
     constructor(
     constructor(
         string memory name_,
         string memory name_,
         ERC20Votes token_,
         ERC20Votes token_,
@@ -20,12 +23,10 @@ contract GovernorTimelockCompoundMock is GovernorTimelockCompound, GovernorVotes
     )
     )
         Governor(name_)
         Governor(name_)
         GovernorTimelockCompound(timelock_)
         GovernorTimelockCompound(timelock_)
+        GovernorSettings(votingDelay_, votingPeriod_, 0)
         GovernorVotes(token_)
         GovernorVotes(token_)
         GovernorVotesQuorumFraction(quorumNumerator_)
         GovernorVotesQuorumFraction(quorumNumerator_)
-    {
-        _votingDelay = votingDelay_;
-        _votingPeriod = votingPeriod_;
-    }
+    {}
 
 
     function supportsInterface(bytes4 interfaceId)
     function supportsInterface(bytes4 interfaceId)
         public
         public
@@ -37,14 +38,6 @@ contract GovernorTimelockCompoundMock is GovernorTimelockCompound, GovernorVotes
         return super.supportsInterface(interfaceId);
         return super.supportsInterface(interfaceId);
     }
     }
 
 
-    function votingDelay() public view override returns (uint256) {
-        return _votingDelay;
-    }
-
-    function votingPeriod() public view override returns (uint256) {
-        return _votingPeriod;
-    }
-
     function quorum(uint256 blockNumber)
     function quorum(uint256 blockNumber)
         public
         public
         view
         view
@@ -76,6 +69,10 @@ contract GovernorTimelockCompoundMock is GovernorTimelockCompound, GovernorVotes
         return super.state(proposalId);
         return super.state(proposalId);
     }
     }
 
 
+    function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
+        return super.proposalThreshold();
+    }
+
     function _execute(
     function _execute(
         uint256 proposalId,
         uint256 proposalId,
         address[] memory targets,
         address[] memory targets,

+ 13 - 16
contracts/mocks/GovernorTimelockControlMock.sol

@@ -3,13 +3,16 @@
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
 import "../governance/extensions/GovernorTimelockControl.sol";
 import "../governance/extensions/GovernorTimelockControl.sol";
+import "../governance/extensions/GovernorSettings.sol";
 import "../governance/extensions/GovernorCountingSimple.sol";
 import "../governance/extensions/GovernorCountingSimple.sol";
 import "../governance/extensions/GovernorVotesQuorumFraction.sol";
 import "../governance/extensions/GovernorVotesQuorumFraction.sol";
 
 
-contract GovernorTimelockControlMock is GovernorTimelockControl, GovernorVotesQuorumFraction, GovernorCountingSimple {
-    uint256 immutable _votingDelay;
-    uint256 immutable _votingPeriod;
-
+contract GovernorTimelockControlMock is
+    GovernorSettings,
+    GovernorTimelockControl,
+    GovernorVotesQuorumFraction,
+    GovernorCountingSimple
+{
     constructor(
     constructor(
         string memory name_,
         string memory name_,
         ERC20Votes token_,
         ERC20Votes token_,
@@ -20,12 +23,10 @@ contract GovernorTimelockControlMock is GovernorTimelockControl, GovernorVotesQu
     )
     )
         Governor(name_)
         Governor(name_)
         GovernorTimelockControl(timelock_)
         GovernorTimelockControl(timelock_)
+        GovernorSettings(votingDelay_, votingPeriod_, 0)
         GovernorVotes(token_)
         GovernorVotes(token_)
         GovernorVotesQuorumFraction(quorumNumerator_)
         GovernorVotesQuorumFraction(quorumNumerator_)
-    {
-        _votingDelay = votingDelay_;
-        _votingPeriod = votingPeriod_;
-    }
+    {}
 
 
     function supportsInterface(bytes4 interfaceId)
     function supportsInterface(bytes4 interfaceId)
         public
         public
@@ -37,14 +38,6 @@ contract GovernorTimelockControlMock is GovernorTimelockControl, GovernorVotesQu
         return super.supportsInterface(interfaceId);
         return super.supportsInterface(interfaceId);
     }
     }
 
 
-    function votingDelay() public view override returns (uint256) {
-        return _votingDelay;
-    }
-
-    function votingPeriod() public view override returns (uint256) {
-        return _votingPeriod;
-    }
-
     function quorum(uint256 blockNumber)
     function quorum(uint256 blockNumber)
         public
         public
         view
         view
@@ -76,6 +69,10 @@ contract GovernorTimelockControlMock is GovernorTimelockControl, GovernorVotesQu
         return super.state(proposalId);
         return super.state(proposalId);
     }
     }
 
 
+    function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
+        return super.proposalThreshold();
+    }
+
     function _execute(
     function _execute(
         uint256 proposalId,
         uint256 proposalId,
         address[] memory targets,
         address[] memory targets,

+ 4 - 0
contracts/mocks/MerkleProofWrapper.sol

@@ -12,4 +12,8 @@ contract MerkleProofWrapper {
     ) public pure returns (bool) {
     ) public pure returns (bool) {
         return MerkleProof.verify(proof, root, leaf);
         return MerkleProof.verify(proof, root, leaf);
     }
     }
+
+    function processProof(bytes32[] memory proof, bytes32 leaf) public pure returns (bytes32) {
+        return MerkleProof.processProof(proof, leaf);
+    }
 }
 }

+ 96 - 0
contracts/mocks/wizard/MyGovernor1.sol

@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.2;
+
+import "../../governance/Governor.sol";
+import "../../governance/extensions/GovernorCountingSimple.sol";
+import "../../governance/extensions/GovernorVotes.sol";
+import "../../governance/extensions/GovernorVotesQuorumFraction.sol";
+import "../../governance/extensions/GovernorTimelockControl.sol";
+
+contract MyGovernor1 is
+    Governor,
+    GovernorTimelockControl,
+    GovernorVotes,
+    GovernorVotesQuorumFraction,
+    GovernorCountingSimple
+{
+    constructor(ERC20Votes _token, TimelockController _timelock)
+        Governor("MyGovernor")
+        GovernorVotes(_token)
+        GovernorVotesQuorumFraction(4)
+        GovernorTimelockControl(_timelock)
+    {}
+
+    function votingDelay() public pure override returns (uint256) {
+        return 1; // 1 block
+    }
+
+    function votingPeriod() public pure override returns (uint256) {
+        return 45818; // 1 week
+    }
+
+    // The following functions are overrides required by Solidity.
+
+    function quorum(uint256 blockNumber)
+        public
+        view
+        override(IGovernor, GovernorVotesQuorumFraction)
+        returns (uint256)
+    {
+        return super.quorum(blockNumber);
+    }
+
+    function getVotes(address account, uint256 blockNumber)
+        public
+        view
+        override(IGovernor, GovernorVotes)
+        returns (uint256)
+    {
+        return super.getVotes(account, blockNumber);
+    }
+
+    function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (ProposalState) {
+        return super.state(proposalId);
+    }
+
+    function propose(
+        address[] memory targets,
+        uint256[] memory values,
+        bytes[] memory calldatas,
+        string memory description
+    ) public override(Governor, IGovernor) returns (uint256) {
+        return super.propose(targets, values, calldatas, description);
+    }
+
+    function _execute(
+        uint256 proposalId,
+        address[] memory targets,
+        uint256[] memory values,
+        bytes[] memory calldatas,
+        bytes32 descriptionHash
+    ) internal override(Governor, GovernorTimelockControl) {
+        super._execute(proposalId, targets, values, calldatas, descriptionHash);
+    }
+
+    function _cancel(
+        address[] memory targets,
+        uint256[] memory values,
+        bytes[] memory calldatas,
+        bytes32 descriptionHash
+    ) internal override(Governor, GovernorTimelockControl) returns (uint256) {
+        return super._cancel(targets, values, calldatas, descriptionHash);
+    }
+
+    function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) {
+        return super._executor();
+    }
+
+    function supportsInterface(bytes4 interfaceId)
+        public
+        view
+        override(Governor, GovernorTimelockControl)
+        returns (bool)
+    {
+        return super.supportsInterface(interfaceId);
+    }
+}

+ 102 - 0
contracts/mocks/wizard/MyGovernor2.sol

@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.2;
+
+import "../../governance/Governor.sol";
+import "../../governance/extensions/GovernorProposalThreshold.sol";
+import "../../governance/extensions/GovernorCountingSimple.sol";
+import "../../governance/extensions/GovernorVotes.sol";
+import "../../governance/extensions/GovernorVotesQuorumFraction.sol";
+import "../../governance/extensions/GovernorTimelockControl.sol";
+
+contract MyGovernor2 is
+    Governor,
+    GovernorTimelockControl,
+    GovernorProposalThreshold,
+    GovernorVotes,
+    GovernorVotesQuorumFraction,
+    GovernorCountingSimple
+{
+    constructor(ERC20Votes _token, TimelockController _timelock)
+        Governor("MyGovernor")
+        GovernorVotes(_token)
+        GovernorVotesQuorumFraction(4)
+        GovernorTimelockControl(_timelock)
+    {}
+
+    function votingDelay() public pure override returns (uint256) {
+        return 1; // 1 block
+    }
+
+    function votingPeriod() public pure override returns (uint256) {
+        return 45818; // 1 week
+    }
+
+    function proposalThreshold() public pure override returns (uint256) {
+        return 1000e18;
+    }
+
+    // The following functions are overrides required by Solidity.
+
+    function quorum(uint256 blockNumber)
+        public
+        view
+        override(IGovernor, GovernorVotesQuorumFraction)
+        returns (uint256)
+    {
+        return super.quorum(blockNumber);
+    }
+
+    function getVotes(address account, uint256 blockNumber)
+        public
+        view
+        override(IGovernor, GovernorVotes)
+        returns (uint256)
+    {
+        return super.getVotes(account, blockNumber);
+    }
+
+    function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (ProposalState) {
+        return super.state(proposalId);
+    }
+
+    function propose(
+        address[] memory targets,
+        uint256[] memory values,
+        bytes[] memory calldatas,
+        string memory description
+    ) public override(Governor, GovernorProposalThreshold, IGovernor) returns (uint256) {
+        return super.propose(targets, values, calldatas, description);
+    }
+
+    function _execute(
+        uint256 proposalId,
+        address[] memory targets,
+        uint256[] memory values,
+        bytes[] memory calldatas,
+        bytes32 descriptionHash
+    ) internal override(Governor, GovernorTimelockControl) {
+        super._execute(proposalId, targets, values, calldatas, descriptionHash);
+    }
+
+    function _cancel(
+        address[] memory targets,
+        uint256[] memory values,
+        bytes[] memory calldatas,
+        bytes32 descriptionHash
+    ) internal override(Governor, GovernorTimelockControl) returns (uint256) {
+        return super._cancel(targets, values, calldatas, descriptionHash);
+    }
+
+    function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) {
+        return super._executor();
+    }
+
+    function supportsInterface(bytes4 interfaceId)
+        public
+        view
+        override(Governor, GovernorTimelockControl)
+        returns (bool)
+    {
+        return super.supportsInterface(interfaceId);
+    }
+}

+ 105 - 0
contracts/mocks/wizard/MyGovernor3.sol

@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.2;
+
+import "../../governance/Governor.sol";
+import "../../governance/compatibility/GovernorCompatibilityBravo.sol";
+import "../../governance/extensions/GovernorVotes.sol";
+import "../../governance/extensions/GovernorVotesQuorumFraction.sol";
+import "../../governance/extensions/GovernorTimelockControl.sol";
+
+contract MyGovernor is
+    Governor,
+    GovernorTimelockControl,
+    GovernorCompatibilityBravo,
+    GovernorVotes,
+    GovernorVotesQuorumFraction
+{
+    constructor(ERC20Votes _token, TimelockController _timelock)
+        Governor("MyGovernor")
+        GovernorVotes(_token)
+        GovernorVotesQuorumFraction(4)
+        GovernorTimelockControl(_timelock)
+    {}
+
+    function votingDelay() public pure override returns (uint256) {
+        return 1; // 1 block
+    }
+
+    function votingPeriod() public pure override returns (uint256) {
+        return 45818; // 1 week
+    }
+
+    function proposalThreshold() public pure override returns (uint256) {
+        return 1000e18;
+    }
+
+    // The following functions are overrides required by Solidity.
+
+    function quorum(uint256 blockNumber)
+        public
+        view
+        override(IGovernor, GovernorVotesQuorumFraction)
+        returns (uint256)
+    {
+        return super.quorum(blockNumber);
+    }
+
+    function getVotes(address account, uint256 blockNumber)
+        public
+        view
+        override(IGovernor, GovernorVotes)
+        returns (uint256)
+    {
+        return super.getVotes(account, blockNumber);
+    }
+
+    function state(uint256 proposalId)
+        public
+        view
+        override(Governor, IGovernor, GovernorTimelockControl)
+        returns (ProposalState)
+    {
+        return super.state(proposalId);
+    }
+
+    function propose(
+        address[] memory targets,
+        uint256[] memory values,
+        bytes[] memory calldatas,
+        string memory description
+    ) public override(Governor, GovernorCompatibilityBravo, IGovernor) returns (uint256) {
+        return super.propose(targets, values, calldatas, description);
+    }
+
+    function _execute(
+        uint256 proposalId,
+        address[] memory targets,
+        uint256[] memory values,
+        bytes[] memory calldatas,
+        bytes32 descriptionHash
+    ) internal override(Governor, GovernorTimelockControl) {
+        super._execute(proposalId, targets, values, calldatas, descriptionHash);
+    }
+
+    function _cancel(
+        address[] memory targets,
+        uint256[] memory values,
+        bytes[] memory calldatas,
+        bytes32 descriptionHash
+    ) internal override(Governor, GovernorTimelockControl) returns (uint256) {
+        return super._cancel(targets, values, calldatas, descriptionHash);
+    }
+
+    function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) {
+        return super._executor();
+    }
+
+    function supportsInterface(bytes4 interfaceId)
+        public
+        view
+        override(Governor, IERC165, GovernorTimelockControl)
+        returns (bool)
+    {
+        return super.supportsInterface(interfaceId);
+    }
+}

+ 1 - 0
contracts/proxy/Clones.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (proxy/Clones.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/proxy/ERC1967/ERC1967Proxy.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (proxy/ERC1967/ERC1967Proxy.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/proxy/ERC1967/ERC1967Upgrade.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (proxy/ERC1967/ERC1967Upgrade.sol)
 
 
 pragma solidity ^0.8.2;
 pragma solidity ^0.8.2;
 
 

+ 1 - 0
contracts/proxy/Proxy.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (proxy/Proxy.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/proxy/beacon/BeaconProxy.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (proxy/beacon/BeaconProxy.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/proxy/beacon/IBeacon.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (proxy/beacon/IBeacon.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/proxy/beacon/UpgradeableBeacon.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (proxy/beacon/UpgradeableBeacon.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/proxy/transparent/ProxyAdmin.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (proxy/transparent/ProxyAdmin.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/proxy/transparent/TransparentUpgradeableProxy.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (proxy/transparent/TransparentUpgradeableProxy.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/proxy/utils/Initializable.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (proxy/utils/Initializable.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/proxy/utils/UUPSUpgradeable.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (proxy/utils/UUPSUpgradeable.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/security/Pausable.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (security/Pausable.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/security/PullPayment.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (security/PullPayment.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/security/ReentrancyGuard.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (security/ReentrancyGuard.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 43 - 30
contracts/token/ERC1155/ERC1155.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC1155/ERC1155.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
@@ -100,10 +101,7 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
      * @dev See {IERC1155-setApprovalForAll}.
      * @dev See {IERC1155-setApprovalForAll}.
      */
      */
     function setApprovalForAll(address operator, bool approved) public virtual override {
     function setApprovalForAll(address operator, bool approved) public virtual override {
-        require(_msgSender() != operator, "ERC1155: setting approval status for self");
-
-        _operatorApprovals[_msgSender()][operator] = approved;
-        emit ApprovalForAll(_msgSender(), operator, approved);
+        _setApprovalForAll(_msgSender(), operator, approved);
     }
     }
 
 
     /**
     /**
@@ -249,32 +247,32 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
     }
     }
 
 
     /**
     /**
-     * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
+     * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
      *
      *
      * Emits a {TransferSingle} event.
      * Emits a {TransferSingle} event.
      *
      *
      * Requirements:
      * Requirements:
      *
      *
-     * - `account` cannot be the zero address.
-     * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
+     * - `to` cannot be the zero address.
+     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
      * acceptance magic value.
      * acceptance magic value.
      */
      */
     function _mint(
     function _mint(
-        address account,
+        address to,
         uint256 id,
         uint256 id,
         uint256 amount,
         uint256 amount,
         bytes memory data
         bytes memory data
     ) internal virtual {
     ) internal virtual {
-        require(account != address(0), "ERC1155: mint to the zero address");
+        require(to != address(0), "ERC1155: mint to the zero address");
 
 
         address operator = _msgSender();
         address operator = _msgSender();
 
 
-        _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);
+        _beforeTokenTransfer(operator, address(0), to, _asSingletonArray(id), _asSingletonArray(amount), data);
 
 
-        _balances[id][account] += amount;
-        emit TransferSingle(operator, address(0), account, id, amount);
+        _balances[id][to] += amount;
+        emit TransferSingle(operator, address(0), to, id, amount);
 
 
-        _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
+        _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
     }
     }
 
 
     /**
     /**
@@ -309,31 +307,31 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
     }
     }
 
 
     /**
     /**
-     * @dev Destroys `amount` tokens of token type `id` from `account`
+     * @dev Destroys `amount` tokens of token type `id` from `from`
      *
      *
      * Requirements:
      * Requirements:
      *
      *
-     * - `account` cannot be the zero address.
-     * - `account` must have at least `amount` tokens of token type `id`.
+     * - `from` cannot be the zero address.
+     * - `from` must have at least `amount` tokens of token type `id`.
      */
      */
     function _burn(
     function _burn(
-        address account,
+        address from,
         uint256 id,
         uint256 id,
         uint256 amount
         uint256 amount
     ) internal virtual {
     ) internal virtual {
-        require(account != address(0), "ERC1155: burn from the zero address");
+        require(from != address(0), "ERC1155: burn from the zero address");
 
 
         address operator = _msgSender();
         address operator = _msgSender();
 
 
-        _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
+        _beforeTokenTransfer(operator, from, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
 
 
-        uint256 accountBalance = _balances[id][account];
-        require(accountBalance >= amount, "ERC1155: burn amount exceeds balance");
+        uint256 fromBalance = _balances[id][from];
+        require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
         unchecked {
         unchecked {
-            _balances[id][account] = accountBalance - amount;
+            _balances[id][from] = fromBalance - amount;
         }
         }
 
 
-        emit TransferSingle(operator, account, address(0), id, amount);
+        emit TransferSingle(operator, from, address(0), id, amount);
     }
     }
 
 
     /**
     /**
@@ -344,29 +342,44 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
      * - `ids` and `amounts` must have the same length.
      * - `ids` and `amounts` must have the same length.
      */
      */
     function _burnBatch(
     function _burnBatch(
-        address account,
+        address from,
         uint256[] memory ids,
         uint256[] memory ids,
         uint256[] memory amounts
         uint256[] memory amounts
     ) internal virtual {
     ) internal virtual {
-        require(account != address(0), "ERC1155: burn from the zero address");
+        require(from != address(0), "ERC1155: burn from the zero address");
         require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
         require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
 
 
         address operator = _msgSender();
         address operator = _msgSender();
 
 
-        _beforeTokenTransfer(operator, account, address(0), ids, amounts, "");
+        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
 
 
         for (uint256 i = 0; i < ids.length; i++) {
         for (uint256 i = 0; i < ids.length; i++) {
             uint256 id = ids[i];
             uint256 id = ids[i];
             uint256 amount = amounts[i];
             uint256 amount = amounts[i];
 
 
-            uint256 accountBalance = _balances[id][account];
-            require(accountBalance >= amount, "ERC1155: burn amount exceeds balance");
+            uint256 fromBalance = _balances[id][from];
+            require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
             unchecked {
             unchecked {
-                _balances[id][account] = accountBalance - amount;
+                _balances[id][from] = fromBalance - amount;
             }
             }
         }
         }
 
 
-        emit TransferBatch(operator, account, address(0), ids, amounts);
+        emit TransferBatch(operator, from, address(0), ids, amounts);
+    }
+
+    /**
+     * @dev Approve `operator` to operate on all of `owner` tokens
+     *
+     * Emits a {ApprovalForAll} event.
+     */
+    function _setApprovalForAll(
+        address owner,
+        address operator,
+        bool approved
+    ) internal virtual {
+        require(owner != operator, "ERC1155: setting approval status for self");
+        _operatorApprovals[owner][operator] = approved;
+        emit ApprovalForAll(owner, operator, approved);
     }
     }
 
 
     /**
     /**

+ 1 - 0
contracts/token/ERC1155/IERC1155.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC1155/IERC1155.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 30 - 24
contracts/token/ERC1155/IERC1155Receiver.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC1155/IERC1155Receiver.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
@@ -9,18 +10,20 @@ import "../../utils/introspection/IERC165.sol";
  */
  */
 interface IERC1155Receiver is IERC165 {
 interface IERC1155Receiver is IERC165 {
     /**
     /**
-        @dev Handles the receipt of a single ERC1155 token type. This function is
-        called at the end of a `safeTransferFrom` after the balance has been updated.
-        To accept the transfer, this must return
-        `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
-        (i.e. 0xf23a6e61, or its own function selector).
-        @param operator The address which initiated the transfer (i.e. msg.sender)
-        @param from The address which previously owned the token
-        @param id The ID of the token being transferred
-        @param value The amount of tokens being transferred
-        @param data Additional data with no specified format
-        @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
-    */
+     * @dev Handles the receipt of a single ERC1155 token type. This function is
+     * called at the end of a `safeTransferFrom` after the balance has been updated.
+     *
+     * NOTE: To accept the transfer, this must return
+     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
+     * (i.e. 0xf23a6e61, or its own function selector).
+     *
+     * @param operator The address which initiated the transfer (i.e. msg.sender)
+     * @param from The address which previously owned the token
+     * @param id The ID of the token being transferred
+     * @param value The amount of tokens being transferred
+     * @param data Additional data with no specified format
+     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
+     */
     function onERC1155Received(
     function onERC1155Received(
         address operator,
         address operator,
         address from,
         address from,
@@ -30,18 +33,21 @@ interface IERC1155Receiver is IERC165 {
     ) external returns (bytes4);
     ) external returns (bytes4);
 
 
     /**
     /**
-        @dev Handles the receipt of a multiple ERC1155 token types. This function
-        is called at the end of a `safeBatchTransferFrom` after the balances have
-        been updated. To accept the transfer(s), this must return
-        `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
-        (i.e. 0xbc197c81, or its own function selector).
-        @param operator The address which initiated the batch transfer (i.e. msg.sender)
-        @param from The address which previously owned the token
-        @param ids An array containing ids of each token being transferred (order and length must match values array)
-        @param values An array containing amounts of each token being transferred (order and length must match ids array)
-        @param data Additional data with no specified format
-        @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
-    */
+     * @dev Handles the receipt of a multiple ERC1155 token types. This function
+     * is called at the end of a `safeBatchTransferFrom` after the balances have
+     * been updated.
+     *
+     * NOTE: To accept the transfer(s), this must return
+     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
+     * (i.e. 0xbc197c81, or its own function selector).
+     *
+     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
+     * @param from The address which previously owned the token
+     * @param ids An array containing ids of each token being transferred (order and length must match values array)
+     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
+     * @param data Additional data with no specified format
+     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
+     */
     function onERC1155BatchReceived(
     function onERC1155BatchReceived(
         address operator,
         address operator,
         address from,
         address from,

+ 2 - 0
contracts/token/ERC1155/README.adoc

@@ -26,6 +26,8 @@ NOTE: This core set of contracts is designed to be unopinionated, allowing devel
 
 
 {{IERC1155Receiver}}
 {{IERC1155Receiver}}
 
 
+{{ERC1155Receiver}}
+
 == Extensions
 == Extensions
 
 
 {{ERC1155Pausable}}
 {{ERC1155Pausable}}

+ 1 - 0
contracts/token/ERC1155/extensions/ERC1155Burnable.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC1155/extensions/ERC1155Burnable.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC1155/extensions/ERC1155Pausable.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC1155/extensions/ERC1155Pausable.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 16 - 43
contracts/token/ERC1155/extensions/ERC1155Supply.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC1155/extensions/ERC1155Supply.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
@@ -23,63 +24,35 @@ abstract contract ERC1155Supply is ERC1155 {
     }
     }
 
 
     /**
     /**
-     * @dev Indicates weither any token exist with a given id, or not.
+     * @dev Indicates whether any token exist with a given id, or not.
      */
      */
     function exists(uint256 id) public view virtual returns (bool) {
     function exists(uint256 id) public view virtual returns (bool) {
         return ERC1155Supply.totalSupply(id) > 0;
         return ERC1155Supply.totalSupply(id) > 0;
     }
     }
 
 
     /**
     /**
-     * @dev See {ERC1155-_mint}.
+     * @dev See {ERC1155-_beforeTokenTransfer}.
      */
      */
-    function _mint(
-        address account,
-        uint256 id,
-        uint256 amount,
-        bytes memory data
-    ) internal virtual override {
-        super._mint(account, id, amount, data);
-        _totalSupply[id] += amount;
-    }
-
-    /**
-     * @dev See {ERC1155-_mintBatch}.
-     */
-    function _mintBatch(
+    function _beforeTokenTransfer(
+        address operator,
+        address from,
         address to,
         address to,
         uint256[] memory ids,
         uint256[] memory ids,
         uint256[] memory amounts,
         uint256[] memory amounts,
         bytes memory data
         bytes memory data
     ) internal virtual override {
     ) internal virtual override {
-        super._mintBatch(to, ids, amounts, data);
-        for (uint256 i = 0; i < ids.length; ++i) {
-            _totalSupply[ids[i]] += amounts[i];
-        }
-    }
+        super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
 
 
-    /**
-     * @dev See {ERC1155-_burn}.
-     */
-    function _burn(
-        address account,
-        uint256 id,
-        uint256 amount
-    ) internal virtual override {
-        super._burn(account, id, amount);
-        _totalSupply[id] -= amount;
-    }
+        if (from == address(0)) {
+            for (uint256 i = 0; i < ids.length; ++i) {
+                _totalSupply[ids[i]] += amounts[i];
+            }
+        }
 
 
-    /**
-     * @dev See {ERC1155-_burnBatch}.
-     */
-    function _burnBatch(
-        address account,
-        uint256[] memory ids,
-        uint256[] memory amounts
-    ) internal virtual override {
-        super._burnBatch(account, ids, amounts);
-        for (uint256 i = 0; i < ids.length; ++i) {
-            _totalSupply[ids[i]] -= amounts[i];
+        if (to == address(0)) {
+            for (uint256 i = 0; i < ids.length; ++i) {
+                _totalSupply[ids[i]] -= amounts[i];
+            }
         }
         }
     }
     }
 }
 }

+ 1 - 0
contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC1155/extensions/IERC1155MetadataURI.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC1155/presets/ERC1155PresetMinterPauser.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 6 - 0
contracts/token/ERC1155/utils/ERC1155Holder.sol

@@ -1,10 +1,16 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC1155/utils/ERC1155Holder.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
 import "./ERC1155Receiver.sol";
 import "./ERC1155Receiver.sol";
 
 
 /**
 /**
+ * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens.
+ *
+ * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be
+ * stuck.
+ *
  * @dev _Available since v3.1._
  * @dev _Available since v3.1._
  */
  */
 contract ERC1155Holder is ERC1155Receiver {
 contract ERC1155Holder is ERC1155Receiver {

+ 1 - 0
contracts/token/ERC1155/utils/ERC1155Receiver.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC1155/utils/ERC1155Receiver.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC20/ERC20.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/ERC20.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC20/IERC20.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/IERC20.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC20/extensions/ERC20Burnable.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/extensions/ERC20Burnable.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC20/extensions/ERC20Capped.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/extensions/ERC20Capped.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC20/extensions/ERC20FlashMint.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/extensions/ERC20FlashMint.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC20/extensions/ERC20Pausable.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/extensions/ERC20Pausable.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC20/extensions/ERC20Snapshot.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/extensions/ERC20Snapshot.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 3 - 2
contracts/token/ERC20/extensions/ERC20Votes.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/extensions/ERC20Votes.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 
@@ -134,7 +135,7 @@ abstract contract ERC20Votes is ERC20Permit {
      * @dev Delegate votes from the sender to `delegatee`.
      * @dev Delegate votes from the sender to `delegatee`.
      */
      */
     function delegate(address delegatee) public virtual {
     function delegate(address delegatee) public virtual {
-        return _delegate(_msgSender(), delegatee);
+        _delegate(_msgSender(), delegatee);
     }
     }
 
 
     /**
     /**
@@ -156,7 +157,7 @@ abstract contract ERC20Votes is ERC20Permit {
             s
             s
         );
         );
         require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce");
         require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce");
-        return _delegate(signer, delegatee);
+        _delegate(signer, delegatee);
     }
     }
 
 
     /**
     /**

+ 1 - 0
contracts/token/ERC20/extensions/ERC20VotesComp.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/extensions/ERC20VotesComp.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC20/extensions/ERC20Wrapper.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/extensions/ERC20Wrapper.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC20/extensions/IERC20Metadata.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/extensions/IERC20Metadata.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC20/extensions/draft-ERC20Permit.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/extensions/draft-ERC20Permit.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

+ 1 - 0
contracts/token/ERC20/extensions/draft-IERC20Permit.sol

@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MIT
 // SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts v4.3.2 (token/ERC20/extensions/draft-IERC20Permit.sol)
 
 
 pragma solidity ^0.8.0;
 pragma solidity ^0.8.0;
 
 

Some files were not shown because too many files changed in this diff