GovernorNoncesKeyed.sol 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v5.4.0-rc.0) (governance/extensions/GovernorNoncesKeyed.sol)
  3. pragma solidity ^0.8.24;
  4. import {Governor} from "../Governor.sol";
  5. import {Nonces} from "../../utils/Nonces.sol";
  6. import {NoncesKeyed} from "../../utils/NoncesKeyed.sol";
  7. import {SignatureChecker} from "../../utils/cryptography/SignatureChecker.sol";
  8. /**
  9. * @dev An extension of {Governor} that extends existing nonce management to use {NoncesKeyed}, where the key is the first 192 bits of the `proposalId`.
  10. * This is useful for voting by signature while maintaining separate sequences of nonces for each proposal.
  11. *
  12. * NOTE: Traditional (un-keyed) nonces are still supported and can continue to be used as if this extension was not present.
  13. */
  14. abstract contract GovernorNoncesKeyed is Governor, NoncesKeyed {
  15. function _useCheckedNonce(address owner, uint256 nonce) internal virtual override(Nonces, NoncesKeyed) {
  16. super._useCheckedNonce(owner, nonce);
  17. }
  18. /**
  19. * @dev Check the signature against keyed nonce and falls back to the traditional nonce.
  20. *
  21. * NOTE: This function won't call `super._validateVoteSig` if the keyed nonce is valid.
  22. * Side effects may be skipped depending on the linearization of the function.
  23. */
  24. function _validateVoteSig(
  25. uint256 proposalId,
  26. uint8 support,
  27. address voter,
  28. bytes memory signature
  29. ) internal virtual override returns (bool) {
  30. if (
  31. SignatureChecker.isValidSignatureNow(
  32. voter,
  33. _hashTypedDataV4(
  34. keccak256(
  35. abi.encode(BALLOT_TYPEHASH, proposalId, support, voter, nonces(voter, uint192(proposalId)))
  36. )
  37. ),
  38. signature
  39. )
  40. ) {
  41. _useNonce(voter, uint192(proposalId));
  42. return true;
  43. } else {
  44. return super._validateVoteSig(proposalId, support, voter, signature);
  45. }
  46. }
  47. /**
  48. * @dev Check the signature against keyed nonce and falls back to the traditional nonce.
  49. *
  50. * NOTE: This function won't call `super._validateExtendedVoteSig` if the keyed nonce is valid.
  51. * Side effects may be skipped depending on the linearization of the function.
  52. */
  53. function _validateExtendedVoteSig(
  54. uint256 proposalId,
  55. uint8 support,
  56. address voter,
  57. string memory reason,
  58. bytes memory params,
  59. bytes memory signature
  60. ) internal virtual override returns (bool) {
  61. if (
  62. SignatureChecker.isValidSignatureNow(
  63. voter,
  64. _hashTypedDataV4(
  65. keccak256(
  66. abi.encode(
  67. EXTENDED_BALLOT_TYPEHASH,
  68. proposalId,
  69. support,
  70. voter,
  71. nonces(voter, uint192(proposalId)),
  72. keccak256(bytes(reason)),
  73. keccak256(params)
  74. )
  75. )
  76. ),
  77. signature
  78. )
  79. ) {
  80. _useNonce(voter, uint192(proposalId));
  81. return true;
  82. } else {
  83. return super._validateExtendedVoteSig(proposalId, support, voter, reason, params, signature);
  84. }
  85. }
  86. }