GovernorNoncesKeyed.sol 3.3 KB

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