What is voteCastBySig?

What does voteCastBySig do?

voteCast and voteCastWithReason seem to be pretty clear. But what's the purpose of cast a vote with your sig?

voteCastBySig function:

    function castVoteBySig(
        uint256 proposalId,
        uint8 support,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override returns (uint256) {
        address voter = ECDSA.recover(
            _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))),
        return _castVote(proposalId, voter, support, "");

voteCast function

    function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) {
        address voter = _msgSender();
        return _castVote(proposalId, voter, support, "");

So the ECDSA(Elliptic Curve Digital Signature Algorithm) stuff is how ETH comes up with addresses from private keys, that makes sense. And we are just hashing our vote with our private key basically? So that's cool and all... but what does it do?

My hunch is that anyone could then execute this vote on behalf of me if I didn't send the tx or something?

Moved to #support:contracts. You should post OpenZeppelin related questions in the #support categories, because the team prioritizes paying attention to those posts.

Yes, exactly! This method implements a meta-transaction, and allows a project to subsidize voting fees. The voters can generate a signature for free, and the project can then submit those and pay for the gas.

1 Like


I was having a hard time figuring out how I'd do that though. So the voter is a signed voter address? Where is the meta transaction part?

A voter needs to create an EIP712 signature containing their vote. Normally they would do this through a UI that would generate the data to be signed, and request the signature from the user's wallet (MetaMask, WalletConnect, etc.).

Here is the code in our tests. We're using eth-sig-util.

1 Like