Votes
Inherits: Context, EIP712, Nonces, IERC5805
This is a base abstract contract that tracks voting units, which are a measure of voting power that can be transferred, and provides a system of vote delegation, where an account can delegate its voting units to a sort of "representative" that will pool delegated voting units from different accounts and can then use it to vote in decisions. In fact, voting units must be delegated in order to count as actual votes, and an account has to delegate those votes to itself if it wishes to participate in decisions and does not have a trusted representative. This contract is often combined with a token contract such that voting units correspond to token units. For an example, see {ERC721Votes}. The full history of delegate votes is tracked on-chain so that governance protocols can consider votes as distributed at a particular block number to protect against flash loans and double voting. The opt-in delegate system makes the cost of this history tracking optional. When using this module the derived contract must implement {_getVotingUnits} (for example, make it return {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the previous example, it would be included in {ERC721-_update}).
State Variables
DELEGATION_TYPEHASH
bytes32 private constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
_delegatee
mapping(address account => address) private _delegatee;
_delegateCheckpoints
mapping(address delegatee => Checkpoints.Trace208) private _delegateCheckpoints;
_totalCheckpoints
Checkpoints.Trace208 private _totalCheckpoints;
Functions
clock
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.
function clock() public view virtual returns (uint48);
CLOCK_MODE
Machine-readable description of the clock as specified in ERC-6372.
function CLOCK_MODE() public view virtual returns (string memory);
_validateTimepoint
Validate that a timepoint is in the past, and return it as a uint48.
function _validateTimepoint(uint256 timepoint) internal view returns (uint48);
getVotes
Returns the current amount of votes that account
has.
function getVotes(address account) public view virtual returns (uint256);
getPastVotes
*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.*
function getPastVotes(address account, uint256 timepoint) public view virtual returns (uint256);
getPastTotalSupply
*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.
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.*
function getPastTotalSupply(uint256 timepoint) public view virtual returns (uint256);
_getTotalSupply
Returns the current total supply of votes.
function _getTotalSupply() internal view virtual returns (uint256);
delegates
Returns the delegate that account
has chosen.
function delegates(address account) public view virtual returns (address);
delegate
Delegates votes from the sender to delegatee
.
function delegate(address delegatee) public virtual;
delegateBySig
Delegates votes from signer to delegatee
.
function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s)
public
virtual;
_delegate
Delegate all of account
's voting units to delegatee
.
Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}.
function _delegate(address account, address delegatee) internal virtual;
_transferVotingUnits
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.
function _transferVotingUnits(address from, address to, uint256 amount) internal virtual;
_moveDelegateVotes
Moves delegated votes from one delegate to another.
function _moveDelegateVotes(address from, address to, uint256 amount) internal virtual;
_numCheckpoints
Get number of checkpoints for account
.
function _numCheckpoints(address account) internal view virtual returns (uint32);
_checkpoints
Get the pos
-th checkpoint for account
.
function _checkpoints(address account, uint32 pos) internal view virtual returns (Checkpoints.Checkpoint208 memory);
_push
function _push(Checkpoints.Trace208 storage store, function(uint208, uint208) view returns (uint208) op, uint208 delta)
private
returns (uint208 oldValue, uint208 newValue);
_add
function _add(uint208 a, uint208 b) private pure returns (uint208);
_subtract
function _subtract(uint208 a, uint208 b) private pure returns (uint208);
_getVotingUnits
Must return the voting units held by an account.
function _getVotingUnits(address) internal view virtual returns (uint256);
Errors
ERC6372InconsistentClock
The clock was incorrectly modified.
error ERC6372InconsistentClock();
ERC5805FutureLookup
Lookup to future votes is not available.
error ERC5805FutureLookup(uint256 timepoint, uint48 clock);