Add Governor signature nonces (#4378)
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com> Co-authored-by: Francisco <fg@frang.io> Co-authored-by: Sergei Tikhomirov <sergey.s.tikhomirov@gmail.com> Co-authored-by: Renan Souza <renan.rodrigues.souza1@gmail.com>
This commit is contained in:
@ -12,6 +12,7 @@ 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";
|
||||
|
||||
/**
|
||||
@ -25,12 +26,15 @@ import {IGovernor, IERC6372} from "./IGovernor.sol";
|
||||
*
|
||||
* _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 {
|
||||
@ -514,17 +518,23 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receive
|
||||
function castVoteBySig(
|
||||
uint256 proposalId,
|
||||
uint8 support,
|
||||
address voter,
|
||||
uint8 v,
|
||||
bytes32 r,
|
||||
bytes32 s
|
||||
) public virtual override returns (uint256) {
|
||||
address voter = ECDSA.recover(
|
||||
_hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))),
|
||||
address signer = ECDSA.recover(
|
||||
_hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support, voter, _useNonce(voter)))),
|
||||
v,
|
||||
r,
|
||||
s
|
||||
);
|
||||
return _castVote(proposalId, voter, support, "");
|
||||
|
||||
if (voter != signer) {
|
||||
revert GovernorInvalidSigner(signer, voter);
|
||||
}
|
||||
|
||||
return _castVote(proposalId, signer, support, "");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -533,19 +543,22 @@ 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
|
||||
) public virtual override returns (uint256) {
|
||||
address voter = ECDSA.recover(
|
||||
address signer = ECDSA.recover(
|
||||
_hashTypedDataV4(
|
||||
keccak256(
|
||||
abi.encode(
|
||||
EXTENDED_BALLOT_TYPEHASH,
|
||||
proposalId,
|
||||
support,
|
||||
voter,
|
||||
_useNonce(voter),
|
||||
keccak256(bytes(reason)),
|
||||
keccak256(params)
|
||||
)
|
||||
@ -556,7 +569,11 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receive
|
||||
s
|
||||
);
|
||||
|
||||
return _castVote(proposalId, voter, support, reason, params);
|
||||
if (voter != signer) {
|
||||
revert GovernorInvalidSigner(signer, voter);
|
||||
}
|
||||
|
||||
return _castVote(proposalId, signer, support, reason, params);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -80,6 +80,11 @@ abstract contract IGovernor is IERC165, IERC6372 {
|
||||
*/
|
||||
error GovernorInvalidVoteType();
|
||||
|
||||
/**
|
||||
* @dev The `voter` doesn't match with the recovered `signer`.
|
||||
*/
|
||||
error GovernorInvalidSigner(address signer, address voter);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a proposal is created.
|
||||
*/
|
||||
@ -355,6 +360,7 @@ abstract contract IGovernor is IERC165, IERC6372 {
|
||||
function castVoteBySig(
|
||||
uint256 proposalId,
|
||||
uint8 support,
|
||||
address voter,
|
||||
uint8 v,
|
||||
bytes32 r,
|
||||
bytes32 s
|
||||
@ -368,6 +374,7 @@ abstract contract IGovernor is IERC165, IERC6372 {
|
||||
function castVoteWithReasonAndParamsBySig(
|
||||
uint256 proposalId,
|
||||
uint8 support,
|
||||
address voter,
|
||||
string calldata reason,
|
||||
bytes memory params,
|
||||
uint8 v,
|
||||
|
||||
Reference in New Issue
Block a user