You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.7 KiB
75 lines
2.7 KiB
// SPDX-License-Identifier: MIT
|
|
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Votes.sol)
|
|
|
|
pragma solidity ^0.8.19;
|
|
|
|
import "../ERC20.sol";
|
|
import "../../../governance/utils/Votes.sol";
|
|
import "../../../utils/math/SafeCast.sol";
|
|
|
|
/**
|
|
* @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,
|
|
* and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.
|
|
*
|
|
* NOTE: This contract does not provide interface compatibility with Compound's COMP token.
|
|
*
|
|
* This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either
|
|
* by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting
|
|
* power can be queried through the public accessors {getVotes} and {getPastVotes}.
|
|
*
|
|
* By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it
|
|
* requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.
|
|
*
|
|
* _Available since v4.2._
|
|
*/
|
|
abstract contract ERC20Votes is ERC20, Votes {
|
|
/**
|
|
* @dev Total supply cap has been exceeded, introducing a risk of votes overflowing.
|
|
*/
|
|
error ERC20ExceededSafeSupply(uint256 increasedSupply, uint256 cap);
|
|
|
|
/**
|
|
* @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).
|
|
*/
|
|
function _maxSupply() internal view virtual returns (uint224) {
|
|
return type(uint224).max;
|
|
}
|
|
|
|
/**
|
|
* @dev Move voting power when tokens are transferred.
|
|
*
|
|
* Emits a {IVotes-DelegateVotesChanged} event.
|
|
*/
|
|
function _update(address from, address to, uint256 amount) internal virtual override {
|
|
super._update(from, to, amount);
|
|
if (from == address(0)) {
|
|
uint256 supply = totalSupply();
|
|
uint256 cap = _maxSupply();
|
|
if (supply > cap) {
|
|
revert ERC20ExceededSafeSupply(supply, cap);
|
|
}
|
|
}
|
|
_transferVotingUnits(from, to, amount);
|
|
}
|
|
|
|
/**
|
|
* @dev Returns the balance of `account`.
|
|
*/
|
|
function _getVotingUnits(address account) internal view virtual override returns (uint256) {
|
|
return balanceOf(account);
|
|
}
|
|
|
|
/**
|
|
* @dev Get number of checkpoints for `account`.
|
|
*/
|
|
function numCheckpoints(address account) public view virtual returns (uint32) {
|
|
return _numCheckpoints(account);
|
|
}
|
|
|
|
/**
|
|
* @dev Get the `pos`-th checkpoint for `account`.
|
|
*/
|
|
function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoints.Checkpoint224 memory) {
|
|
return _checkpoints(account, pos);
|
|
}
|
|
}
|
|
|