ERC20VotesUpgradeable.sol 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.5.0-rc.0) (token/ERC20/extensions/ERC20Votes.sol)
  3. pragma solidity ^0.8.0;
  4. import "./draft-ERC20PermitUpgradeable.sol";
  5. import "../../../utils/math/MathUpgradeable.sol";
  6. import "../../../governance/utils/IVotesUpgradeable.sol";
  7. import "../../../utils/math/SafeCastUpgradeable.sol";
  8. import "../../../utils/cryptography/ECDSAUpgradeable.sol";
  9. import "../../../proxy/utils/Initializable.sol";
  10. /**
  11. * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,
  12. * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.
  13. *
  14. * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.
  15. *
  16. * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either
  17. * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting
  18. * power can be queried through the public accessors {getVotes} and {getPastVotes}.
  19. *
  20. * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it
  21. * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.
  22. *
  23. * _Available since v4.2._
  24. */
  25. abstract contract ERC20VotesUpgradeable is Initializable, IVotesUpgradeable, ERC20PermitUpgradeable {
  26. function __ERC20Votes_init() internal onlyInitializing {
  27. }
  28. function __ERC20Votes_init_unchained() internal onlyInitializing {
  29. }
  30. struct Checkpoint {
  31. uint32 fromBlock;
  32. uint224 votes;
  33. }
  34. bytes32 private constant _DELEGATION_TYPEHASH =
  35. keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
  36. mapping(address => address) private _delegates;
  37. mapping(address => Checkpoint[]) private _checkpoints;
  38. Checkpoint[] private _totalSupplyCheckpoints;
  39. /**
  40. * @dev Get the `pos`-th checkpoint for `account`.
  41. */
  42. function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {
  43. return _checkpoints[account][pos];
  44. }
  45. /**
  46. * @dev Get number of checkpoints for `account`.
  47. */
  48. function numCheckpoints(address account) public view virtual returns (uint32) {
  49. return SafeCastUpgradeable.toUint32(_checkpoints[account].length);
  50. }
  51. /**
  52. * @dev Get the address `account` is currently delegating to.
  53. */
  54. function delegates(address account) public view virtual override returns (address) {
  55. return _delegates[account];
  56. }
  57. /**
  58. * @dev Gets the current votes balance for `account`
  59. */
  60. function getVotes(address account) public view virtual override returns (uint256) {
  61. uint256 pos = _checkpoints[account].length;
  62. return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;
  63. }
  64. /**
  65. * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.
  66. *
  67. * Requirements:
  68. *
  69. * - `blockNumber` must have been already mined
  70. */
  71. function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {
  72. require(blockNumber < block.number, "ERC20Votes: block not yet mined");
  73. return _checkpointsLookup(_checkpoints[account], blockNumber);
  74. }
  75. /**
  76. * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.
  77. * It is but NOT the sum of all the delegated votes!
  78. *
  79. * Requirements:
  80. *
  81. * - `blockNumber` must have been already mined
  82. */
  83. function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {
  84. require(blockNumber < block.number, "ERC20Votes: block not yet mined");
  85. return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);
  86. }
  87. /**
  88. * @dev Lookup a value in a list of (sorted) checkpoints.
  89. */
  90. function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {
  91. // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.
  92. //
  93. // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).
  94. // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.
  95. // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)
  96. // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)
  97. // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not
  98. // out of bounds (in which case we're looking too far in the past and the result is 0).
  99. // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is
  100. // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out
  101. // the same.
  102. uint256 high = ckpts.length;
  103. uint256 low = 0;
  104. while (low < high) {
  105. uint256 mid = MathUpgradeable.average(low, high);
  106. if (ckpts[mid].fromBlock > blockNumber) {
  107. high = mid;
  108. } else {
  109. low = mid + 1;
  110. }
  111. }
  112. return high == 0 ? 0 : ckpts[high - 1].votes;
  113. }
  114. /**
  115. * @dev Delegate votes from the sender to `delegatee`.
  116. */
  117. function delegate(address delegatee) public virtual override {
  118. _delegate(_msgSender(), delegatee);
  119. }
  120. /**
  121. * @dev Delegates votes from signer to `delegatee`
  122. */
  123. function delegateBySig(
  124. address delegatee,
  125. uint256 nonce,
  126. uint256 expiry,
  127. uint8 v,
  128. bytes32 r,
  129. bytes32 s
  130. ) public virtual override {
  131. require(block.timestamp <= expiry, "ERC20Votes: signature expired");
  132. address signer = ECDSAUpgradeable.recover(
  133. _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),
  134. v,
  135. r,
  136. s
  137. );
  138. require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce");
  139. _delegate(signer, delegatee);
  140. }
  141. /**
  142. * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).
  143. */
  144. function _maxSupply() internal view virtual returns (uint224) {
  145. return type(uint224).max;
  146. }
  147. /**
  148. * @dev Snapshots the totalSupply after it has been increased.
  149. */
  150. function _mint(address account, uint256 amount) internal virtual override {
  151. super._mint(account, amount);
  152. require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes");
  153. _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);
  154. }
  155. /**
  156. * @dev Snapshots the totalSupply after it has been decreased.
  157. */
  158. function _burn(address account, uint256 amount) internal virtual override {
  159. super._burn(account, amount);
  160. _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);
  161. }
  162. /**
  163. * @dev Move voting power when tokens are transferred.
  164. *
  165. * Emits a {DelegateVotesChanged} event.
  166. */
  167. function _afterTokenTransfer(
  168. address from,
  169. address to,
  170. uint256 amount
  171. ) internal virtual override {
  172. super._afterTokenTransfer(from, to, amount);
  173. _moveVotingPower(delegates(from), delegates(to), amount);
  174. }
  175. /**
  176. * @dev Change delegation for `delegator` to `delegatee`.
  177. *
  178. * Emits events {DelegateChanged} and {DelegateVotesChanged}.
  179. */
  180. function _delegate(address delegator, address delegatee) internal virtual {
  181. address currentDelegate = delegates(delegator);
  182. uint256 delegatorBalance = balanceOf(delegator);
  183. _delegates[delegator] = delegatee;
  184. emit DelegateChanged(delegator, currentDelegate, delegatee);
  185. _moveVotingPower(currentDelegate, delegatee, delegatorBalance);
  186. }
  187. function _moveVotingPower(
  188. address src,
  189. address dst,
  190. uint256 amount
  191. ) private {
  192. if (src != dst && amount > 0) {
  193. if (src != address(0)) {
  194. (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);
  195. emit DelegateVotesChanged(src, oldWeight, newWeight);
  196. }
  197. if (dst != address(0)) {
  198. (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);
  199. emit DelegateVotesChanged(dst, oldWeight, newWeight);
  200. }
  201. }
  202. }
  203. function _writeCheckpoint(
  204. Checkpoint[] storage ckpts,
  205. function(uint256, uint256) view returns (uint256) op,
  206. uint256 delta
  207. ) private returns (uint256 oldWeight, uint256 newWeight) {
  208. uint256 pos = ckpts.length;
  209. oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;
  210. newWeight = op(oldWeight, delta);
  211. if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {
  212. ckpts[pos - 1].votes = SafeCastUpgradeable.toUint224(newWeight);
  213. } else {
  214. ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(block.number), votes: SafeCastUpgradeable.toUint224(newWeight)}));
  215. }
  216. }
  217. function _add(uint256 a, uint256 b) private pure returns (uint256) {
  218. return a + b;
  219. }
  220. function _subtract(uint256 a, uint256 b) private pure returns (uint256) {
  221. return a - b;
  222. }
  223. /**
  224. * This empty reserved space is put in place to allow future versions to add new
  225. * variables without shifting down storage in the inheritance chain.
  226. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
  227. */
  228. uint256[47] private __gap;
  229. }