Merge branch 'master' into refactor/DoubleEndedQueue

pull/4150/head
Hadrien Croubois 2 years ago
commit 734bf8e85a
  1. 5
      .changeset/blue-horses-do.md
  2. 5
      .changeset/loud-shrimps-play.md
  3. 5
      .changeset/orange-apes-draw.md
  4. 5
      .changeset/popular-deers-raise.md
  5. 5
      .changeset/sixty-numbers-reply.md
  6. 1
      .github/workflows/checks.yml
  7. 3
      .solhint.json
  8. 2
      README.md
  9. 12
      contracts/access/AccessControl.sol
  10. 11
      contracts/access/AccessControlDefaultAdminRules.sol
  11. 6
      contracts/access/AccessControlEnumerable.sol
  12. 2
      contracts/access/IAccessControl.sol
  13. 4
      contracts/access/IAccessControlDefaultAdminRules.sol
  14. 2
      contracts/access/IAccessControlEnumerable.sol
  15. 2
      contracts/access/Ownable.sol
  16. 2
      contracts/access/Ownable2Step.sol
  17. 7
      contracts/finance/VestingWallet.sol
  18. 70
      contracts/governance/Governor.sol
  19. 27
      contracts/governance/IGovernor.sol
  20. 3
      contracts/governance/README.adoc
  21. 84
      contracts/governance/TimelockController.sol
  22. 10
      contracts/governance/compatibility/GovernorCompatibilityBravo.sol
  23. 4
      contracts/governance/compatibility/IGovernorCompatibilityBravo.sol
  24. 4
      contracts/governance/extensions/GovernorCountingSimple.sol
  25. 7
      contracts/governance/extensions/GovernorPreventLateQuorum.sol
  26. 4
      contracts/governance/extensions/GovernorSettings.sol
  27. 13
      contracts/governance/extensions/GovernorTimelockCompound.sol
  28. 9
      contracts/governance/extensions/GovernorTimelockControl.sol
  29. 8
      contracts/governance/extensions/GovernorVotes.sol
  30. 9
      contracts/governance/extensions/GovernorVotesQuorumFraction.sol
  31. 4
      contracts/governance/extensions/IGovernorTimelock.sol
  32. 6
      contracts/governance/utils/IVotes.sol
  33. 16
      contracts/governance/utils/Votes.sol
  34. 2
      contracts/interfaces/IERC1155.sol
  35. 2
      contracts/interfaces/IERC1155MetadataURI.sol
  36. 2
      contracts/interfaces/IERC1155Receiver.sol
  37. 2
      contracts/interfaces/IERC1271.sol
  38. 4
      contracts/interfaces/IERC1363.sol
  39. 2
      contracts/interfaces/IERC165.sol
  40. 2
      contracts/interfaces/IERC1967.sol
  41. 2
      contracts/interfaces/IERC20.sol
  42. 2
      contracts/interfaces/IERC20Metadata.sol
  43. 2
      contracts/interfaces/IERC2309.sol
  44. 2
      contracts/interfaces/IERC2612.sol
  45. 4
      contracts/interfaces/IERC2981.sol
  46. 4
      contracts/interfaces/IERC3156.sol
  47. 2
      contracts/interfaces/IERC3156FlashBorrower.sol
  48. 4
      contracts/interfaces/IERC3156FlashLender.sol
  49. 6
      contracts/interfaces/IERC4626.sol
  50. 4
      contracts/interfaces/IERC4906.sol
  51. 2
      contracts/interfaces/IERC5313.sol
  52. 4
      contracts/interfaces/IERC5805.sol
  53. 2
      contracts/interfaces/IERC721.sol
  54. 2
      contracts/interfaces/IERC721Enumerable.sol
  55. 2
      contracts/interfaces/IERC721Metadata.sol
  56. 2
      contracts/interfaces/IERC721Receiver.sol
  57. 1
      contracts/interfaces/draft-IERC6093.sol
  58. 2
      contracts/metatx/ERC2771Context.sol
  59. 308
      contracts/metatx/ERC2771Forwarder.sol
  60. 104
      contracts/metatx/MinimalForwarder.sol
  61. 2
      contracts/metatx/README.adoc
  62. 2
      contracts/mocks/AddressFnPointersMock.sol
  63. 2
      contracts/mocks/ArraysMock.sol
  64. 2
      contracts/mocks/ContextMock.sol
  65. 3
      contracts/mocks/DummyImplementation.sol
  66. 4
      contracts/mocks/EIP712Verifier.sol
  67. 6
      contracts/mocks/ERC1271WalletMock.sol
  68. 2
      contracts/mocks/ERC165/ERC165InterfacesSupported.sol
  69. 2
      contracts/mocks/ERC165/ERC165ReturnBomb.sol
  70. 5
      contracts/mocks/ERC2771ContextMock.sol
  71. 6
      contracts/mocks/ERC3156FlashBorrowerMock.sol
  72. 2
      contracts/mocks/InitializableMock.sol
  73. 2
      contracts/mocks/MulticallTest.sol
  74. 2
      contracts/mocks/MultipleInheritanceInitializableMocks.sol
  75. 2
      contracts/mocks/PausableMock.sol
  76. 2
      contracts/mocks/ReentrancyAttack.sol
  77. 4
      contracts/mocks/ReentrancyMock.sol
  78. 2
      contracts/mocks/RegressionImplementation.sol
  79. 2
      contracts/mocks/SingleInheritanceInitializableMocks.sol
  80. 2
      contracts/mocks/StorageSlotMock.sol
  81. 2
      contracts/mocks/TimelockReentrant.sol
  82. 2
      contracts/mocks/VotesMock.sol
  83. 5
      contracts/mocks/docs/ERC4626Fees.sol
  84. 13
      contracts/mocks/docs/governance/MyGovernor.sol
  85. 7
      contracts/mocks/docs/governance/MyToken.sol
  86. 7
      contracts/mocks/docs/governance/MyTokenTimestampBased.sol
  87. 9
      contracts/mocks/docs/governance/MyTokenWrapped.sol
  88. 10
      contracts/mocks/governance/GovernorCompatibilityBravoMock.sol
  89. 7
      contracts/mocks/governance/GovernorMock.sol
  90. 9
      contracts/mocks/governance/GovernorPreventLateQuorumMock.sol
  91. 9
      contracts/mocks/governance/GovernorTimelockCompoundMock.sol
  92. 9
      contracts/mocks/governance/GovernorTimelockControlMock.sol
  93. 4
      contracts/mocks/governance/GovernorVoteMock.sol
  94. 5
      contracts/mocks/governance/GovernorWithParamsMock.sol
  95. 3
      contracts/mocks/proxy/UUPSUpgradeableMock.sol
  96. 4
      contracts/mocks/token/ERC1155ReceiverMock.sol
  97. 2
      contracts/mocks/token/ERC20ApprovalMock.sol
  98. 2
      contracts/mocks/token/ERC20DecimalsMock.sol
  99. 2
      contracts/mocks/token/ERC20FlashMintMock.sol
  100. 2
      contracts/mocks/token/ERC20ForceApproveMock.sol
  101. Some files were not shown because too many files have changed in this diff Show More

@ -0,0 +1,5 @@
---
'openzeppelin-solidity': major
---
`ERC2771Forwarder`: Added `deadline` for expiring transactions, batching, and more secure handling of `msg.value`.

@ -0,0 +1,5 @@
---
'openzeppelin-solidity': minor
---
`TimelockController`: Add a state getter that returns an `OperationState` enum.

@ -0,0 +1,5 @@
---
'openzeppelin-solidity': major
---
Switched to using explicit Solidity import statements. Some previously available symbols may now have to be separately imported.

@ -0,0 +1,5 @@
---
'openzeppelin-solidity': major
---
`Governor`: Add support for casting votes with ERC-1271 signatures by using a `bytes memory signature` instead of `r`, `s` and `v` arguments in the `castVoteBySig` and `castVoteWithReasonAndParamsBySig` functions.

@ -0,0 +1,5 @@
---
'openzeppelin-solidity': major
---
`Governor`: Add `voter` and `nonce` parameters in signed ballots, to avoid forging signatures for random addresses, prevent signature replay, and allow invalidating signatures. Add `voter` as a new parameter in the `castVoteBySig` and `castVoteWithReasonAndParamsBySig` functions.

@ -100,6 +100,7 @@ jobs:
- uses: crytic/slither-action@v0.3.0 - uses: crytic/slither-action@v0.3.0
with: with:
node-version: 18.15 node-version: 18.15
slither-version: 0.9.3
codespell: codespell:
runs-on: ubuntu-latest runs-on: ubuntu-latest

@ -9,6 +9,7 @@
"modifier-name-mixedcase": "error", "modifier-name-mixedcase": "error",
"private-vars-leading-underscore": "error", "private-vars-leading-underscore": "error",
"var-name-mixedcase": "error", "var-name-mixedcase": "error",
"imports-on-top": "error" "imports-on-top": "error",
"no-global-import": "error"
} }
} }

