Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ERC721Votes for NFT-based governance #2944

Merged
merged 329 commits into from
Dec 10, 2021
Merged
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
329 commits
Select commit Hold shift + click to select a range
abeaf5c
Fixing checkpoints count
JulissaDantes Oct 31, 2021
798baa0
Updating ERC721Vote tests
JulissaDantes Oct 31, 2021
4f5a44d
Renaming supplied tokenId on tests
JulissaDantes Nov 1, 2021
13d4a91
Updating tests based on new contract changes
JulissaDantes Nov 1, 2021
6ae58d3
Updating execution order inside of mint
JulissaDantes Nov 2, 2021
c8abe20
Adding Mocks for testing and integrating nft minting to current workf…
JulissaDantes Nov 2, 2021
a5d52d9
Governance adocs update
JulissaDantes Nov 2, 2021
a2ec66b
Updating contracts listing order
JulissaDantes Nov 3, 2021
d8147d4
Following lint suggestions
JulissaDantes Nov 3, 2021
2b03bf9
Delete of test contract
JulissaDantes Nov 3, 2021
c987124
Merge branch 'master' of https://github.com/JulissaDantes/openzeppeli…
JulissaDantes Nov 24, 2021
69c6bb1
Delete unused test file
JulissaDantes Nov 24, 2021
339aa31
Update changelog
JulissaDantes Nov 25, 2021
1cabd29
Create Checkpoints and Voting libraries
JulissaDantes Nov 25, 2021
ec5ea0e
Update ERC721Votes contract to use library
JulissaDantes Nov 25, 2021
5f15d46
Add function to Voting library
JulissaDantes Nov 26, 2021
82b1565
Update ERC721Governance contracts
JulissaDantes Nov 26, 2021
8e3feae
Documentation for Checkpoints library
JulissaDantes Nov 26, 2021
d3f3502
Add documentation for Voting library
JulissaDantes Nov 26, 2021
1b95cc8
Add Mock contracts for Voting and checkpoints test
JulissaDantes Nov 26, 2021
9335d04
Add Voting library tests
JulissaDantes Nov 26, 2021
c88fd74
Add Checkpoints library tests
JulissaDantes Nov 26, 2021
b2c0568
Add more documentation for voting library
JulissaDantes Nov 26, 2021
f0dc612
Merge pull request #12 from JulissaDantes/VotingLibrary
JulissaDantes Nov 26, 2021
88edb90
Merge branch 'master' into ERC721Governance
JulissaDantes Nov 26, 2021
a0a26ce
Initial contracts creation
JulissaDantes Oct 31, 2021
0991757
creating permit tests
JulissaDantes Oct 31, 2021
9c3f9fd
Fixing checkpoints count
JulissaDantes Oct 31, 2021
0b0406e
Updating ERC721Vote tests
JulissaDantes Oct 31, 2021
4d3ca3a
Updating ERC721Vote tests descriptions
JulissaDantes Oct 31, 2021
d71fb49
Updating ERC721Vote contract and tests
JulissaDantes Oct 31, 2021
dd4a695
Finished tests
JulissaDantes Nov 1, 2021
2d834df
Adding _afterTokenTransfer to base ERC271 contract
JulissaDantes Nov 1, 2021
a207eb5
Renaming supplied tokenId on tests
JulissaDantes Nov 1, 2021
052d4a1
Updating tests based on new contract changes
JulissaDantes Nov 1, 2021
adbbbfb
Updating execution order inside of mint
JulissaDantes Nov 2, 2021
4899be8
Adding Mocks for testing and integrating nft minting to current workf…
JulissaDantes Nov 2, 2021
1f85057
Implementing override test
JulissaDantes Nov 2, 2021
3d0f1e4
Removing .only from tests
JulissaDantes Nov 2, 2021
9a3f2a1
Updating contracts READMEs
JulissaDantes Nov 2, 2021
f3d8453
Governance adocs update
JulissaDantes Nov 2, 2021
ec047ac
Removing test contract
JulissaDantes Nov 3, 2021
1179e90
Initial contracts creation
JulissaDantes Oct 31, 2021
913946b
creating permit tests
JulissaDantes Oct 31, 2021
e999d78
Fixing checkpoints count
JulissaDantes Oct 31, 2021
3c63a1d
Updating ERC721Vote tests
JulissaDantes Oct 31, 2021
b42d0ab
Renaming supplied tokenId on tests
JulissaDantes Nov 1, 2021
dc0ec55
Updating tests based on new contract changes
JulissaDantes Nov 1, 2021
9d0f7fe
Updating execution order inside of mint
JulissaDantes Nov 2, 2021
9efd8c1
Adding Mocks for testing and integrating nft minting to current workf…
JulissaDantes Nov 2, 2021
87cf640
Governance adocs update
JulissaDantes Nov 2, 2021
b135af5
Updating contracts listing order
JulissaDantes Nov 3, 2021
510c373
Following lint suggestions
JulissaDantes Nov 3, 2021
f58c91e
Delete of test contract
JulissaDantes Nov 3, 2021
8663d84
Initial contracts creation
JulissaDantes Oct 31, 2021
6d69091
creating permit tests
JulissaDantes Oct 31, 2021
72c887d
Fixing checkpoints count
JulissaDantes Oct 31, 2021
b94e475
Updating ERC721Vote tests
JulissaDantes Oct 31, 2021
a7397ba
Updating ERC721Vote tests descriptions
JulissaDantes Oct 31, 2021
6ed1ccd
Adding _afterTokenTransfer to base ERC271 contract
JulissaDantes Nov 1, 2021
718274a
Updating tests based on new contract changes
JulissaDantes Nov 1, 2021
e341b83
Governance adocs update
JulissaDantes Nov 2, 2021
130664e
Removing test contract
JulissaDantes Nov 3, 2021
5c9e993
Initial contracts creation
JulissaDantes Oct 31, 2021
1ad617a
creating permit tests
JulissaDantes Oct 31, 2021
13d3b7c
Fixing checkpoints count
JulissaDantes Oct 31, 2021
f9fa57a
Updating ERC721Vote tests
JulissaDantes Oct 31, 2021
af0d1a5
Updating ERC721Vote contract and tests
JulissaDantes Oct 31, 2021
3ccfdd9
Adding _afterTokenTransfer to base ERC271 contract
JulissaDantes Nov 1, 2021
05e8cee
Renaming supplied tokenId on tests
JulissaDantes Nov 1, 2021
b9c8e7b
Updating tests based on new contract changes
JulissaDantes Nov 1, 2021
068da60
Updating execution order inside of mint
JulissaDantes Nov 2, 2021
e350d15
Adding Mocks for testing and integrating nft minting to current workf…
JulissaDantes Nov 2, 2021
c5f44f7
Implementing override test
JulissaDantes Nov 2, 2021
7a9228f
Governance adocs update
JulissaDantes Nov 2, 2021
49a378f
Updating contracts listing order
JulissaDantes Nov 3, 2021
22c672e
Delete of test contract
JulissaDantes Nov 3, 2021
514e0aa
Updating comment and documentation
JulissaDantes Nov 3, 2021
074430d
Update docs/modules/ROOT/pages/governance.adoc
JulissaDantes Nov 4, 2021
a9d6cff
Improving documentation, adding spaces, renaming variables
JulissaDantes Nov 4, 2021
05ed326
Update contracts/token/ERC721/extensions/ERC721Votes.sol
JulissaDantes Nov 4, 2021
3eb6d74
Update contracts/token/ERC721/extensions/ERC721Votes.sol
JulissaDantes Nov 4, 2021
d8ff5cc
Update docs/modules/ROOT/pages/governance.adoc
JulissaDantes Nov 4, 2021
367f9bb
Adding constructor
JulissaDantes Nov 4, 2021
cca8ff2
Updating tests setting more NFT voting power to single voter
JulissaDantes Nov 4, 2021
1e0f543
Update erc721.adoc
JulissaDantes Nov 4, 2021
84d97db
Adding method to return token voting power
JulissaDantes Nov 4, 2021
8147461
Delete local file
JulissaDantes Nov 4, 2021
c914c84
Update contracts/token/ERC721/extensions/draft-ERC721Votes.sol
JulissaDantes Nov 5, 2021
2a45f36
Including getVotingPower
JulissaDantes Nov 5, 2021
deb2b1e
After prettier run, updating format
JulissaDantes Nov 5, 2021
6fe31e9
Renaming totalSupply to totalVotingPower for the code to be cleaner
JulissaDantes Nov 5, 2021
51ade3f
Update changelog
JulissaDantes Nov 25, 2021
3aec0a7
Create Checkpoints and Voting libraries
JulissaDantes Nov 25, 2021
41aa303
Update ERC721Votes contract to use library
JulissaDantes Nov 25, 2021
4d1912b
Add function to Voting library
JulissaDantes Nov 26, 2021
2524a87
Update ERC721Governance contracts
JulissaDantes Nov 26, 2021
1e46d25
Documentation for Checkpoints library
JulissaDantes Nov 26, 2021
7d4c5fe
Add documentation for Voting library
JulissaDantes Nov 26, 2021
44df89d
Add Mock contracts for Voting and checkpoints test
JulissaDantes Nov 26, 2021
55213f5
Add Voting library tests
JulissaDantes Nov 26, 2021
054c78f
Add Checkpoints library tests
JulissaDantes Nov 26, 2021
92936c8
Add more documentation for voting library
JulissaDantes Nov 26, 2021
c7c9b29
Lint run
JulissaDantes Nov 26, 2021
d05cb0a
change after rebase
JulissaDantes Nov 26, 2021
8582932
Merge branch 'master' into ERC721Governance
JulissaDantes Nov 26, 2021
b57a3dc
Remove empty spaces
JulissaDantes Nov 26, 2021
02115ae
Run prettier
JulissaDantes Nov 26, 2021
abc90f9
Merge pull request #13 from JulissaDantes/ERC721Governance
JulissaDantes Nov 26, 2021
51002f9
Remove whitespaces
JulissaDantes Nov 29, 2021
54d80db
Remove whitespaces
JulissaDantes Nov 29, 2021
acd9a00
Update changelog after merge
JulissaDantes Nov 29, 2021
7f5a8f4
Merge pull request #14 from JulissaDantes/ERC721Governance
JulissaDantes Nov 29, 2021
c919980
Initial contracts creation
JulissaDantes Oct 31, 2021
5a10153
creating permit tests
JulissaDantes Oct 31, 2021
792ce18
Fixing checkpoints count
JulissaDantes Oct 31, 2021
71301aa
Updating ERC721Vote tests
JulissaDantes Oct 31, 2021
9c39e32
Updating ERC721Vote tests descriptions
JulissaDantes Oct 31, 2021
a3396c5
Updating ERC721Vote contract and tests
JulissaDantes Oct 31, 2021
3aef1f9
Finished tests
JulissaDantes Nov 1, 2021
9784e04
Adding _afterTokenTransfer to base ERC271 contract
JulissaDantes Nov 1, 2021
1a3dc28
Renaming supplied tokenId on tests
JulissaDantes Nov 1, 2021
e37f4bf
Updating tests based on new contract changes
JulissaDantes Nov 1, 2021
f275406
Updating execution order inside of mint
JulissaDantes Nov 2, 2021
6a9caf0
Adding Mocks for testing and integrating nft minting to current workf…
JulissaDantes Nov 2, 2021
5a58fc2
Implementing override test
JulissaDantes Nov 2, 2021
e07dfa6
Removing .only from tests
JulissaDantes Nov 2, 2021
0bc0ab5
Updating contracts READMEs
JulissaDantes Nov 2, 2021
61523ed
Governance adocs update
JulissaDantes Nov 2, 2021
f82873e
Removing test contract
JulissaDantes Nov 3, 2021
4f0f39e
Initial contracts creation
JulissaDantes Oct 31, 2021
acc4aa7
creating permit tests
JulissaDantes Oct 31, 2021
82e313b
Fixing checkpoints count
JulissaDantes Oct 31, 2021
e55511a
Updating ERC721Vote tests
JulissaDantes Oct 31, 2021
9eaa01d
Renaming supplied tokenId on tests
JulissaDantes Nov 1, 2021
29b0e16
Updating tests based on new contract changes
JulissaDantes Nov 1, 2021
3c49d6c
Updating execution order inside of mint
JulissaDantes Nov 2, 2021
d344647
Adding Mocks for testing and integrating nft minting to current workf…
JulissaDantes Nov 2, 2021
d687e09
Governance adocs update
JulissaDantes Nov 2, 2021
101a82c
Updating contracts listing order
JulissaDantes Nov 3, 2021
5201c96
Following lint suggestions
JulissaDantes Nov 3, 2021
4f9cc0a
Delete of test contract
JulissaDantes Nov 3, 2021
4175ade
Updating comment and documentation
JulissaDantes Nov 3, 2021
c8e1c94
Update docs/modules/ROOT/pages/governance.adoc
JulissaDantes Nov 4, 2021
de45b91
Update contracts/token/ERC721/extensions/ERC721Votes.sol
JulissaDantes Nov 4, 2021
6af56a9
Update docs/modules/ROOT/pages/governance.adoc
JulissaDantes Nov 4, 2021
9079397
Update erc721.adoc
JulissaDantes Nov 4, 2021
6eb60da
Delete unused test file
JulissaDantes Nov 24, 2021
29e7a02
Create Checkpoints and Voting libraries
JulissaDantes Nov 25, 2021
9a26c4d
Add function to Voting library
JulissaDantes Nov 26, 2021
af23b86
Documentation for Checkpoints library
JulissaDantes Nov 26, 2021
9b4d4cf
Add Mock contracts for Voting and checkpoints test
JulissaDantes Nov 26, 2021
aa3c0db
Governance adocs update
JulissaDantes Nov 2, 2021
2a3e090
Removing test contract
JulissaDantes Nov 3, 2021
e3730e1
Initial contracts creation
JulissaDantes Oct 31, 2021
731586f
Renaming supplied tokenId on tests
JulissaDantes Nov 1, 2021
9dad235
Updating contracts listing order
JulissaDantes Nov 3, 2021
ae4d235
Fixing checkpoints count
JulissaDantes Oct 31, 2021
897938f
Adding _afterTokenTransfer to base ERC271 contract
JulissaDantes Nov 1, 2021
c0cab85
Governance adocs update
JulissaDantes Nov 2, 2021
3b031da
Removing test contract
JulissaDantes Nov 3, 2021
9829c08
creating permit tests
JulissaDantes Oct 31, 2021
ada5c98
Adding Mocks for testing and integrating nft minting to current workf…
JulissaDantes Nov 2, 2021
c730f4d
Implementing override test
JulissaDantes Nov 2, 2021
98a6618
Updating contracts listing order
JulissaDantes Nov 3, 2021
ef43fb2
Update erc721.adoc
JulissaDantes Nov 4, 2021
ec7e892
Update changelog
JulissaDantes Nov 25, 2021
b813f9c
Run prettier
JulissaDantes Nov 26, 2021
09da50d
Update changelog after merge
JulissaDantes Nov 29, 2021
e0e8d74
Update after rebase
JulissaDantes Nov 29, 2021
fb2bd07
Merge branch 'master' of https://github.com/JulissaDantes/openzeppeli…
JulissaDantes Nov 29, 2021
d7f1dda
Remove unused library
JulissaDantes Nov 29, 2021
5506617
Prevent version mismatch
JulissaDantes Nov 29, 2021
25eadd0
Merge pull request #15 from JulissaDantes/ERC721Governance
JulissaDantes Nov 30, 2021
424af50
Remove minting restriction
JulissaDantes Nov 30, 2021
b2b7f5b
Remove afterToken transfer and Add _transfer function
JulissaDantes Nov 30, 2021
ef252c9
Remove checkpoints methods
JulissaDantes Nov 30, 2021
83eeac5
Update contract structure
JulissaDantes Dec 1, 2021
176d166
Add _getDelegatorVotes function for ERC721Votes
JulissaDantes Dec 1, 2021
bb32fba
Update Voting test and Mock
JulissaDantes Dec 1, 2021
1d0c1ea
Update Votes mock and tests
JulissaDantes Dec 2, 2021
3e14830
Fix functions visibility on Votes contract
JulissaDantes Dec 2, 2021
f7a7b51
Run lint
JulissaDantes Dec 2, 2021
5740f3c
Merge pull request #16 from JulissaDantes/ERC721Governance
JulissaDantes Dec 2, 2021
5704b3b
Fix delegation, add test coverage, fix moveVotingPower
JulissaDantes Dec 2, 2021
be216d0
Merge pull request #17 from JulissaDantes/ERC721Governance
JulissaDantes Dec 2, 2021
c37502f
Change inheritance order
JulissaDantes Dec 2, 2021
a28a4b2
Merge pull request #18 from JulissaDantes/ERC721Governance
JulissaDantes Dec 2, 2021
9ea08be
Update documentation contract
JulissaDantes Dec 2, 2021
6bcff2b
Update CHANGELOG.md
JulissaDantes Dec 3, 2021
73bb657
Update checkpoints storage variable names
JulissaDantes Dec 3, 2021
3ffdb76
Update docs/modules/ROOT/pages/governance.adoc
JulissaDantes Dec 3, 2021
b6cbe1d
Update variable names, Remove index based functions, update documenta…
JulissaDantes Dec 3, 2021
099fa20
Merge branch 'ERC721Governance' of https://github.com/JulissaDantes/o…
JulissaDantes Dec 3, 2021
f054441
Update delegate arguments, rename variables, add function call on bas…
JulissaDantes Dec 3, 2021
0c8b601
Update _moveVotingPower
JulissaDantes Dec 3, 2021
7de147c
Update tests
JulissaDantes Dec 3, 2021
d852c08
Run lint
JulissaDantes Dec 3, 2021
5efd9a2
Add IVote interface an update tests
JulissaDantes Dec 3, 2021
052f064
Remove .only from test
JulissaDantes Dec 3, 2021
76d47c7
Merge pull request #19 from JulissaDantes/ERC721Governance
JulissaDantes Dec 3, 2021
499559a
Merge branch 'master' of https://github.com/OpenZeppelin/openzeppelin…
JulissaDantes Dec 3, 2021
eb6304b
Update contract inheriting from GovernorVotes
JulissaDantes Dec 3, 2021
e5fecaf
Indentitation/format consistency
Amxx Dec 3, 2021
9addc4f
Improve format
JulissaDantes Dec 3, 2021
f536b1b
Merge branch 'ERC721Governance' of https://github.com/JulissaDantes/o…
JulissaDantes Dec 3, 2021
b8639e7
Update contracts/utils/Votes.sol
JulissaDantes Dec 3, 2021
f5f6aab
Update contracts/token/ERC20/extensions/ERC20Votes.sol
JulissaDantes Dec 3, 2021
87bd7b2
Update contracts/utils/Checkpoints.sol
JulissaDantes Dec 3, 2021
93a2079
Update IVotes and Votes directory
JulissaDantes Dec 3, 2021
829f074
Remove .only from test files
JulissaDantes Dec 3, 2021
8fdb1e0
Update storage variables names
JulissaDantes Dec 3, 2021
dfe225c
Change inheritance order
JulissaDantes Dec 3, 2021
ee10185
Merge pull request #20 from JulissaDantes/ERC721Governance
JulissaDantes Dec 3, 2021
1cca7be
Add function to handle mint and burn before moving voting power
JulissaDantes Dec 6, 2021
c173749
Update README.adoc
frangio Dec 6, 2021
f2cccc3
rename files to new names
frangio Dec 6, 2021
2f8cf7b
Rename function getTotalSupply
JulissaDantes Dec 6, 2021
628567c
Merge branch 'ERC721Governance' of https://github.com/JulissaDantes/o…
JulissaDantes Dec 6, 2021
edf795b
Change test function name
JulissaDantes Dec 6, 2021
7f90b88
Fix documentation after function rename
JulissaDantes Dec 6, 2021
7cda9a3
improve documentation
frangio Dec 6, 2021
a82fc9c
Update Votes.sol documentation
JulissaDantes Dec 6, 2021
b171720
Add Chekpoints.sol documentation
JulissaDantes Dec 6, 2021
7e134d8
Improve ERc721 documentation
JulissaDantes Dec 6, 2021
1197d84
Erc721 governance documentation improvement (#21)
JulissaDantes Dec 6, 2021
c60d9b5
add Checkpoints: prefix to revert reason
frangio Dec 6, 2021
81972f7
fix revert reason
frangio Dec 6, 2021
4773334
remove revert reason prefix from test
frangio Dec 6, 2021
7ead55f
Update CHANGELOG.md
JulissaDantes Dec 7, 2021
f099426
Add checkpoints tests
JulissaDantes Dec 7, 2021
c4d3dfd
Improve format
JulissaDantes Dec 7, 2021
43abcee
revert back to previous error message
frangio Dec 8, 2021
cd3ab17
restructure Checkpoints tests
frangio Dec 8, 2021
c349618
lint
frangio Dec 8, 2021
ebd3082
improve Checkpoints docs
frangio Dec 8, 2021
ce1df1f
Update revert message
JulissaDantes Dec 8, 2021
5cb991b
Add VotesWorklfow to aid testing
JulissaDantes Dec 8, 2021
37c9e73
Add mint before delegate on votes tests
JulissaDantes Dec 8, 2021
d556b27
Merge branch 'ERC721Governance' of https://github.com/JulissaDantes/o…
JulissaDantes Dec 8, 2021
94d63e0
Update token specific test for ERC721Votes
JulissaDantes Dec 8, 2021
547cba4
Merge branch 'master' into ERC721Governance
JulissaDantes Dec 8, 2021
90ca1e2
remove added whitespace
frangio Dec 10, 2021
9d705ce
further improve docs and rename for new concept of vote units
frangio Dec 10, 2021
8e74446
rename VotesWorkflow to Votes behavior
frangio Dec 10, 2021
d6ae076
remove unused helpers
frangio Dec 10, 2021
92537f3
Rename tests variables based on contract renamed variable
JulissaDantes Dec 10, 2021
b306e61
fix missing name variable
frangio Dec 10, 2021
53847b4
revert event argument change
frangio Dec 10, 2021
bd6ec00
Merge branch 'master' into ERC721Governance
frangio Dec 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

* `Voting`: Added a library for vote tracking with delegation. ([#2944](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2944))
JulissaDantes marked this conversation as resolved.
Show resolved Hide resolved
* `ERC721Votes`: Added an extension of ERC721 enabled with vote tracking and delegation. ([#2944](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2944))
* `GovernorTimelockControl`: improve the `state()` function to have it reflect cases where a proposal has been canceled directly on the timelock. ([#2977](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2977))
* `Math`: add a `abs(int256)` method that returns the unsigned absolute value of a signed value. ([#2984](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2984))
* Preset contracts are now deprecated in favor of [Contracts Wizard](https://wizard.openzeppelin.com). ([#2986](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2986))
Expand Down
2 changes: 1 addition & 1 deletion contracts/governance/IGovernor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ abstract contract IGovernor is IERC165 {
function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance);

/**
* @dev Cast a with a reason
* @dev Cast a vote with a reason
*
* Emits a {VoteCast} event.
*/
Expand Down
5 changes: 5 additions & 0 deletions contracts/governance/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,17 @@ NOTE: Functions of the `Governor` contract do not include access control. If you

{{GovernorProposalThreshold}}

== Utils

{{Votes}}

== Timelock

In a governance system, the {TimelockController} contract is in charge of introducing a delay between a proposal and its execution. It can be used with or without a {Governor}.

{{TimelockController}}


[[timelock-terminology]]
==== Terminology

Expand Down
9 changes: 4 additions & 5 deletions contracts/governance/extensions/GovernorVotes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@
pragma solidity ^0.8.0;

import "../Governor.sol";
import "../../token/ERC20/extensions/ERC20Votes.sol";
import "../../utils/math/Math.sol";
import "../utils/IVotes.sol";

/**
* @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token.
* @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} token.
*
* _Available since v4.3._
*/
abstract contract GovernorVotes is Governor {
ERC20Votes public immutable token;
IVotes public immutable token;

constructor(ERC20Votes tokenAddress) {
constructor(IVotes tokenAddress) {
token = tokenAddress;
}

Expand Down
52 changes: 52 additions & 0 deletions contracts/governance/utils/IVotes.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (interfaces/IVotes.sol)
pragma solidity ^0.8.0;

/**
* @dev Interface of the Votes standard.
*
* _Available since v4.4._
*/
interface IVotes {
/**
* @dev Returns total amount of votes for account.
*/
function getVotes(address account) external view returns (uint256);

/**
* @dev Returns total amount of votes at given blockNumber.
*/
function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);

/**
* @dev Retrieve the `totalVotingPower` at the end of `blockNumber`. Note, this value is the sum of all balances.
* It is but NOT the sum of all the delegated votes!
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);

/**
* @dev Returns account delegation.
*/
function delegates(address account) external view returns (address);

/**
* @dev Delegate votes from the sender to `delegatee`.
*/
function delegate(address delegatee) external;

/**
* @dev Delegates votes from signer to `delegatee`
*/
function delegateBySig(
address delegatee,
uint256 nonce,
uint256 expiry,
uint8 v,
bytes32 r,
bytes32 s
) external;
}
217 changes: 217 additions & 0 deletions contracts/governance/utils/Votes.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../../utils/Context.sol";
import "../../utils/Counters.sol";
import "../../utils/Checkpoints.sol";
import "../../utils/cryptography/draft-EIP712.sol";
import "./IVotes.sol";

/**
* @dev This is a base abstract contract that tracks voting power for a set of accounts with a vote delegation system.
* It can be combined with a token contract to represent voting power as the token unit, see {ERC721Votes}.
*
* 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 {getVotes}.
*
* 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.
* Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this
* will significantly increase the base gas cost of transfers.
*
* When using this module, the derived contract must implement {_getDelegatorVotingPower}, and can use {_transferVotingAssets}
* when a delegator's voting power is changed.
*
* _Available since v4.5._
*/
JulissaDantes marked this conversation as resolved.
Show resolved Hide resolved
abstract contract Votes is IVotes, Context, EIP712 {
using Checkpoints for Checkpoints.History;
using Counters for Counters.Counter;

bytes32 private constant _DELEGATION_TYPEHASH =
keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

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

mapping(address => Counters.Counter) private _nonces;

/**
* @dev Emitted when an account changes their delegate.
*/
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

/**
* @dev Emitted when a token transfer or delegate change results in changes to an account's voting power.
*/
event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

/**
* @dev Returns total amount of votes for account.
*/
function getVotes(address account) public view virtual override returns (uint256) {
return _delegateCheckpoints[account].latest();
}

/**
* @dev Returns total amount of votes at given blockNumber for account.
*/
function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {
return _delegateCheckpoints[account].getAtBlock(blockNumber);
}

/**
* @dev Retrieve the votes total supply at the end of `blockNumber`. Note, this value is the sum of all balances.
* It is but NOT the sum of all the delegated votes!
*
* Requirements:
*
* - `blockNumber` must have been already mined
*/
function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {
require(blockNumber < block.number, "ERC721Votes: block not yet mined");
return _totalCheckpoints.getAtBlock(blockNumber);
}

/**
* @dev Returns total amount of votes.
*/
function _getTotalSupply() internal view virtual returns (uint256) {
return _totalCheckpoints.latest();
}

/**
* @dev Returns account delegation.
*/
function delegates(address account) public view virtual override returns (address) {
return _delegation[account];
}

/**
* @dev Delegate votes from the sender to `delegatee`.
*/
function delegate(address delegatee) public virtual override {
address delegator = _msgSender();
_delegate(delegator, delegatee);
}

/**
* @dev Delegates votes from signer to `delegatee`
*/
function delegateBySig(
address delegatee,
uint256 nonce,
uint256 expiry,
uint8 v,
bytes32 r,
bytes32 s
) public virtual override {
require(block.timestamp <= expiry, "ERC721Votes: signature expired");
address signer = ECDSA.recover(
_hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),
v,
r,
s
);
require(nonce == _useNonce(signer), "ERC721Votes: invalid nonce");
_delegate(signer, delegatee);
}

/**
* @dev Change delegation for `delegator` to `delegatee`.
*
* Emits events {DelegateChanged} and {DelegateVotesChanged}.
*/
function _delegate(address delegator, address newDelegation) internal virtual {
address oldDelegation = delegates(delegator);
_delegation[delegator] = newDelegation;

emit DelegateChanged(delegator, oldDelegation, newDelegation);

_moveVotingPower(oldDelegation, newDelegation, _getDelegatorVotingPower(delegator));
}

/**
* @dev Transfers voting assets.
*/
function _transferVotingAssets(
address from,
address to,
uint256 amount
) internal virtual {
if (from == address(0)) {
_totalCheckpoints.push(_add, amount);
}
if (to == address(0)) {
_totalCheckpoints.push(_subtract, amount);
}
_moveVotingPower(delegates(from), delegates(to), amount);
}

/**
* @dev Moves voting power.
*/
function _moveVotingPower(
address from,
address to,
uint256 amount
) private {
if (from != to && amount > 0) {
if (from != address(0)) {
(uint256 oldValue, uint256 newValue) = _delegateCheckpoints[from].push(_subtract, amount);
emit DelegateVotesChanged(from, oldValue, newValue);
}
if (to != address(0)) {
(uint256 oldValue, uint256 newValue) = _delegateCheckpoints[to].push(_add, amount);
emit DelegateVotesChanged(to, oldValue, newValue);
}
}
}

/**
* @dev Adds two numbers.
*/
function _add(uint256 a, uint256 b) private pure returns (uint256) {
return a + b;
}

/**
* @dev Subtracts two numbers.
*/
function _subtract(uint256 a, uint256 b) private pure returns (uint256) {
return a - b;
}

/**
* @dev Consumes a nonce.
*
* Returns the current value and increments nonce.
*/
function _useNonce(address owner) internal virtual returns (uint256 current) {
Counters.Counter storage nonce = _nonces[owner];
current = nonce.current();
nonce.increment();
}

/**
* @dev Returns an address nonce.
*/
function nonces(address owner) public view virtual returns (uint256) {
return _nonces[owner].current();
}

/**
* @dev Returns DOMAIN_SEPARATOR.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32) {
return _domainSeparatorV4();
}

/**
* @dev Returns the balance of the delegator account
*/
function _getDelegatorVotingPower(address) internal virtual returns (uint256);
}
23 changes: 23 additions & 0 deletions contracts/mocks/CheckpointsImpl.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Checkpoints.sol";

contract CheckpointsImpl {
using Checkpoints for Checkpoints.History;

Checkpoints.History private _totalCheckpoints;

function latest() public view returns (uint256) {
return _totalCheckpoints.latest();
}

function getAtBlock(uint256 blockNumber) public view returns (uint256) {
return _totalCheckpoints.getAtBlock(blockNumber);
}

function push(uint256 value) public returns (uint256, uint256) {
return _totalCheckpoints.push(value);
}
}
21 changes: 21 additions & 0 deletions contracts/mocks/ERC721VotesMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../token/ERC721/extensions/draft-ERC721Votes.sol";

contract ERC721VotesMock is ERC721Votes {
constructor(string memory name, string memory symbol) ERC721(name, symbol) EIP712(name, "1") {}

function mint(address account, uint256 tokenId) public {
_mint(account, tokenId);
}

function burn(uint256 tokenId) public {
_burn(tokenId);
}

function getChainId() external view returns (uint256) {
return block.chainid;
}
}
2 changes: 1 addition & 1 deletion contracts/mocks/GovernorMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ contract GovernorMock is
{
constructor(
string memory name_,
ERC20Votes token_,
IVotes token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 quorumNumerator_
Expand Down
2 changes: 1 addition & 1 deletion contracts/mocks/GovernorPreventLateQuorumMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ contract GovernorPreventLateQuorumMock is

constructor(
string memory name_,
ERC20Votes token_,
IVotes token_,
uint256 votingDelay_,
uint256 votingPeriod_,
uint256 quorum_,
Expand Down