Governance
Smart contract governance utilities and implementations
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
import "@openzeppelin/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 VotesConfidential.delegate
function directly, or by providing
a signature to be used with VotesConfidential.delegateBySig
. Confidential voting power handles can be queried
through the public accessors VotesConfidential.getVotes
and VotesConfidential.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
IERC6372
EIP712
IERC5267
Nonces
Events
Errors
clock() → uint48
public
#Clock used for flagging checkpoints. Can be overridden to implement timestamp based
checkpoints (and voting), in which case VotesConfidential.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 VotesConfidential.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 VotesConfidential.clock
is
configured to use block numbers, this will return the value at the end of the corresponding block.
NOTE: 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 VotesConfidential.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.