@ -48,7 +48,7 @@ Once installed, you can use the contracts in the library by importing them:
```solidity ```solidity
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyCollectible is ERC721 { contract MyCollectible is ERC721 {
constructor() ERC721("MyCollectible", "MCO") { constructor() ERC721("MyCollectible", "MCO") {

@ -3,10 +3,10 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./IAccessControl.sol"; import {IAccessControl} from "./IAccessControl.sol";
import "../utils/Context.sol"; import {Context} from "../utils/Context.sol";
import "../utils/Strings.sol"; import {Strings} from "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol"; import {ERC165} from "../utils/introspection/ERC165.sol";
/** /**
* @dev Contract module that allows children to implement role-based access * @dev Contract module that allows children to implement role-based access
@ -64,8 +64,6 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 {
* The format of the revert reason is given by the following regular expression: * The format of the revert reason is given by the following regular expression:
* *
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*
* _Available since v4.1._
*/ */
modifier onlyRole(bytes32 role) { modifier onlyRole(bytes32 role) {
_checkRole(role); _checkRole(role);
@ -91,8 +89,6 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 {
* Overriding this function changes the behavior of the {onlyRole} modifier. * Overriding this function changes the behavior of the {onlyRole} modifier.
* *
* Format of the revert message is described in {_checkRole}. * Format of the revert message is described in {_checkRole}.
*
* _Available since v4.6._
*/ */
function _checkRole(bytes32 role) internal view virtual { function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender()); _checkRole(role, _msgSender());

@ -3,10 +3,11 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./AccessControl.sol"; import {AccessControl, IAccessControl} from "./AccessControl.sol";
import "./IAccessControlDefaultAdminRules.sol"; import {IAccessControlDefaultAdminRules} from "./IAccessControlDefaultAdminRules.sol";
import "../utils/math/SafeCast.sol"; import {SafeCast} from "../utils/math/SafeCast.sol";
import "../interfaces/IERC5313.sol"; import {Math} from "../utils/math/Math.sol";
import {IERC5313} from "../interfaces/IERC5313.sol";
/** /**
* @dev Extension of {AccessControl} that allows specifying special rules to manage * @dev Extension of {AccessControl} that allows specifying special rules to manage
@ -34,8 +35,6 @@ import "../interfaces/IERC5313.sol";
* ) {} * ) {}
* } * }
* ``` * ```
*
* _Available since v4.9._
*/ */
abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRules, IERC5313, AccessControl { abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRules, IERC5313, AccessControl {
// pending admin pair read/written together frequently // pending admin pair read/written together frequently

@ -3,9 +3,9 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./IAccessControlEnumerable.sol"; import {IAccessControlEnumerable} from "./IAccessControlEnumerable.sol";
import "./AccessControl.sol"; import {AccessControl} from "./AccessControl.sol";
import "../utils/structs/EnumerableSet.sol"; import {EnumerableSet} from "../utils/structs/EnumerableSet.sol";
/** /**
* @dev Extension of {AccessControl} that allows enumerating the members of each role. * @dev Extension of {AccessControl} that allows enumerating the members of each role.

@ -24,8 +24,6 @@ interface IAccessControl {
* *
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this. * {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/ */
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

@ -3,12 +3,10 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./IAccessControl.sol"; import {IAccessControl} from "./IAccessControl.sol";
/** /**
* @dev External interface of AccessControlDefaultAdminRules declared to support ERC165 detection. * @dev External interface of AccessControlDefaultAdminRules declared to support ERC165 detection.
*
* _Available since v4.9._
*/ */
interface IAccessControlDefaultAdminRules is IAccessControl { interface IAccessControlDefaultAdminRules is IAccessControl {
/** /**

@ -3,7 +3,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./IAccessControl.sol"; import {IAccessControl} from "./IAccessControl.sol";
/** /**
* @dev External interface of AccessControlEnumerable declared to support ERC165 detection. * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.

@ -3,7 +3,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../utils/Context.sol"; import {Context} from "../utils/Context.sol";
/** /**
* @dev Contract module which provides a basic access control mechanism, where * @dev Contract module which provides a basic access control mechanism, where

@ -3,7 +3,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./Ownable.sol"; import {Ownable} from "./Ownable.sol";
/** /**
* @dev Contract module which provides access control mechanism, where * @dev Contract module which provides access control mechanism, where

@ -2,9 +2,10 @@
// OpenZeppelin Contracts (last updated v4.9.0) (finance/VestingWallet.sol) // OpenZeppelin Contracts (last updated v4.9.0) (finance/VestingWallet.sol)
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC20/utils/SafeERC20.sol"; import {IERC20} from "../token/ERC20/IERC20.sol";
import "../utils/Address.sol"; import {SafeERC20} from "../token/ERC20/utils/SafeERC20.sol";
import "../utils/Context.sol"; import {Address} from "../utils/Address.sol";
import {Context} from "../utils/Context.sol";
/** /**
* @title VestingWallet * @title VestingWallet

@ -3,16 +3,17 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC721/IERC721Receiver.sol"; import {IERC721Receiver} from "../token/ERC721/IERC721Receiver.sol";
import "../token/ERC1155/IERC1155Receiver.sol"; import {IERC1155Receiver} from "../token/ERC1155/IERC1155Receiver.sol";
import "../utils/cryptography/ECDSA.sol"; import {EIP712} from "../utils/cryptography/EIP712.sol";
import "../utils/cryptography/EIP712.sol"; import {SignatureChecker} from "../utils/cryptography/SignatureChecker.sol";
import "../utils/introspection/ERC165.sol"; import {IERC165, ERC165} from "../utils/introspection/ERC165.sol";
import "../utils/math/SafeCast.sol"; import {SafeCast} from "../utils/math/SafeCast.sol";
import "../utils/structs/DoubleEndedQueue.sol"; import {DoubleEndedQueue} from "../utils/structs/DoubleEndedQueue.sol";
import "../utils/Address.sol"; import {Address} from "../utils/Address.sol";
import "../utils/Context.sol"; import {Context} from "../utils/Context.sol";
import "./IGovernor.sol"; import {Nonces} from "../utils/Nonces.sol";
import {IGovernor, IERC6372} from "./IGovernor.sol";
/** /**
* @dev Core of the governance system, designed to be extended though various modules. * @dev Core of the governance system, designed to be extended though various modules.
@ -22,15 +23,16 @@ import "./IGovernor.sol";
* - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote} * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote}
* - A voting module must implement {_getVotes} * - A voting module must implement {_getVotes}
* - Additionally, {votingPeriod} must also be implemented * - Additionally, {votingPeriod} must also be implemented
*
* _Available since v4.3._
*/ */
abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receiver, IERC1155Receiver { abstract contract Governor is Context, ERC165, EIP712, Nonces, IGovernor, IERC721Receiver, IERC1155Receiver {
using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque;
bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant BALLOT_TYPEHASH =
keccak256("Ballot(uint256 proposalId,uint8 support,address voter,uint256 nonce)");
bytes32 public constant EXTENDED_BALLOT_TYPEHASH = bytes32 public constant EXTENDED_BALLOT_TYPEHASH =
keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); keccak256(
"ExtendedBallot(uint256 proposalId,uint8 support,address voter,uint256 nonce,string reason,bytes params)"
);
// solhint-disable var-name-mixedcase // solhint-disable var-name-mixedcase
struct ProposalCore { struct ProposalCore {
@ -45,7 +47,6 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receive
bytes32 private constant _ALL_PROPOSAL_STATES_BITMAP = bytes32((2 ** (uint8(type(ProposalState).max) + 1)) - 1); bytes32 private constant _ALL_PROPOSAL_STATES_BITMAP = bytes32((2 ** (uint8(type(ProposalState).max) + 1)) - 1);
string private _name; string private _name;
/// @custom:oz-retyped-from mapping(uint256 => Governor.ProposalCore)
mapping(uint256 => ProposalCore) private _proposals; mapping(uint256 => ProposalCore) private _proposals;
// This queue keeps track of the governor operating on itself. Calls to functions protected by the // This queue keeps track of the governor operating on itself. Calls to functions protected by the
@ -514,16 +515,19 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receive
function castVoteBySig( function castVoteBySig(
uint256 proposalId, uint256 proposalId,
uint8 support, uint8 support,
uint8 v, address voter,
bytes32 r, bytes memory signature
bytes32 s
) public virtual override returns (uint256) { ) public virtual override returns (uint256) {
address voter = ECDSA.recover( bool valid = SignatureChecker.isValidSignatureNow(
_hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), voter,
v, _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support, voter, _useNonce(voter)))),
r, signature
s
); );
if (!valid) {
revert GovernorInvalidSignature(voter);
}
return _castVote(proposalId, voter, support, ""); return _castVote(proposalId, voter, support, "");
} }
@ -533,29 +537,33 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receive
function castVoteWithReasonAndParamsBySig( function castVoteWithReasonAndParamsBySig(
uint256 proposalId, uint256 proposalId,
uint8 support, uint8 support,
address voter,
string calldata reason, string calldata reason,
bytes memory params, bytes memory params,
uint8 v, bytes memory signature
bytes32 r,
bytes32 s
) public virtual override returns (uint256) { ) public virtual override returns (uint256) {
address voter = ECDSA.recover( bool valid = SignatureChecker.isValidSignatureNow(
voter,
_hashTypedDataV4( _hashTypedDataV4(
keccak256( keccak256(
abi.encode( abi.encode(
EXTENDED_BALLOT_TYPEHASH, EXTENDED_BALLOT_TYPEHASH,
proposalId, proposalId,
support, support,
voter,
_useNonce(voter),
keccak256(bytes(reason)), keccak256(bytes(reason)),
keccak256(params) keccak256(params)
) )
) )
), ),
v, signature
r,
s
); );
if (!valid) {
revert GovernorInvalidSignature(voter);
}
return _castVote(proposalId, voter, support, reason, params); return _castVote(proposalId, voter, support, reason, params);
} }

@ -3,13 +3,11 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../interfaces/IERC165.sol"; import {IERC165} from "../interfaces/IERC165.sol";
import "../interfaces/IERC6372.sol"; import {IERC6372} from "../interfaces/IERC6372.sol";
/** /**
* @dev Interface of the {Governor} core. * @dev Interface of the {Governor} core.
*
* _Available since v4.3._
*/ */
abstract contract IGovernor is IERC165, IERC6372 { abstract contract IGovernor is IERC165, IERC6372 {
enum ProposalState { enum ProposalState {
@ -80,6 +78,12 @@ abstract contract IGovernor is IERC165, IERC6372 {
*/ */
error GovernorInvalidVoteType(); error GovernorInvalidVoteType();
/**
* @dev The provided signature is not valid for the expected `voter`.
* If the `voter` is a contract, the signature is not valid using {IERC1271-isValidSignature}.
*/
error GovernorInvalidSignature(address voter);
/** /**
* @dev Emitted when a proposal is created. * @dev Emitted when a proposal is created.
*/ */
@ -348,30 +352,29 @@ abstract contract IGovernor is IERC165, IERC6372 {
) public virtual returns (uint256 balance); ) public virtual returns (uint256 balance);
/** /**
* @dev Cast a vote using the user's cryptographic signature. * @dev Cast a vote using the voter's signature, including ERC-1271 signature support.
* *
* Emits a {VoteCast} event. * Emits a {VoteCast} event.
*/ */
function castVoteBySig( function castVoteBySig(
uint256 proposalId, uint256 proposalId,
uint8 support, uint8 support,
uint8 v, address voter,
bytes32 r, bytes memory signature
bytes32 s
) public virtual returns (uint256 balance); ) public virtual returns (uint256 balance);
/** /**
* @dev Cast a vote with a reason and additional encoded parameters using the user's cryptographic signature. * @dev Cast a vote with a reason and additional encoded parameters using the voter's signature,
* including ERC-1271 signature support.
* *
* Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params.
*/ */
function castVoteWithReasonAndParamsBySig( function castVoteWithReasonAndParamsBySig(
uint256 proposalId, uint256 proposalId,
uint8 support, uint8 support,
address voter,
string calldata reason, string calldata reason,
bytes memory params, bytes memory params,
uint8 v, bytes memory signature
bytes32 r,
bytes32 s
) public virtual returns (uint256 balance); ) public virtual returns (uint256 balance);
} }

@ -92,8 +92,9 @@ In a governance system, the {TimelockController} contract is in charge of introd
* *Operation:* A transaction (or a set of transactions) that is the subject of the timelock. It has to be scheduled by a proposer and executed by an executor. The timelock enforces a minimum delay between the proposition and the execution (see xref:access-control.adoc#operation_lifecycle[operation lifecycle]). If the operation contains multiple transactions (batch mode), they are executed atomically. Operations are identified by the hash of their content. * *Operation:* A transaction (or a set of transactions) that is the subject of the timelock. It has to be scheduled by a proposer and executed by an executor. The timelock enforces a minimum delay between the proposition and the execution (see xref:access-control.adoc#operation_lifecycle[operation lifecycle]). If the operation contains multiple transactions (batch mode), they are executed atomically. Operations are identified by the hash of their content.
* *Operation status:* * *Operation status:*
** *Unset:* An operation that is not part of the timelock mechanism. ** *Unset:* An operation that is not part of the timelock mechanism.
** *Pending:* An operation that has been scheduled, before the timer expires. ** *Waiting:* An operation that has been scheduled, before the timer expires.
** *Ready:* An operation that has been scheduled, after the timer expires. ** *Ready:* An operation that has been scheduled, after the timer expires.
** *Pending:* An operation that is either waiting or ready.
** *Done:* An operation that has been executed. ** *Done:* An operation that has been executed.
* *Predecessor*: An (optional) dependency between operations. An operation can depend on another operation (its predecessor), forcing the execution order of these two operations. * *Predecessor*: An (optional) dependency between operations. An operation can depend on another operation (its predecessor), forcing the execution order of these two operations.
* *Role*: * *Role*:

@ -3,10 +3,11 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../access/AccessControl.sol"; import {AccessControl} from "../access/AccessControl.sol";
import "../token/ERC721/utils/ERC721Holder.sol"; import {ERC721Holder} from "../token/ERC721/utils/ERC721Holder.sol";
import "../token/ERC1155/utils/ERC1155Holder.sol"; import {ERC1155Holder} from "../token/ERC1155/utils/ERC1155Holder.sol";
import "../utils/Address.sol"; import {ERC1155Receiver} from "../token/ERC1155/utils/ERC1155Receiver.sol";
import {Address} from "../utils/Address.sol";
/** /**
* @dev Contract module which acts as a timelocked controller. When set as the * @dev Contract module which acts as a timelocked controller. When set as the
@ -20,8 +21,6 @@ import "../utils/Address.sol";
* is in charge of proposing (resp executing) operations. A common use case is * is in charge of proposing (resp executing) operations. A common use case is
* to position this {TimelockController} as the owner of a smart contract, with * to position this {TimelockController} as the owner of a smart contract, with
* a multisig or a DAO as the sole proposer. * a multisig or a DAO as the sole proposer.
*
* _Available since v3.3._
*/ */
contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder { contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE"); bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");
@ -34,7 +33,7 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
enum OperationState { enum OperationState {
Unset, Unset,
Pending, Waiting,
Ready, Ready,
Done Done
} }
@ -51,8 +50,12 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
/** /**
* @dev The current state of an operation is not as required. * @dev The current state of an operation is not as required.
* The `expectedStates` is a bitmap with the bits enabled for each OperationState enum position
* counting from right to left.
*
* See {_encodeStateBitmap}.
*/ */
error TimelockUnexpectedOperationState(bytes32 operationId, OperationState expected); error TimelockUnexpectedOperationState(bytes32 operationId, bytes32 expectedStates);
/** /**
* @dev The predecessor to an operation not yet done. * @dev The predecessor to an operation not yet done.
@ -165,30 +168,30 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
* @dev Returns whether an id correspond to a registered operation. This * @dev Returns whether an id correspond to a registered operation. This
* includes both Pending, Ready and Done operations. * includes both Pending, Ready and Done operations.
*/ */
function isOperation(bytes32 id) public view virtual returns (bool) { function isOperation(bytes32 id) public view returns (bool) {
return getTimestamp(id) > 0; return getOperationState(id) != OperationState.Unset;
} }
/** /**
* @dev Returns whether an operation is pending or not. Note that a "pending" operation may also be "ready". * @dev Returns whether an operation is pending or not. Note that a "pending" operation may also be "ready".
*/ */
function isOperationPending(bytes32 id) public view virtual returns (bool) { function isOperationPending(bytes32 id) public view returns (bool) {
return getTimestamp(id) > _DONE_TIMESTAMP; OperationState state = getOperationState(id);
return state == OperationState.Waiting || state == OperationState.Ready;
} }
/** /**
* @dev Returns whether an operation is ready for execution. Note that a "ready" operation is also "pending". * @dev Returns whether an operation is ready for execution. Note that a "ready" operation is also "pending".
*/ */
function isOperationReady(bytes32 id) public view virtual returns (bool) { function isOperationReady(bytes32 id) public view returns (bool) {
uint256 timestamp = getTimestamp(id); return getOperationState(id) == OperationState.Ready;
return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp;
} }
/** /**
* @dev Returns whether an operation is done or not. * @dev Returns whether an operation is done or not.
*/ */
function isOperationDone(bytes32 id) public view virtual returns (bool) { function isOperationDone(bytes32 id) public view returns (bool) {
return getTimestamp(id) == _DONE_TIMESTAMP; return getOperationState(id) == OperationState.Done;
} }
/** /**
@ -199,6 +202,22 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
return _timestamps[id]; return _timestamps[id];
} }
/**
* @dev Returns operation state.
*/
function getOperationState(bytes32 id) public view virtual returns (OperationState) {
uint256 timestamp = getTimestamp(id);
if (timestamp == 0) {
return OperationState.Unset;
} else if (timestamp == _DONE_TIMESTAMP) {
return OperationState.Done;
} else if (timestamp > block.timestamp) {
return OperationState.Waiting;
} else {
return OperationState.Ready;
}
}
/** /**
* @dev Returns the minimum delay for an operation to become valid. * @dev Returns the minimum delay for an operation to become valid.
* *
@ -297,7 +316,7 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
*/ */
function _schedule(bytes32 id, uint256 delay) private { function _schedule(bytes32 id, uint256 delay) private {
if (isOperation(id)) { if (isOperation(id)) {
revert TimelockUnexpectedOperationState(id, OperationState.Unset); revert TimelockUnexpectedOperationState(id, _encodeStateBitmap(OperationState.Unset));
} }
uint256 minDelay = getMinDelay(); uint256 minDelay = getMinDelay();
if (delay < minDelay) { if (delay < minDelay) {
@ -315,7 +334,10 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
*/ */
function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) { function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) {
if (!isOperationPending(id)) { if (!isOperationPending(id)) {
revert TimelockUnexpectedOperationState(id, OperationState.Pending); revert TimelockUnexpectedOperationState(
id,
_encodeStateBitmap(OperationState.Waiting) | _encodeStateBitmap(OperationState.Ready)
);
} }
delete _timestamps[id]; delete _timestamps[id];
@ -398,7 +420,7 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
*/ */
function _beforeCall(bytes32 id, bytes32 predecessor) private view { function _beforeCall(bytes32 id, bytes32 predecessor) private view {
if (!isOperationReady(id)) { if (!isOperationReady(id)) {
revert TimelockUnexpectedOperationState(id, OperationState.Ready); revert TimelockUnexpectedOperationState(id, _encodeStateBitmap(OperationState.Ready));
} }
if (predecessor != bytes32(0) && !isOperationDone(predecessor)) { if (predecessor != bytes32(0) && !isOperationDone(predecessor)) {
revert TimelockUnexecutedPredecessor(predecessor); revert TimelockUnexecutedPredecessor(predecessor);
@ -410,7 +432,7 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
*/ */
function _afterCall(bytes32 id) private { function _afterCall(bytes32 id) private {
if (!isOperationReady(id)) { if (!isOperationReady(id)) {
revert TimelockUnexpectedOperationState(id, OperationState.Ready); revert TimelockUnexpectedOperationState(id, _encodeStateBitmap(OperationState.Ready));
} }
_timestamps[id] = _DONE_TIMESTAMP; _timestamps[id] = _DONE_TIMESTAMP;
} }
@ -426,10 +448,26 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
* an operation where the timelock is the target and the data is the ABI-encoded call to this function. * an operation where the timelock is the target and the data is the ABI-encoded call to this function.
*/ */
function updateDelay(uint256 newDelay) external virtual { function updateDelay(uint256 newDelay) external virtual {
if (msg.sender != address(this)) { address sender = _msgSender();
revert TimelockUnauthorizedCaller(msg.sender); if (sender != address(this)) {
revert TimelockUnauthorizedCaller(sender);
} }
emit MinDelayChange(_minDelay, newDelay); emit MinDelayChange(_minDelay, newDelay);
_minDelay = newDelay; _minDelay = newDelay;
} }
/**
* @dev Encodes a `OperationState` into a `bytes32` representation where each bit enabled corresponds to
* the underlying position in the `OperationState` enum. For example:
*
* 0x000...1000
* ^^^^^^----- ...
* ^---- Done
* ^--- Ready
* ^-- Waiting
* ^- Unset
*/
function _encodeStateBitmap(OperationState operationState) internal pure returns (bytes32) {
return bytes32(1 << uint8(operationState));
}
} }

@ -3,10 +3,10 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../utils/math/SafeCast.sol"; import {SafeCast} from "../../utils/math/SafeCast.sol";
import "../extensions/IGovernorTimelock.sol"; import {IGovernorTimelock} from "../extensions/IGovernorTimelock.sol";
import "../Governor.sol"; import {IGovernor, Governor} from "../Governor.sol";
import "./IGovernorCompatibilityBravo.sol"; import {IGovernorCompatibilityBravo} from "./IGovernorCompatibilityBravo.sol";
/** /**
* @dev Compatibility layer that implements GovernorBravo compatibility on top of {Governor}. * @dev Compatibility layer that implements GovernorBravo compatibility on top of {Governor}.
@ -15,8 +15,6 @@ import "./IGovernorCompatibilityBravo.sol";
* through inheritance. It does not include token bindings, nor does it include any variable upgrade patterns. * through inheritance. It does not include token bindings, nor does it include any variable upgrade patterns.
* *
* NOTE: When using this module, you may need to enable the Solidity optimizer to avoid hitting the contract size limit. * NOTE: When using this module, you may need to enable the Solidity optimizer to avoid hitting the contract size limit.
*
* _Available since v4.3._
*/ */
abstract contract GovernorCompatibilityBravo is IGovernorTimelock, IGovernorCompatibilityBravo, Governor { abstract contract GovernorCompatibilityBravo is IGovernorTimelock, IGovernorCompatibilityBravo, Governor {
enum VoteType { enum VoteType {

@ -3,12 +3,10 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../IGovernor.sol"; import {IGovernor} from "../IGovernor.sol";
/** /**
* @dev Interface extension that adds missing functions to the {Governor} core to provide `GovernorBravo` compatibility. * @dev Interface extension that adds missing functions to the {Governor} core to provide `GovernorBravo` compatibility.
*
* _Available since v4.3._
*/ */
abstract contract IGovernorCompatibilityBravo is IGovernor { abstract contract IGovernorCompatibilityBravo is IGovernor {
/** /**

@ -3,12 +3,10 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../Governor.sol"; import {Governor} from "../Governor.sol";
/** /**
* @dev Extension of {Governor} for simple, 3 options, vote counting. * @dev Extension of {Governor} for simple, 3 options, vote counting.
*
* _Available since v4.3._
*/ */
abstract contract GovernorCountingSimple is Governor { abstract contract GovernorCountingSimple is Governor {
/** /**

@ -3,8 +3,8 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../Governor.sol"; import {Governor} from "../Governor.sol";
import "../../utils/math/Math.sol"; import {Math} from "../../utils/math/Math.sol";
/** /**
* @dev A module that ensures there is a minimum voting period after quorum is reached. This prevents a large voter from * @dev A module that ensures there is a minimum voting period after quorum is reached. This prevents a large voter from
@ -14,13 +14,10 @@ import "../../utils/math/Math.sol";
* If a vote causes quorum to be reached, the proposal's voting period may be extended so that it does not end before at * If a vote causes quorum to be reached, the proposal's voting period may be extended so that it does not end before at
* least a specified time has passed (the "vote extension" parameter). This parameter can be set through a governance * least a specified time has passed (the "vote extension" parameter). This parameter can be set through a governance
* proposal. * proposal.
*
* _Available since v4.5._
*/ */
abstract contract GovernorPreventLateQuorum is Governor { abstract contract GovernorPreventLateQuorum is Governor {
uint48 private _voteExtension; uint48 private _voteExtension;
/// @custom:oz-retyped-from mapping(uint256 => Timers.BlockNumber)
mapping(uint256 => uint48) private _extendedDeadlines; mapping(uint256 => uint48) private _extendedDeadlines;
/// @dev Emitted when a proposal deadline is pushed back due to reaching quorum late in its voting period. /// @dev Emitted when a proposal deadline is pushed back due to reaching quorum late in its voting period.

@ -3,12 +3,10 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../Governor.sol"; import {Governor} from "../Governor.sol";
/** /**
* @dev Extension of {Governor} for settings updatable through governance. * @dev Extension of {Governor} for settings updatable through governance.
*
* _Available since v4.4._
*/ */
abstract contract GovernorSettings is Governor { abstract contract GovernorSettings is Governor {
// amount of token // amount of token

@ -3,10 +3,12 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./IGovernorTimelock.sol"; import {IGovernorTimelock} from "./IGovernorTimelock.sol";
import "../Governor.sol"; import {IGovernor, Governor} from "../Governor.sol";
import "../../utils/math/SafeCast.sol"; import {SafeCast} from "../../utils/math/SafeCast.sol";
import "../../vendor/compound/ICompoundTimelock.sol"; import {ICompoundTimelock} from "../../vendor/compound/ICompoundTimelock.sol";
import {IERC165} from "../../interfaces/IERC165.sol";
import {Address} from "../../utils/Address.sol";
/** /**
* @dev Extension of {Governor} that binds the execution process to a Compound Timelock. This adds a delay, enforced by * @dev Extension of {Governor} that binds the execution process to a Compound Timelock. This adds a delay, enforced by
@ -17,13 +19,10 @@ import "../../vendor/compound/ICompoundTimelock.sol";
* Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus, * Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus,
* the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be * the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be
* inaccessible. * inaccessible.
*
* _Available since v4.3._
*/ */
abstract contract GovernorTimelockCompound is IGovernorTimelock, Governor { abstract contract GovernorTimelockCompound is IGovernorTimelock, Governor {
ICompoundTimelock private _timelock; ICompoundTimelock private _timelock;
/// @custom:oz-retyped-from mapping(uint256 => GovernorTimelockCompound.ProposalTimelock)
mapping(uint256 => uint256) private _proposalTimelocks; mapping(uint256 => uint256) private _proposalTimelocks;
/** /**

@ -3,9 +3,10 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./IGovernorTimelock.sol"; import {IGovernorTimelock} from "./IGovernorTimelock.sol";
import "../Governor.sol"; import {IGovernor, Governor} from "../Governor.sol";
import "../TimelockController.sol"; import {TimelockController} from "../TimelockController.sol";
import {IERC165} from "../../interfaces/IERC165.sol";
/** /**
* @dev Extension of {Governor} that binds the execution process to an instance of {TimelockController}. This adds a * @dev Extension of {Governor} that binds the execution process to an instance of {TimelockController}. This adds a
@ -20,8 +21,6 @@ import "../TimelockController.sol";
* grants them powers that they must be trusted or known not to use: 1) {onlyGovernance} functions like {relay} are * grants them powers that they must be trusted or known not to use: 1) {onlyGovernance} functions like {relay} are
* available to them through the timelock, and 2) approved governance proposals can be blocked by them, effectively * available to them through the timelock, and 2) approved governance proposals can be blocked by them, effectively
* executing a Denial of Service attack. This risk will be mitigated in a future release. * executing a Denial of Service attack. This risk will be mitigated in a future release.
*
* _Available since v4.3._
*/ */
abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { abstract contract GovernorTimelockControl is IGovernorTimelock, Governor {
TimelockController private _timelock; TimelockController private _timelock;

@ -3,13 +3,13 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../Governor.sol"; import {Governor} from "../Governor.sol";
import "../../interfaces/IERC5805.sol"; import {IVotes} from "../utils/IVotes.sol";
import {IERC5805} from "../../interfaces/IERC5805.sol";
import {SafeCast} from "../../utils/math/SafeCast.sol";
/** /**
* @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} token. * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} token.
*
* _Available since v4.3._
*/ */
abstract contract GovernorVotes is Governor { abstract contract GovernorVotes is Governor {
IERC5805 public immutable token; IERC5805 public immutable token;

@ -3,20 +3,17 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./GovernorVotes.sol"; import {GovernorVotes} from "./GovernorVotes.sol";
import "../../utils/math/SafeCast.sol"; import {SafeCast} from "../../utils/math/SafeCast.sol";
import "../../utils/structs/Checkpoints.sol"; import {Checkpoints} from "../../utils/structs/Checkpoints.sol";
/** /**
* @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a
* fraction of the total supply. * fraction of the total supply.
*
* _Available since v4.3._
*/ */
abstract contract GovernorVotesQuorumFraction is GovernorVotes { abstract contract GovernorVotesQuorumFraction is GovernorVotes {
using Checkpoints for Checkpoints.Trace224; using Checkpoints for Checkpoints.Trace224;
/// @custom:oz-retyped-from Checkpoints.History
Checkpoints.Trace224 private _quorumNumeratorHistory; Checkpoints.Trace224 private _quorumNumeratorHistory;
event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator); event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator);

@ -3,12 +3,10 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../IGovernor.sol"; import {IGovernor} from "../IGovernor.sol";
/** /**
* @dev Extension of the {IGovernor} for timelock supporting modules. * @dev Extension of the {IGovernor} for timelock supporting modules.
*
* _Available since v4.3._
*/ */
abstract contract IGovernorTimelock is IGovernor { abstract contract IGovernorTimelock is IGovernor {
/** /**

@ -4,8 +4,6 @@ pragma solidity ^0.8.19;
/** /**
* @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.
*
* _Available since v4.5._
*/ */
interface IVotes { interface IVotes {
/** /**
@ -19,9 +17,9 @@ interface IVotes {
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
/** /**
* @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of voting units.
*/ */
event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); event DelegateVotesChanged(address indexed delegate, uint256 previousVotes, uint256 newVotes);
/** /**
* @dev Returns the current amount of votes that `account` has. * @dev Returns the current amount of votes that `account` has.

@ -2,11 +2,13 @@
// OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/Votes.sol) // OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/Votes.sol)
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../interfaces/IERC5805.sol"; import {IERC5805} from "../../interfaces/IERC5805.sol";
import "../../utils/Context.sol"; import {Context} from "../../utils/Context.sol";
import "../../utils/Nonces.sol"; import {Nonces} from "../../utils/Nonces.sol";
import "../../utils/cryptography/EIP712.sol"; import {EIP712} from "../../utils/cryptography/EIP712.sol";
import "../../utils/structs/Checkpoints.sol"; import {Checkpoints} from "../../utils/structs/Checkpoints.sol";
import {SafeCast} from "../../utils/math/SafeCast.sol";
import {ECDSA} from "../../utils/cryptography/ECDSA.sol";
/** /**
* @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be * @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be
@ -25,8 +27,6 @@ import "../../utils/structs/Checkpoints.sol";
* When using this module the derived contract must implement {_getVotingUnits} (for example, make it return * When using this module the derived contract must implement {_getVotingUnits} (for example, make it return
* {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the * {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the
* previous example, it would be included in {ERC721-_beforeTokenTransfer}). * previous example, it would be included in {ERC721-_beforeTokenTransfer}).
*
* _Available since v4.5._
*/ */
abstract contract Votes is Context, EIP712, Nonces, IERC5805 { abstract contract Votes is Context, EIP712, Nonces, IERC5805 {
using Checkpoints for Checkpoints.Trace224; using Checkpoints for Checkpoints.Trace224;
@ -36,10 +36,8 @@ abstract contract Votes is Context, EIP712, Nonces, IERC5805 {
mapping(address => address) private _delegation; mapping(address => address) private _delegation;
/// @custom:oz-retyped-from mapping(address => Checkpoints.History)
mapping(address => Checkpoints.Trace224) private _delegateCheckpoints; mapping(address => Checkpoints.Trace224) private _delegateCheckpoints;
/// @custom:oz-retyped-from Checkpoints.History
Checkpoints.Trace224 private _totalCheckpoints; Checkpoints.Trace224 private _totalCheckpoints;
/** /**

@ -3,4 +3,4 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC1155/IERC1155.sol"; import {IERC1155} from "../token/ERC1155/IERC1155.sol";

@ -3,4 +3,4 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC1155/extensions/IERC1155MetadataURI.sol"; import {IERC1155MetadataURI} from "../token/ERC1155/extensions/IERC1155MetadataURI.sol";

@ -3,4 +3,4 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC1155/IERC1155Receiver.sol"; import {IERC1155Receiver} from "../token/ERC1155/IERC1155Receiver.sol";

@ -6,8 +6,6 @@ pragma solidity ^0.8.19;
/** /**
* @dev Interface of the ERC1271 standard signature validation method for * @dev Interface of the ERC1271 standard signature validation method for
* contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
*
* _Available since v4.1._
*/ */
interface IERC1271 { interface IERC1271 {
/** /**

@ -3,8 +3,8 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./IERC20.sol"; import {IERC20} from "./IERC20.sol";
import "./IERC165.sol"; import {IERC165} from "./IERC165.sol";
/** /**
* @dev Interface of an ERC1363 compliant contract, as defined in the * @dev Interface of an ERC1363 compliant contract, as defined in the

@ -3,4 +3,4 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../utils/introspection/IERC165.sol"; import {IERC165} from "../utils/introspection/IERC165.sol";

@ -5,8 +5,6 @@ pragma solidity ^0.8.19;
/** /**
* @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
*
* _Available since v4.8.3._
*/ */
interface IERC1967 { interface IERC1967 {
/** /**

@ -3,4 +3,4 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC20/IERC20.sol"; import {IERC20} from "../token/ERC20/IERC20.sol";

@ -3,4 +3,4 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC20/extensions/IERC20Metadata.sol"; import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol";

@ -5,8 +5,6 @@ pragma solidity ^0.8.19;
/** /**
* @dev ERC-2309: ERC-721 Consecutive Transfer Extension. * @dev ERC-2309: ERC-721 Consecutive Transfer Extension.
*
* _Available since v4.8._
*/ */
interface IERC2309 { interface IERC2309 {
/** /**

@ -3,6 +3,6 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC20/extensions/IERC20Permit.sol"; import {IERC20Permit} from "../token/ERC20/extensions/IERC20Permit.sol";
interface IERC2612 is IERC20Permit {} interface IERC2612 is IERC20Permit {}

@ -3,15 +3,13 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../utils/introspection/IERC165.sol"; import {IERC165} from "../utils/introspection/IERC165.sol";
/** /**
* @dev Interface for the NFT Royalty Standard. * @dev Interface for the NFT Royalty Standard.
* *
* A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
* support for royalty payments across all NFT marketplaces and ecosystem participants. * support for royalty payments across all NFT marketplaces and ecosystem participants.
*
* _Available since v4.5._
*/ */
interface IERC2981 is IERC165 { interface IERC2981 is IERC165 {
/** /**

@ -3,5 +3,5 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./IERC3156FlashBorrower.sol"; import {IERC3156FlashBorrower} from "./IERC3156FlashBorrower.sol";
import "./IERC3156FlashLender.sol"; import {IERC3156FlashLender} from "./IERC3156FlashLender.sol";

@ -6,8 +6,6 @@ pragma solidity ^0.8.19;
/** /**
* @dev Interface of the ERC3156 FlashBorrower, as defined in * @dev Interface of the ERC3156 FlashBorrower, as defined in
* https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
*
* _Available since v4.1._
*/ */
interface IERC3156FlashBorrower { interface IERC3156FlashBorrower {
/** /**

@ -3,13 +3,11 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./IERC3156FlashBorrower.sol"; import {IERC3156FlashBorrower} from "./IERC3156FlashBorrower.sol";
/** /**
* @dev Interface of the ERC3156 FlashLender, as defined in * @dev Interface of the ERC3156 FlashLender, as defined in
* https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
*
* _Available since v4.1._
*/ */
interface IERC3156FlashLender { interface IERC3156FlashLender {
/** /**

@ -3,14 +3,12 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC20/IERC20.sol"; import {IERC20} from "../token/ERC20/IERC20.sol";
import "../token/ERC20/extensions/IERC20Metadata.sol"; import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol";
/** /**
* @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in * @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in
* https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].
*
* _Available since v4.7._
*/ */
interface IERC4626 is IERC20, IERC20Metadata { interface IERC4626 is IERC20, IERC20Metadata {
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);

@ -3,8 +3,8 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./IERC165.sol"; import {IERC165} from "./IERC165.sol";
import "./IERC721.sol"; import {IERC721} from "./IERC721.sol";
/// @title EIP-721 Metadata Update Extension /// @title EIP-721 Metadata Update Extension
interface IERC4906 is IERC165, IERC721 { interface IERC4906 is IERC165, IERC721 {

@ -7,8 +7,6 @@ pragma solidity ^0.8.19;
* @dev Interface for the Light Contract Ownership Standard. * @dev Interface for the Light Contract Ownership Standard.
* *
* A standardized minimal interface required to identify an account that controls a contract * A standardized minimal interface required to identify an account that controls a contract
*
* _Available since v4.9._
*/ */
interface IERC5313 { interface IERC5313 {
/** /**

@ -3,7 +3,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../governance/utils/IVotes.sol"; import {IVotes} from "../governance/utils/IVotes.sol";
import "./IERC6372.sol"; import {IERC6372} from "./IERC6372.sol";
interface IERC5805 is IERC6372, IVotes {} interface IERC5805 is IERC6372, IVotes {}

@ -3,4 +3,4 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC721/IERC721.sol"; import {IERC721} from "../token/ERC721/IERC721.sol";

@ -3,4 +3,4 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC721/extensions/IERC721Enumerable.sol"; import {IERC721Enumerable} from "../token/ERC721/extensions/IERC721Enumerable.sol";

@ -3,4 +3,4 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC721/extensions/IERC721Metadata.sol"; import {IERC721Metadata} from "../token/ERC721/extensions/IERC721Metadata.sol";

@ -3,4 +3,4 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC721/IERC721Receiver.sol"; import {IERC721Receiver} from "../token/ERC721/IERC721Receiver.sol";

@ -118,6 +118,7 @@ interface IERC1155Errors {
* @param sender Address whose tokens are being transferred. * @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account. * @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer. * @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/ */
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

@ -3,7 +3,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../utils/Context.sol"; import {Context} from "../utils/Context.sol";
/** /**
* @dev Context variant with ERC2771 support. * @dev Context variant with ERC2771 support.

@ -0,0 +1,308 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (metatx/ERC2771Forwarder.sol)
pragma solidity ^0.8.19;
import {ECDSA} from "../utils/cryptography/ECDSA.sol";
import {EIP712} from "../utils/cryptography/EIP712.sol";
import {Nonces} from "../utils/Nonces.sol";
import {Address} from "../utils/Address.sol";
/**
* @dev A forwarder compatible with ERC2771 contracts. See {ERC2771Context}.
*
* This forwarder operates on forward requests that include:
*
* * `from`: An address to operate on behalf of. It is required to be equal to the request signer.
* * `to`: The address that should be called.
* * `value`: The amount of native token to attach with the requested call.
* * `gas`: The amount of gas limit that will be forwarded with the requested call.
* * `nonce`: A unique transaction ordering identifier to avoid replayability and request invalidation.
* * `deadline`: A timestamp after which the request is not executable anymore.
* * `data`: Encoded `msg.data` to send with the requested call.
*
* Relayers are able to submit batches if they are processing a high volume of requests. With high
* throughput, relayers may run into limitations of the chain such as limits on the number of
* transactions in the mempool. In these cases the recommendation is to distribute the load among
* multiple accounts.
*
* ==== Security Considerations
*
* If a relayer submits a forward request, it should be willing to pay up to 100% of the gas amount
* specified in the request. This contract does not implement any kind of retribution for this gas,
* and it is assumed that there is an out of band incentive for relayers to pay for execution on
* behalf of signers. Often, the relayer is operated by a project that will consider it a user
* acquisition cost.
*
* By offering to pay for gas, relayers are at risk of having that gas used by an attacker toward
* some other purpose that is not aligned with the expected out of band incentives. If you operate a
* relayer, consider whitelisting target contracts and function selectors. When relaying ERC-721 or
* ERC-1155 transfers specifically, consider rejecting the use of the `data` field, since it can be
* used to execute arbitrary code.
*/
contract ERC2771Forwarder is EIP712, Nonces {
using ECDSA for bytes32;
struct ForwardRequestData {
address from;
address to;
uint256 value;
uint256 gas;
uint48 deadline;
bytes data;
bytes signature;
}
bytes32 private constant _FORWARD_REQUEST_TYPEHASH =
keccak256(
"ForwardRequest(address from,address to,uint256 value,uint256 gas,uint256 nonce,uint48 deadline,bytes data)"
);
/**
* @dev Emitted when a `ForwardRequest` is executed.
*
* NOTE: An unsuccessful forward request could be due to an invalid signature, an expired deadline,
* or simply a revert in the requested call. The contract guarantees that the relayer is not able to force
* the requested call to run out of gas.
*/
event ExecutedForwardRequest(address indexed signer, uint256 nonce, bool success);
/**
* @dev The request `from` doesn't match with the recovered `signer`.
*/
error ERC2771ForwarderInvalidSigner(address signer, address from);
/**
* @dev The `requestedValue` doesn't match with the available `msgValue`.
*/
error ERC2771ForwarderMismatchedValue(uint256 requestedValue, uint256 msgValue);
/**
* @dev The request `deadline` has expired.
*/
error ERC2771ForwarderExpiredRequest(uint48 deadline);
/**
* @dev See {EIP712-constructor}.
*/
constructor(string memory name) EIP712(name, "1") {}
/**
* @dev Returns `true` if a request is valid for a provided `signature` at the current block timestamp.
*
* A transaction is considered valid when it hasn't expired (deadline is not met), and the signer
* matches the `from` parameter of the signed request.
*
* NOTE: A request may return false here but it won't cause {executeBatch} to revert if a refund
* receiver is provided.
*/
function verify(ForwardRequestData calldata request) public view virtual returns (bool) {
(bool alive, bool signerMatch, ) = _validate(request);
return alive && signerMatch;
}
/**
* @dev Executes a `request` on behalf of `signature`'s signer using the ERC-2771 protocol. The gas
* provided to the requested call may not be exactly the amount requested, but the call will not run
* out of gas. Will revert if the request is invalid or the call reverts, in this case the nonce is not consumed.
*
* Requirements:
*
* - The request value should be equal to the provided `msg.value`.
* - The request should be valid according to {verify}.
*/
function execute(ForwardRequestData calldata request) public payable virtual {
// We make sure that msg.value and request.value match exactly.
// If the request is invalid or the call reverts, this whole function
// will revert, ensuring value isn't stuck.
if (msg.value != request.value) {
revert ERC2771ForwarderMismatchedValue(request.value, msg.value);
}
if (!_execute(request, true)) {
revert Address.FailedInnerCall();
}
}
/**
* @dev Batch version of {execute} with optional refunding and atomic execution.
*
* In case a batch contains at least one invalid request (see {verify}), the
* request will be skipped and the `refundReceiver` parameter will receive back the
* unused requested value at the end of the execution. This is done to prevent reverting
* the entire batch when a request is invalid or has already been submitted.
*
* If the `refundReceiver` is the `address(0)`, this function will revert when at least
* one of the requests was not valid instead of skipping it. This could be useful if
* a batch is required to get executed atomically (at least at the top-level). For example,
* refunding (and thus atomicity) can be opt-out if the relayer is using a service that avoids
* including reverted transactions.
*
* Requirements:
*
* - The sum of the requests' values should be equal to the provided `msg.value`.
* - All of the requests should be valid (see {verify}) when `refundReceiver` is the zero address.
*
* NOTE: Setting a zero `refundReceiver` guarantees an all-or-nothing requests execution only for
* the first-level forwarded calls. In case a forwarded request calls to a contract with another
* subcall, the second-level call may revert without the top-level call reverting.
*/
function executeBatch(
ForwardRequestData[] calldata requests,
address payable refundReceiver
) public payable virtual {
bool atomic = refundReceiver == address(0);
uint256 requestsValue;
uint256 refundValue;
for (uint256 i; i < requests.length; ++i) {
requestsValue += requests[i].value;
bool success = _execute(requests[i], atomic);
if (!success) {
refundValue += requests[i].value;
}
}
// The batch should revert if there's a mismatched msg.value provided
// to avoid request value tampering
if (requestsValue != msg.value) {
revert ERC2771ForwarderMismatchedValue(requestsValue, msg.value);
}
// Some requests with value were invalid (possibly due to frontrunning).
// To avoid leaving ETH in the contract this value is refunded.
if (refundValue != 0) {
// We know refundReceiver != address(0) && requestsValue == msg.value
// meaning we can ensure refundValue is not taken from the original contract's balance
// and refundReceiver is a known account.
Address.sendValue(refundReceiver, refundValue);
}
}
/**
* @dev Validates if the provided request can be executed at current block timestamp with
* the given `request.signature` on behalf of `request.signer`.
*/
function _validate(
ForwardRequestData calldata request
) internal view virtual returns (bool alive, bool signerMatch, address signer) {
signer = _recoverForwardRequestSigner(request);
return (request.deadline >= block.timestamp, signer == request.from, signer);
}
/**
* @dev Recovers the signer of an EIP712 message hash for a forward `request` and its corresponding `signature`.
* See {ECDSA-recover}.
*/
function _recoverForwardRequestSigner(ForwardRequestData calldata request) internal view virtual returns (address) {
return
_hashTypedDataV4(
keccak256(
abi.encode(
_FORWARD_REQUEST_TYPEHASH,
request.from,
request.to,
request.value,
request.gas,
nonces(request.from),
request.deadline,
keccak256(request.data)
)
)
).recover(request.signature);
}
/**
* @dev Validates and executes a signed request returning the request call `success` value.
*
* Internal function without msg.value validation.
*
* Requirements:
*
* - The caller must have provided enough gas to forward with the call.
* - The request must be valid (see {verify}) if the `requireValidRequest` is true.
*
* Emits an {ExecutedForwardRequest} event.
*
* IMPORTANT: Using this function doesn't check that all the `msg.value` was sent, potentially
* leaving value stuck in the contract.
*/
function _execute(
ForwardRequestData calldata request,
bool requireValidRequest
) internal virtual returns (bool success) {
(bool alive, bool signerMatch, address signer) = _validate(request);
// Need to explicitly specify if a revert is required since non-reverting is default for
// batches and reversion is opt-in since it could be useful in some scenarios
if (requireValidRequest) {
if (!alive) {
revert ERC2771ForwarderExpiredRequest(request.deadline);
}
if (!signerMatch) {
revert ERC2771ForwarderInvalidSigner(signer, request.from);
}
}
// Ignore an invalid request because requireValidRequest = false
if (signerMatch && alive) {
// Nonce should be used before the call to prevent reusing by reentrancy
uint256 currentNonce = _useNonce(signer);
(success, ) = request.to.call{gas: request.gas, value: request.value}(
abi.encodePacked(request.data, request.from)
);
_checkForwardedGas(request);
emit ExecutedForwardRequest(signer, currentNonce, success);
}
}
/**
* @dev Checks if the requested gas was correctly forwarded to the callee.
*
* As a consequence of https://eips.ethereum.org/EIPS/eip-150[EIP-150]:
* - At most `gasleft() - floor(gasleft() / 64)` is forwarded to the callee.
* - At least `floor(gasleft() / 64)` is kept in the caller.
*
* It reverts consuming all the available gas if the forwarded gas is not the requested gas.
*
* IMPORTANT: This function should be called exactly the end of the forwarded call. Any gas consumed
* in between will make room for bypassing this check.
*/
function _checkForwardedGas(ForwardRequestData calldata request) private view {
// To avoid insufficient gas griefing attacks, as referenced in https://ronan.eth.limo/blog/ethereum-gas-dangers/
//
// A malicious relayer can attempt to shrink the gas forwarded so that the underlying call reverts out-of-gas
// but the forwarding itself still succeeds. In order to make sure that the subcall received sufficient gas,
// we will inspect gasleft() after the forwarding.
//
// Let X be the gas available before the subcall, such that the subcall gets at most X * 63 / 64.
// We can't know X after CALL dynamic costs, but we want it to be such that X * 63 / 64 >= req.gas.
// Let Y be the gas used in the subcall. gasleft() measured immediately after the subcall will be gasleft() = X - Y.
// If the subcall ran out of gas, then Y = X * 63 / 64 and gasleft() = X - Y = X / 64.
// Under this assumption req.gas / 63 > gasleft() is true is true if and only if
// req.gas / 63 > X / 64, or equivalently req.gas > X * 63 / 64.
// This means that if the subcall runs out of gas we are able to detect that insufficient gas was passed.
//
// We will now also see that req.gas / 63 > gasleft() implies that req.gas >= X * 63 / 64.
// The contract guarantees Y <= req.gas, thus gasleft() = X - Y >= X - req.gas.
// - req.gas / 63 > gasleft()
// - req.gas / 63 >= X - req.gas
// - req.gas >= X * 63 / 64
// In other words if req.gas < X * 63 / 64 then req.gas / 63 <= gasleft(), thus if the relayer behaves honestly
// the forwarding does not revert.
if (gasleft() < request.gas / 63) {
// We explicitly trigger invalid opcode to consume all gas and bubble-up the effects, since
// neither revert or assert consume all gas since Solidity 0.8.0
// https://docs.soliditylang.org/en/v0.8.0/control-structures.html#panic-via-assert-and-error-via-require
/// @solidity memory-safe-assembly
assembly {
invalid()
}
}
}
}

@ -1,104 +0,0 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (metatx/MinimalForwarder.sol)
pragma solidity ^0.8.19;
import "../utils/cryptography/ECDSA.sol";
import "../utils/cryptography/EIP712.sol";
/**
* @dev Simple minimal forwarder to be used together with an ERC2771 compatible contract. See {ERC2771Context}.
*
* MinimalForwarder is mainly meant for testing, as it is missing features to be a good production-ready forwarder. This
* contract does not intend to have all the properties that are needed for a sound forwarding system. A fully
* functioning forwarding system with good properties requires more complexity. We suggest you look at other projects
* such as the GSN which do have the goal of building a system like that.
*/
contract MinimalForwarder is EIP712 {
using ECDSA for bytes32;
struct ForwardRequest {
address from;
address to;
uint256 value;
uint256 gas;
uint256 nonce;
bytes data;
}
bytes32 private constant _TYPEHASH =
keccak256("ForwardRequest(address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data)");
mapping(address => uint256) private _nonces;
/**
* @dev The request `from` doesn't match with the recovered `signer`.
*/
error MinimalForwarderInvalidSigner(address signer, address from);
/**
* @dev The request nonce doesn't match with the `current` nonce for the request signer.
*/
error MinimalForwarderInvalidNonce(address signer, uint256 current);
constructor() EIP712("MinimalForwarder", "0.0.1") {}
function getNonce(address from) public view returns (uint256) {
return _nonces[from];
}
function verify(ForwardRequest calldata req, bytes calldata signature) public view returns (bool) {
address signer = _recover(req, signature);
(bool correctFrom, bool correctNonce) = _validateReq(req, signer);
return correctFrom && correctNonce;
}
function execute(
ForwardRequest calldata req,
bytes calldata signature
) public payable returns (bool, bytes memory) {
address signer = _recover(req, signature);
(bool correctFrom, bool correctNonce) = _validateReq(req, signer);
if (!correctFrom) {
revert MinimalForwarderInvalidSigner(signer, req.from);
}
if (!correctNonce) {
revert MinimalForwarderInvalidNonce(signer, _nonces[req.from]);
}
_nonces[req.from] = req.nonce + 1;
(bool success, bytes memory returndata) = req.to.call{gas: req.gas, value: req.value}(
abi.encodePacked(req.data, req.from)
);
// Validate that the relayer has sent enough gas for the call.
// See https://ronan.eth.limo/blog/ethereum-gas-dangers/
if (gasleft() <= req.gas / 63) {
// We explicitly trigger invalid opcode to consume all gas and bubble-up the effects, since
// neither revert or assert consume all gas since Solidity 0.8.0
// https://docs.soliditylang.org/en/v0.8.0/control-structures.html#panic-via-assert-and-error-via-require
/// @solidity memory-safe-assembly
assembly {
invalid()
}
}
return (success, returndata);
}
function _recover(ForwardRequest calldata req, bytes calldata signature) internal view returns (address) {
return
_hashTypedDataV4(
keccak256(abi.encode(_TYPEHASH, req.from, req.to, req.value, req.gas, req.nonce, keccak256(req.data)))
).recover(signature);
}
function _validateReq(
ForwardRequest calldata req,
address signer
) internal view returns (bool correctFrom, bool correctNonce) {
return (signer == req.from, _nonces[req.from] == req.nonce);
}
}

@ -9,4 +9,4 @@ NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/
== Utils == Utils
{{MinimalForwarder}} {{ERC2771Forwarder}}

@ -2,7 +2,7 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import "../utils/Address.sol"; import {Address} from "../utils/Address.sol";
/** /**
* @dev A mock to expose `Address`'s functions with function pointers. * @dev A mock to expose `Address`'s functions with function pointers.

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../utils/Arrays.sol"; import {Arrays} from "../utils/Arrays.sol";
contract Uint256ArraysMock { contract Uint256ArraysMock {
using Arrays for uint256[]; using Arrays for uint256[];

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../utils/Context.sol"; import {Context} from "../utils/Context.sol";
contract ContextMock is Context { contract ContextMock is Context {
event Sender(address sender); event Sender(address sender);

@ -2,7 +2,8 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../proxy/ERC1967/ERC1967Utils.sol"; import {ERC1967Utils} from "../proxy/ERC1967/ERC1967Utils.sol";
import {StorageSlot} from "../utils/StorageSlot.sol";
abstract contract Impl { abstract contract Impl {
function version() public pure virtual returns (string memory); function version() public pure virtual returns (string memory);

@ -2,8 +2,8 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../utils/cryptography/ECDSA.sol"; import {ECDSA} from "../utils/cryptography/ECDSA.sol";
import "../utils/cryptography/EIP712.sol"; import {EIP712} from "../utils/cryptography/EIP712.sol";
abstract contract EIP712Verifier is EIP712 { abstract contract EIP712Verifier is EIP712 {
function verify(bytes memory signature, address signer, address mailTo, string memory mailContents) external view { function verify(bytes memory signature, address signer, address mailTo, string memory mailContents) external view {

@ -2,9 +2,9 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../access/Ownable.sol"; import {Ownable} from "../access/Ownable.sol";
import "../interfaces/IERC1271.sol"; import {IERC1271} from "../interfaces/IERC1271.sol";
import "../utils/cryptography/ECDSA.sol"; import {ECDSA} from "../utils/cryptography/ECDSA.sol";
contract ERC1271WalletMock is Ownable, IERC1271 { contract ERC1271WalletMock is Ownable, IERC1271 {
constructor(address originalOwner) Ownable(originalOwner) {} constructor(address originalOwner) Ownable(originalOwner) {}

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../utils/introspection/IERC165.sol"; import {IERC165} from "../../utils/introspection/IERC165.sol";
/** /**
* https://eips.ethereum.org/EIPS/eip-214#specification * https://eips.ethereum.org/EIPS/eip-214#specification

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../utils/introspection/IERC165.sol"; import {IERC165} from "../../utils/introspection/IERC165.sol";
contract ERC165ReturnBombMock is IERC165 { contract ERC165ReturnBombMock is IERC165 {
function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { function supportsInterface(bytes4 interfaceId) public pure override returns (bool) {

@ -2,8 +2,9 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./ContextMock.sol"; import {ContextMock} from "./ContextMock.sol";
import "../metatx/ERC2771Context.sol"; import {Context} from "../utils/Context.sol";
import {ERC2771Context} from "../metatx/ERC2771Context.sol";
// By inheriting from ERC2771Context, Context's internal functions are overridden automatically // By inheriting from ERC2771Context, Context's internal functions are overridden automatically
contract ERC2771ContextMock is ContextMock, ERC2771Context { contract ERC2771ContextMock is ContextMock, ERC2771Context {

@ -2,9 +2,9 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../token/ERC20/IERC20.sol"; import {IERC20} from "../token/ERC20/IERC20.sol";
import "../interfaces/IERC3156.sol"; import {IERC3156FlashBorrower} from "../interfaces/IERC3156.sol";
import "../utils/Address.sol"; import {Address} from "../utils/Address.sol";
/** /**
* @dev WARNING: this IERC3156FlashBorrower mock implementation is for testing purposes ONLY. * @dev WARNING: this IERC3156FlashBorrower mock implementation is for testing purposes ONLY.

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../proxy/utils/Initializable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol";
/** /**
* @title InitializableMock * @title InitializableMock

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "./token/ERC20MulticallMock.sol"; import {ERC20MulticallMock} from "./token/ERC20MulticallMock.sol";
contract MulticallTest { contract MulticallTest {
function checkReturnValues( function checkReturnValues(

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../proxy/utils/Initializable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol";
// Sample contracts showing upgradeability with multiple inheritance. // Sample contracts showing upgradeability with multiple inheritance.
// Child contract inherits from Father and Mother contracts, and Father extends from Gramps. // Child contract inherits from Father and Mother contracts, and Father extends from Gramps.

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../security/Pausable.sol"; import {Pausable} from "../security/Pausable.sol";
contract PausableMock is Pausable { contract PausableMock is Pausable {
bool public drasticMeasureTaken; bool public drasticMeasureTaken;

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../utils/Context.sol"; import {Context} from "../utils/Context.sol";
contract ReentrancyAttack is Context { contract ReentrancyAttack is Context {
function callSender(bytes calldata data) public { function callSender(bytes calldata data) public {

@ -2,8 +2,8 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../security/ReentrancyGuard.sol"; import {ReentrancyGuard} from "../security/ReentrancyGuard.sol";
import "./ReentrancyAttack.sol"; import {ReentrancyAttack} from "./ReentrancyAttack.sol";
contract ReentrancyMock is ReentrancyGuard { contract ReentrancyMock is ReentrancyGuard {
uint256 public counter; uint256 public counter;

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../proxy/utils/Initializable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol";
contract Implementation1 is Initializable { contract Implementation1 is Initializable {
uint256 internal _value; uint256 internal _value;

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../proxy/utils/Initializable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol";
/** /**
* @title MigratableMockV1 * @title MigratableMockV1

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../utils/StorageSlot.sol"; import {StorageSlot} from "../utils/StorageSlot.sol";
contract StorageSlotMock { contract StorageSlotMock {
using StorageSlot for *; using StorageSlot for *;

@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../utils/Address.sol"; import {Address} from "../utils/Address.sol";
contract TimelockReentrant { contract TimelockReentrant {
address private _reenterTarget; address private _reenterTarget;

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../governance/utils/Votes.sol"; import {Votes} from "../governance/utils/Votes.sol";
abstract contract VotesMock is Votes { abstract contract VotesMock is Votes {
mapping(address => uint256) private _votingUnits; mapping(address => uint256) private _votingUnits;

@ -2,7 +2,10 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../token/ERC20/extensions/ERC4626.sol"; import {IERC20} from "../../token/ERC20/IERC20.sol";
import {ERC4626} from "../../token/ERC20/extensions/ERC4626.sol";
import {SafeERC20} from "../../token/ERC20/utils/SafeERC20.sol";
import {Math} from "../../utils/math/Math.sol";
abstract contract ERC4626Fees is ERC4626 { abstract contract ERC4626Fees is ERC4626 {
using Math for uint256; using Math for uint256;

@ -1,11 +1,14 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../../governance/Governor.sol"; import {IGovernor, Governor} from "../../../governance/Governor.sol";
import "../../../governance/compatibility/GovernorCompatibilityBravo.sol"; import {GovernorCompatibilityBravo} from "../../../governance/compatibility/GovernorCompatibilityBravo.sol";
import "../../../governance/extensions/GovernorVotes.sol"; import {GovernorVotes} from "../../../governance/extensions/GovernorVotes.sol";
import "../../../governance/extensions/GovernorVotesQuorumFraction.sol"; import {GovernorVotesQuorumFraction} from "../../../governance/extensions/GovernorVotesQuorumFraction.sol";
import "../../../governance/extensions/GovernorTimelockControl.sol"; import {GovernorTimelockControl} from "../../../governance/extensions/GovernorTimelockControl.sol";
import {TimelockController} from "../../../governance/TimelockController.sol";
import {IVotes} from "../../../governance/utils/IVotes.sol";
import {IERC165} from "../../../interfaces/IERC165.sol";
contract MyGovernor is contract MyGovernor is
Governor, Governor,

@ -1,9 +1,10 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../../token/ERC20/ERC20.sol"; import {ERC20} from "../../../token/ERC20/ERC20.sol";
import "../../../token/ERC20/extensions/ERC20Permit.sol"; import {ERC20Permit} from "../../../token/ERC20/extensions/ERC20Permit.sol";
import "../../../token/ERC20/extensions/ERC20Votes.sol"; import {ERC20Votes} from "../../../token/ERC20/extensions/ERC20Votes.sol";
import {Nonces} from "../../../utils/Nonces.sol";
contract MyToken is ERC20, ERC20Permit, ERC20Votes { contract MyToken is ERC20, ERC20Permit, ERC20Votes {
constructor() ERC20("MyToken", "MTK") ERC20Permit("MyToken") {} constructor() ERC20("MyToken", "MTK") ERC20Permit("MyToken") {}

@ -1,9 +1,10 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../../token/ERC20/ERC20.sol"; import {ERC20} from "../../../token/ERC20/ERC20.sol";
import "../../../token/ERC20/extensions/ERC20Permit.sol"; import {ERC20Permit} from "../../../token/ERC20/extensions/ERC20Permit.sol";
import "../../../token/ERC20/extensions/ERC20Votes.sol"; import {ERC20Votes} from "../../../token/ERC20/extensions/ERC20Votes.sol";
import {Nonces} from "../../../utils/Nonces.sol";
contract MyTokenTimestampBased is ERC20, ERC20Permit, ERC20Votes { contract MyTokenTimestampBased is ERC20, ERC20Permit, ERC20Votes {
constructor() ERC20("MyTokenTimestampBased", "MTK") ERC20Permit("MyTokenTimestampBased") {} constructor() ERC20("MyTokenTimestampBased", "MTK") ERC20Permit("MyTokenTimestampBased") {}

@ -1,10 +1,11 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../../token/ERC20/ERC20.sol"; import {IERC20, ERC20} from "../../../token/ERC20/ERC20.sol";
import "../../../token/ERC20/extensions/ERC20Permit.sol"; import {ERC20Permit} from "../../../token/ERC20/extensions/ERC20Permit.sol";
import "../../../token/ERC20/extensions/ERC20Votes.sol"; import {ERC20Votes} from "../../../token/ERC20/extensions/ERC20Votes.sol";
import "../../../token/ERC20/extensions/ERC20Wrapper.sol"; import {ERC20Wrapper} from "../../../token/ERC20/extensions/ERC20Wrapper.sol";
import {Nonces} from "../../../utils/Nonces.sol";
contract MyTokenWrapped is ERC20, ERC20Permit, ERC20Votes, ERC20Wrapper { contract MyTokenWrapped is ERC20, ERC20Permit, ERC20Votes, ERC20Wrapper {
constructor( constructor(

@ -2,10 +2,12 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../governance/compatibility/GovernorCompatibilityBravo.sol"; import {IGovernor, Governor} from "../../governance/Governor.sol";
import "../../governance/extensions/GovernorTimelockCompound.sol"; import {GovernorCompatibilityBravo} from "../../governance/compatibility/GovernorCompatibilityBravo.sol";
import "../../governance/extensions/GovernorSettings.sol"; import {IGovernorTimelock, GovernorTimelockCompound} from "../../governance/extensions/GovernorTimelockCompound.sol";
import "../../governance/extensions/GovernorVotes.sol"; import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol";
import {GovernorVotes} from "../../governance/extensions/GovernorVotes.sol";
import {IERC165} from "../../interfaces/IERC165.sol";
abstract contract GovernorCompatibilityBravoMock is abstract contract GovernorCompatibilityBravoMock is
GovernorCompatibilityBravo, GovernorCompatibilityBravo,

@ -2,9 +2,10 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../governance/extensions/GovernorSettings.sol"; import {Governor} from "../../governance/Governor.sol";
import "../../governance/extensions/GovernorCountingSimple.sol"; import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol";
import "../../governance/extensions/GovernorVotesQuorumFraction.sol"; import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol";
abstract contract GovernorMock is GovernorSettings, GovernorVotesQuorumFraction, GovernorCountingSimple { abstract contract GovernorMock is GovernorSettings, GovernorVotesQuorumFraction, GovernorCountingSimple {
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {

@ -2,10 +2,11 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../governance/extensions/GovernorPreventLateQuorum.sol"; import {Governor} from "../../governance/Governor.sol";
import "../../governance/extensions/GovernorSettings.sol"; import {GovernorPreventLateQuorum} from "../../governance/extensions/GovernorPreventLateQuorum.sol";
import "../../governance/extensions/GovernorCountingSimple.sol"; import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol";
import "../../governance/extensions/GovernorVotes.sol"; import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotes} from "../../governance/extensions/GovernorVotes.sol";
abstract contract GovernorPreventLateQuorumMock is abstract contract GovernorPreventLateQuorumMock is
GovernorSettings, GovernorSettings,

@ -2,10 +2,11 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../governance/extensions/GovernorTimelockCompound.sol"; import {IGovernor, Governor} from "../../governance/Governor.sol";
import "../../governance/extensions/GovernorSettings.sol"; import {GovernorTimelockCompound} from "../../governance/extensions/GovernorTimelockCompound.sol";
import "../../governance/extensions/GovernorCountingSimple.sol"; import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol";
import "../../governance/extensions/GovernorVotesQuorumFraction.sol"; import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol";
abstract contract GovernorTimelockCompoundMock is abstract contract GovernorTimelockCompoundMock is
GovernorSettings, GovernorSettings,

@ -2,10 +2,11 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../governance/extensions/GovernorTimelockControl.sol"; import {IGovernor, Governor} from "../../governance/Governor.sol";
import "../../governance/extensions/GovernorSettings.sol"; import {GovernorTimelockControl} from "../../governance/extensions/GovernorTimelockControl.sol";
import "../../governance/extensions/GovernorCountingSimple.sol"; import {GovernorSettings} from "../../governance/extensions/GovernorSettings.sol";
import "../../governance/extensions/GovernorVotesQuorumFraction.sol"; import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotesQuorumFraction} from "../../governance/extensions/GovernorVotesQuorumFraction.sol";
abstract contract GovernorTimelockControlMock is abstract contract GovernorTimelockControlMock is
GovernorSettings, GovernorSettings,

@ -2,8 +2,8 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../governance/extensions/GovernorCountingSimple.sol"; import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import "../../governance/extensions/GovernorVotes.sol"; import {GovernorVotes} from "../../governance/extensions/GovernorVotes.sol";
abstract contract GovernorVoteMocks is GovernorVotes, GovernorCountingSimple { abstract contract GovernorVoteMocks is GovernorVotes, GovernorCountingSimple {
function quorum(uint256) public pure override returns (uint256) { function quorum(uint256) public pure override returns (uint256) {

@ -2,8 +2,9 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../governance/extensions/GovernorCountingSimple.sol"; import {Governor} from "../../governance/Governor.sol";
import "../../governance/extensions/GovernorVotes.sol"; import {GovernorCountingSimple} from "../../governance/extensions/GovernorCountingSimple.sol";
import {GovernorVotes} from "../../governance/extensions/GovernorVotes.sol";
abstract contract GovernorWithParamsMock is GovernorVotes, GovernorCountingSimple { abstract contract GovernorWithParamsMock is GovernorVotes, GovernorCountingSimple {
event CountParams(uint256 uintParam, string strParam); event CountParams(uint256 uintParam, string strParam);

@ -2,7 +2,8 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../proxy/utils/UUPSUpgradeable.sol"; import {UUPSUpgradeable} from "../../proxy/utils/UUPSUpgradeable.sol";
import {ERC1967Utils} from "../../proxy/ERC1967/ERC1967Utils.sol";
contract NonUpgradeableMock { contract NonUpgradeableMock {
uint256 internal _counter; uint256 internal _counter;

@ -2,8 +2,8 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../token/ERC1155/IERC1155Receiver.sol"; import {IERC1155Receiver} from "../../token/ERC1155/IERC1155Receiver.sol";
import "../../utils/introspection/ERC165.sol"; import {ERC165} from "../../utils/introspection/ERC165.sol";
contract ERC1155ReceiverMock is ERC165, IERC1155Receiver { contract ERC1155ReceiverMock is ERC165, IERC1155Receiver {
enum RevertType { enum RevertType {

@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../token/ERC20/ERC20.sol"; import {ERC20} from "../../token/ERC20/ERC20.sol";
abstract contract ERC20ApprovalMock is ERC20 { abstract contract ERC20ApprovalMock is ERC20 {
function _approve(address owner, address spender, uint256 amount, bool) internal virtual override { function _approve(address owner, address spender, uint256 amount, bool) internal virtual override {

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../token/ERC20/ERC20.sol"; import {ERC20} from "../../token/ERC20/ERC20.sol";
abstract contract ERC20DecimalsMock is ERC20 { abstract contract ERC20DecimalsMock is ERC20 {
uint8 private immutable _decimals; uint8 private immutable _decimals;

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../token/ERC20/extensions/ERC20FlashMint.sol"; import {ERC20FlashMint} from "../../token/ERC20/extensions/ERC20FlashMint.sol";
abstract contract ERC20FlashMintMock is ERC20FlashMint { abstract contract ERC20FlashMintMock is ERC20FlashMint {
uint256 _flashFeeAmount; uint256 _flashFeeAmount;

@ -2,7 +2,7 @@
pragma solidity ^0.8.19; pragma solidity ^0.8.19;
import "../../token/ERC20/ERC20.sol"; import {ERC20} from "../../token/ERC20/ERC20.sol";
// contract that replicate USDT (0xdac17f958d2ee523a2206206994597c13d831ec7) approval beavior // contract that replicate USDT (0xdac17f958d2ee523a2206206994597c13d831ec7) approval beavior
abstract contract ERC20ForceApproveMock is ERC20 { abstract contract ERC20ForceApproveMock is ERC20 {

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

Loading…
Cancel
Save