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
with:
node-version: 18.15
slither-version: 0.9.3
codespell:
runs-on: ubuntu-latest

@ -9,6 +9,7 @@
"modifier-name-mixedcase": "error",
"private-vars-leading-underscore": "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
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 {
constructor() ERC721("MyCollectible", "MCO") {

@ -3,10 +3,10 @@
pragma solidity ^0.8.19;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {Strings} from "../utils/Strings.sol";
import {ERC165} from "../utils/introspection/ERC165.sol";
/**
* @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:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*
* _Available since v4.1._
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
@ -91,8 +89,6 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 {
* Overriding this function changes the behavior of the {onlyRole} modifier.
*
* Format of the revert message is described in {_checkRole}.
*
* _Available since v4.6._
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());

@ -3,10 +3,11 @@
pragma solidity ^0.8.19;
import "./AccessControl.sol";
import "./IAccessControlDefaultAdminRules.sol";
import "../utils/math/SafeCast.sol";
import "../interfaces/IERC5313.sol";
import {AccessControl, IAccessControl} from "./AccessControl.sol";
import {IAccessControlDefaultAdminRules} from "./IAccessControlDefaultAdminRules.sol";
import {SafeCast} from "../utils/math/SafeCast.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
@ -34,8 +35,6 @@ import "../interfaces/IERC5313.sol";
* ) {}
* }
* ```
*
* _Available since v4.9._
*/
abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRules, IERC5313, AccessControl {
// pending admin pair read/written together frequently

@ -3,9 +3,9 @@
pragma solidity ^0.8.19;
import "./IAccessControlEnumerable.sol";
import "./AccessControl.sol";
import "../utils/structs/EnumerableSet.sol";
import {IAccessControlEnumerable} from "./IAccessControlEnumerable.sol";
import {AccessControl} from "./AccessControl.sol";
import {EnumerableSet} from "../utils/structs/EnumerableSet.sol";
/**
* @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
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

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

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

@ -3,7 +3,7 @@
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

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

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

@ -3,16 +3,17 @@
pragma solidity ^0.8.19;
import "../token/ERC721/IERC721Receiver.sol";
import "../token/ERC1155/IERC1155Receiver.sol";
import "../utils/cryptography/ECDSA.sol";
import "../utils/cryptography/EIP712.sol";
import "../utils/introspection/ERC165.sol";
import "../utils/math/SafeCast.sol";
import "../utils/structs/DoubleEndedQueue.sol";
import "../utils/Address.sol";
import "../utils/Context.sol";
import "./IGovernor.sol";
import {IERC721Receiver} from "../token/ERC721/IERC721Receiver.sol";
import {IERC1155Receiver} from "../token/ERC1155/IERC1155Receiver.sol";
import {EIP712} from "../utils/cryptography/EIP712.sol";
import {SignatureChecker} from "../utils/cryptography/SignatureChecker.sol";
import {IERC165, ERC165} from "../utils/introspection/ERC165.sol";
import {SafeCast} from "../utils/math/SafeCast.sol";
import {DoubleEndedQueue} from "../utils/structs/DoubleEndedQueue.sol";
import {Address} from "../utils/Address.sol";
import {Context} from "../utils/Context.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.
@ -22,15 +23,16 @@ import "./IGovernor.sol";
* - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote}
* - A voting module must implement {_getVotes}
* - 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;
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 =
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
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);
string private _name;
/// @custom:oz-retyped-from mapping(uint256 => Governor.ProposalCore)
mapping(uint256 => ProposalCore) private _proposals;
// 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(
uint256 proposalId,
uint8 support,
uint8 v,
bytes32 r,
bytes32 s
address voter,
bytes memory signature
) public virtual override returns (uint256) {
address voter = ECDSA.recover(
_hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))),
v,
r,
s
bool valid = SignatureChecker.isValidSignatureNow(
voter,
_hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support, voter, _useNonce(voter)))),
signature
);
if (!valid) {
revert GovernorInvalidSignature(voter);
}
return _castVote(proposalId, voter, support, "");
}
@ -533,29 +537,33 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receive
function castVoteWithReasonAndParamsBySig(
uint256 proposalId,
uint8 support,
address voter,
string calldata reason,
bytes memory params,
uint8 v,
bytes32 r,
bytes32 s
bytes memory signature
) public virtual override returns (uint256) {
address voter = ECDSA.recover(
bool valid = SignatureChecker.isValidSignatureNow(
voter,
_hashTypedDataV4(
keccak256(
abi.encode(
EXTENDED_BALLOT_TYPEHASH,
proposalId,
support,
voter,
_useNonce(voter),
keccak256(bytes(reason)),
keccak256(params)
)
)
),
v,
r,
s
signature
);
if (!valid) {
revert GovernorInvalidSignature(voter);
}
return _castVote(proposalId, voter, support, reason, params);
}

@ -3,13 +3,11 @@
pragma solidity ^0.8.19;
import "../interfaces/IERC165.sol";
import "../interfaces/IERC6372.sol";
import {IERC165} from "../interfaces/IERC165.sol";
import {IERC6372} from "../interfaces/IERC6372.sol";
/**
* @dev Interface of the {Governor} core.
*
* _Available since v4.3._
*/
abstract contract IGovernor is IERC165, IERC6372 {
enum ProposalState {
@ -80,6 +78,12 @@ abstract contract IGovernor is IERC165, IERC6372 {
*/
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.
*/
@ -348,30 +352,29 @@ abstract contract IGovernor is IERC165, IERC6372 {
) 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.
*/
function castVoteBySig(
uint256 proposalId,
uint8 support,
uint8 v,
bytes32 r,
bytes32 s
address voter,
bytes memory signature
) 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.
*/
function castVoteWithReasonAndParamsBySig(
uint256 proposalId,
uint8 support,
address voter,
string calldata reason,
bytes memory params,
uint8 v,
bytes32 r,
bytes32 s
bytes memory signature
) 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 status:*
** *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.
** *Pending:* An operation that is either waiting or ready.
** *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.
* *Role*:

@ -3,10 +3,11 @@
pragma solidity ^0.8.19;
import "../access/AccessControl.sol";
import "../token/ERC721/utils/ERC721Holder.sol";
import "../token/ERC1155/utils/ERC1155Holder.sol";
import "../utils/Address.sol";
import {AccessControl} from "../access/AccessControl.sol";
import {ERC721Holder} from "../token/ERC721/utils/ERC721Holder.sol";
import {ERC1155Holder} from "../token/ERC1155/utils/ERC1155Holder.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
@ -20,8 +21,6 @@ import "../utils/Address.sol";
* 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
* a multisig or a DAO as the sole proposer.
*
* _Available since v3.3._
*/
contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");
@ -34,7 +33,7 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
enum OperationState {
Unset,
Pending,
Waiting,
Ready,
Done
}
@ -51,8 +50,12 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
/**
* @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.
@ -165,30 +168,30 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
* @dev Returns whether an id correspond to a registered operation. This
* includes both Pending, Ready and Done operations.
*/
function isOperation(bytes32 id) public view virtual returns (bool) {
return getTimestamp(id) > 0;
function isOperation(bytes32 id) public view returns (bool) {
return getOperationState(id) != OperationState.Unset;
}
/**
* @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) {
return getTimestamp(id) > _DONE_TIMESTAMP;
function isOperationPending(bytes32 id) public view returns (bool) {
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".
*/
function isOperationReady(bytes32 id) public view virtual returns (bool) {
uint256 timestamp = getTimestamp(id);
return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp;
function isOperationReady(bytes32 id) public view returns (bool) {
return getOperationState(id) == OperationState.Ready;
}
/**
* @dev Returns whether an operation is done or not.
*/
function isOperationDone(bytes32 id) public view virtual returns (bool) {
return getTimestamp(id) == _DONE_TIMESTAMP;
function isOperationDone(bytes32 id) public view returns (bool) {
return getOperationState(id) == OperationState.Done;
}
/**
@ -199,6 +202,22 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
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.
*
@ -297,7 +316,7 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
*/
function _schedule(bytes32 id, uint256 delay) private {
if (isOperation(id)) {
revert TimelockUnexpectedOperationState(id, OperationState.Unset);
revert TimelockUnexpectedOperationState(id, _encodeStateBitmap(OperationState.Unset));
}
uint256 minDelay = getMinDelay();
if (delay < minDelay) {
@ -315,7 +334,10 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
*/
function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) {
if (!isOperationPending(id)) {
revert TimelockUnexpectedOperationState(id, OperationState.Pending);
revert TimelockUnexpectedOperationState(
id,
_encodeStateBitmap(OperationState.Waiting) | _encodeStateBitmap(OperationState.Ready)
);
}
delete _timestamps[id];
@ -398,7 +420,7 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
*/
function _beforeCall(bytes32 id, bytes32 predecessor) private view {
if (!isOperationReady(id)) {
revert TimelockUnexpectedOperationState(id, OperationState.Ready);
revert TimelockUnexpectedOperationState(id, _encodeStateBitmap(OperationState.Ready));
}
if (predecessor != bytes32(0) && !isOperationDone(predecessor)) {
revert TimelockUnexecutedPredecessor(predecessor);
@ -410,7 +432,7 @@ contract TimelockController is AccessControl, ERC721Holder, ERC1155Holder {
*/
function _afterCall(bytes32 id) private {
if (!isOperationReady(id)) {
revert TimelockUnexpectedOperationState(id, OperationState.Ready);
revert TimelockUnexpectedOperationState(id, _encodeStateBitmap(OperationState.Ready));
}
_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.
*/
function updateDelay(uint256 newDelay) external virtual {
if (msg.sender != address(this)) {
revert TimelockUnauthorizedCaller(msg.sender);
address sender = _msgSender();
if (sender != address(this)) {
revert TimelockUnauthorizedCaller(sender);
}
emit MinDelayChange(_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;
import "../../utils/math/SafeCast.sol";
import "../extensions/IGovernorTimelock.sol";
import "../Governor.sol";
import "./IGovernorCompatibilityBravo.sol";
import {SafeCast} from "../../utils/math/SafeCast.sol";
import {IGovernorTimelock} from "../extensions/IGovernorTimelock.sol";
import {IGovernor, Governor} from "../Governor.sol";
import {IGovernorCompatibilityBravo} from "./IGovernorCompatibilityBravo.sol";
/**
* @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.
*
* 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 {
enum VoteType {

@ -3,12 +3,10 @@
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.
*
* _Available since v4.3._
*/
abstract contract IGovernorCompatibilityBravo is IGovernor {
/**

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

@ -3,8 +3,8 @@
pragma solidity ^0.8.19;
import "../Governor.sol";
import "../../utils/math/Math.sol";
import {Governor} from "../Governor.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
@ -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
* least a specified time has passed (the "vote extension" parameter). This parameter can be set through a governance
* proposal.
*
* _Available since v4.5._
*/
abstract contract GovernorPreventLateQuorum is Governor {
uint48 private _voteExtension;
/// @custom:oz-retyped-from mapping(uint256 => Timers.BlockNumber)
mapping(uint256 => uint48) private _extendedDeadlines;
/// @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;
import "../Governor.sol";
import {Governor} from "../Governor.sol";
/**
* @dev Extension of {Governor} for settings updatable through governance.
*
* _Available since v4.4._
*/
abstract contract GovernorSettings is Governor {
// amount of token

@ -3,10 +3,12 @@
pragma solidity ^0.8.19;
import "./IGovernorTimelock.sol";
import "../Governor.sol";
import "../../utils/math/SafeCast.sol";
import "../../vendor/compound/ICompoundTimelock.sol";
import {IGovernorTimelock} from "./IGovernorTimelock.sol";
import {IGovernor, Governor} from "../Governor.sol";
import {SafeCast} from "../../utils/math/SafeCast.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
@ -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,
* the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be
* inaccessible.
*
* _Available since v4.3._
*/
abstract contract GovernorTimelockCompound is IGovernorTimelock, Governor {
ICompoundTimelock private _timelock;
/// @custom:oz-retyped-from mapping(uint256 => GovernorTimelockCompound.ProposalTimelock)
mapping(uint256 => uint256) private _proposalTimelocks;
/**

@ -3,9 +3,10 @@
pragma solidity ^0.8.19;
import "./IGovernorTimelock.sol";
import "../Governor.sol";
import "../TimelockController.sol";
import {IGovernorTimelock} from "./IGovernorTimelock.sol";
import {IGovernor, Governor} from "../Governor.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
@ -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
* 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.
*
* _Available since v4.3._
*/
abstract contract GovernorTimelockControl is IGovernorTimelock, Governor {
TimelockController private _timelock;

@ -3,13 +3,13 @@
pragma solidity ^0.8.19;
import "../Governor.sol";
import "../../interfaces/IERC5805.sol";
import {Governor} from "../Governor.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.
*
* _Available since v4.3._
*/
abstract contract GovernorVotes is Governor {
IERC5805 public immutable token;

@ -3,20 +3,17 @@
pragma solidity ^0.8.19;
import "./GovernorVotes.sol";
import "../../utils/math/SafeCast.sol";
import "../../utils/structs/Checkpoints.sol";
import {GovernorVotes} from "./GovernorVotes.sol";
import {SafeCast} from "../../utils/math/SafeCast.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
* fraction of the total supply.
*
* _Available since v4.3._
*/
abstract contract GovernorVotesQuorumFraction is GovernorVotes {
using Checkpoints for Checkpoints.Trace224;
/// @custom:oz-retyped-from Checkpoints.History
Checkpoints.Trace224 private _quorumNumeratorHistory;
event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator);

@ -3,12 +3,10 @@
pragma solidity ^0.8.19;
import "../IGovernor.sol";
import {IGovernor} from "../IGovernor.sol";
/**
* @dev Extension of the {IGovernor} for timelock supporting modules.
*
* _Available since v4.3._
*/
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.
*
* _Available since v4.5._
*/
interface IVotes {
/**
@ -19,9 +17,9 @@ interface IVotes {
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.

@ -2,11 +2,13 @@
// OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/Votes.sol)
pragma solidity ^0.8.19;
import "../../interfaces/IERC5805.sol";
import "../../utils/Context.sol";
import "../../utils/Nonces.sol";
import "../../utils/cryptography/EIP712.sol";
import "../../utils/structs/Checkpoints.sol";
import {IERC5805} from "../../interfaces/IERC5805.sol";
import {Context} from "../../utils/Context.sol";
import {Nonces} from "../../utils/Nonces.sol";
import {EIP712} from "../../utils/cryptography/EIP712.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
@ -25,8 +27,6 @@ import "../../utils/structs/Checkpoints.sol";
* 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
* previous example, it would be included in {ERC721-_beforeTokenTransfer}).
*
* _Available since v4.5._
*/
abstract contract Votes is Context, EIP712, Nonces, IERC5805 {
using Checkpoints for Checkpoints.Trace224;
@ -36,10 +36,8 @@ abstract contract Votes is Context, EIP712, Nonces, IERC5805 {
mapping(address => address) private _delegation;
/// @custom:oz-retyped-from mapping(address => Checkpoints.History)
mapping(address => Checkpoints.Trace224) private _delegateCheckpoints;
/// @custom:oz-retyped-from Checkpoints.History
Checkpoints.Trace224 private _totalCheckpoints;
/**

@ -3,4 +3,4 @@
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;
import "../token/ERC1155/extensions/IERC1155MetadataURI.sol";
import {IERC1155MetadataURI} from "../token/ERC1155/extensions/IERC1155MetadataURI.sol";

@ -3,4 +3,4 @@
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
* contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
*
* _Available since v4.1._
*/
interface IERC1271 {
/**

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

@ -3,4 +3,4 @@
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.
*
* _Available since v4.8.3._
*/
interface IERC1967 {
/**

@ -3,4 +3,4 @@
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;
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.
*
* _Available since v4.8._
*/
interface IERC2309 {
/**

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

@ -3,15 +3,13 @@
pragma solidity ^0.8.19;
import "../utils/introspection/IERC165.sol";
import {IERC165} from "../utils/introspection/IERC165.sol";
/**
* @dev Interface for the NFT Royalty Standard.
*
* 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.
*
* _Available since v4.5._
*/
interface IERC2981 is IERC165 {
/**

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

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

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

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

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

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

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

@ -3,4 +3,4 @@
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;
import "../token/ERC721/extensions/IERC721Enumerable.sol";
import {IERC721Enumerable} from "../token/ERC721/extensions/IERC721Enumerable.sol";

@ -3,4 +3,4 @@
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;
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 balance Current balance for the interacting account.
* @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);

@ -3,7 +3,7 @@
pragma solidity ^0.8.19;
import "../utils/Context.sol";
import {Context} from "../utils/Context.sol";
/**
* @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
{{MinimalForwarder}}
{{ERC2771Forwarder}}

@ -2,7 +2,7 @@
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.

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

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

@ -2,7 +2,8 @@
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 {
function version() public pure virtual returns (string memory);

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

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

@ -2,7 +2,7 @@
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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -2,7 +2,10 @@
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 {
using Math for uint256;

@ -1,11 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "../../../governance/Governor.sol";
import "../../../governance/compatibility/GovernorCompatibilityBravo.sol";
import "../../../governance/extensions/GovernorVotes.sol";
import "../../../governance/extensions/GovernorVotesQuorumFraction.sol";
import "../../../governance/extensions/GovernorTimelockControl.sol";
import {IGovernor, Governor} from "../../../governance/Governor.sol";
import {GovernorCompatibilityBravo} from "../../../governance/compatibility/GovernorCompatibilityBravo.sol";
import {GovernorVotes} from "../../../governance/extensions/GovernorVotes.sol";
import {GovernorVotesQuorumFraction} from "../../../governance/extensions/GovernorVotesQuorumFraction.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
Governor,

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

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

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

@ -2,10 +2,12 @@
pragma solidity ^0.8.19;
import "../../governance/compatibility/GovernorCompatibilityBravo.sol";
import "../../governance/extensions/GovernorTimelockCompound.sol";
import "../../governance/extensions/GovernorSettings.sol";
import "../../governance/extensions/GovernorVotes.sol";
import {IGovernor, Governor} from "../../governance/Governor.sol";
import {GovernorCompatibilityBravo} from "../../governance/compatibility/GovernorCompatibilityBravo.sol";
import {IGovernorTimelock, GovernorTimelockCompound} from "../../governance/extensions/GovernorTimelockCompound.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
GovernorCompatibilityBravo,

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

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

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

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

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

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

@ -2,7 +2,8 @@
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 {
uint256 internal _counter;

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

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

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

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

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

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

Loading…
Cancel
Save