Skip to main content

Votes

Git Source

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-_beforeTokenTransfer}).

  • Available since v4.5.

State Variables

_delegation

mapping(address => address) private _delegation;

_delegateCheckpoints

mapping(address => Checkpoints.History) private _delegateCheckpoints;

_totalCheckpoints

Checkpoints.History private _totalCheckpoints;

Functions

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 the end of a past block (blockNumber). Requirements:

  • blockNumber must have been already mined
function getPastVotes(address account, uint256 blockNumber) public view virtual returns (uint256);

getPastTotalSupply

Returns the total supply of votes available at the end of a past block (blockNumber). 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:

  • blockNumber must have been already mined
function getPastTotalSupply(uint256 blockNumber) 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;

_delegate

Delegate all of account's voting units to delegatee. Emits events DelegateChanged and 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) private;

_add

function _add(uint256 a, uint256 b) internal pure returns (uint256);

_subtract

function _subtract(uint256 a, uint256 b) internal pure returns (uint256);

_getVotingUnits

Must return the voting units held by an account.

function _getVotingUnits(address) internal view virtual returns (uint256);

Events

DelegateChanged

Emitted when an account changes their delegate.

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

DelegateVotesChanged

Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.

event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

Errors

SIGNATURE_EXPIRED

error SIGNATURE_EXPIRED();

BLOCK_NOT_YET_MINED

error BLOCK_NOT_YET_MINED();

INVALID

error INVALID();