Governance

This directory includes primitives for on-chain confidential governance.

  • VotesConfidential: Abstract contract that keeps track of confidential voting units, enabling checkpointed voting through governance.

Utils

VotesConfidential

import "@openzeppelin/confidential-contracts/governance/utils/VotesConfidential.sol";

A confidential votes contract tracking confidential voting power of accounts over time. It features vote delegation to delegators.

This contract keeps a history (checkpoints) of each account’s confidential vote power. Confidential voting power can be delegated either by calling the delegate function directly, or by providing a signature to be used with delegateBySig. Confidential voting power handles can be queried through the public accessors getVotes and getPastVotes but can only be decrypted by accounts allowed to access them. Ensure that HandleAccessManager._validateHandleAllowance is implemented properly, allowing all necessary addresses to access voting power handles.

By default, voting units does not account for voting power. This makes transfers of underlying voting units cheaper. The downside is that it requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.

Functions
  • clock()

  • CLOCK_MODE()

  • getVotes(account)

  • getPastVotes(account, timepoint)

  • getPastTotalSupply(timepoint)

  • confidentialTotalSupply()

  • delegates(account)

  • delegate(delegatee)

  • delegateBySig(delegatee, nonce, expiry, v, r, s)

  • _delegate(account, delegatee)

  • _transferVotingUnits(from, to, amount)

  • _moveDelegateVotes(from, to, amount)

  • _validateTimepoint(timepoint)

  • _getVotingUnits()

HandleAccessManager
  • getHandleAllowance(handle, account, persistent)

  • _validateHandleAllowance(handle)

EIP712
  • _domainSeparatorV4()

  • _hashTypedDataV4(structHash)

  • eip712Domain()

  • _EIP712Name()

  • _EIP712Version()

Nonces
  • nonces(owner)

  • _useNonce(owner)

  • _useCheckedNonce(owner, nonce)

Events
  • DelegateVotesChanged(delegate, previousVotes, newVotes)

  • DelegateChanged(delegator, fromDelegate, toDelegate)

IERC5267
  • EIP712DomainChanged()

Errors
  • VotesExpiredSignature(expiry)

  • ERC6372InconsistentClock()

  • ERC5805FutureLookup(timepoint, clock)

Nonces
  • InvalidAccountNonce(account, currentNonce)

clock() → uint48 public

Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting), in which case CLOCK_MODE should be overridden as well to match.

CLOCK_MODE() → string public

Machine-readable description of the clock as specified in ERC-6372.

getVotes(address account) → euint64 public

Returns the current amount of votes that account has.

getPastVotes(address account, uint256 timepoint) → euint64 public

Returns the amount of votes that account had at a specific moment in the past. If the clock is configured to use block numbers, this will return the value at the end of the corresponding block.

Requirements:

  • timepoint must be in the past. If operating using block numbers, the block must be already mined.

getPastTotalSupply(uint256 timepoint) → euint64 public

Returns the total supply of votes available at a specific moment in the past. If the clock is configured to use block numbers, this will return the value at the end of the corresponding block.

This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. Votes that have not been delegated are still part of total supply, even though they would not participate in a vote.

Requirements:

  • timepoint must be in the past. If operating using block numbers, the block must be already mined.

confidentialTotalSupply() → euint64 public

Returns the current total supply of votes as an encrypted uint64 (euint64). Must be implemented by the derived contract.

delegates(address account) → address public

Returns the delegate that account has chosen.

delegate(address delegatee) public

Delegates votes from the sender to delegatee.

delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) public

Delegates votes from an EOA to delegatee via an ECDSA signature.

_delegate(address account, address delegatee) internal

Delegate all of account’s voting units to `delegatee.

Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}.

_transferVotingUnits(address from, address to, euint64 amount) internal

Transfers, mints, or burns voting units. To register a mint, from should be zero. To register a burn, to should be zero. Total supply of voting units will be adjusted with mints and burns.

Must be called after confidentialTotalSupply is updated.

_moveDelegateVotes(address from, address to, euint64 amount) internal

Moves delegated votes from one delegate to another.

_validateTimepoint(uint256 timepoint) → uint48 internal

Validate that a timepoint is in the past, and return it as a uint48.

_getVotingUnits(address) → euint64 internal

Must return the voting units held by an account.

DelegateVotesChanged(address indexed delegate, euint64 previousVotes, euint64 newVotes) event

Emitted when a token transfer or delegate change results in changes to a delegate’s number of voting units.

DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate) event

Emitted when an account changes their delegate.

VotesExpiredSignature(uint256 expiry) error

The signature used has expired.

ERC6372InconsistentClock() error

The clock was incorrectly modified.

ERC5805FutureLookup(uint256 timepoint, uint48 clock) error

Lookup to future votes is not available.