Skip to content

Commit

Permalink
feat: add importing existing token to token voting docs
Browse files Browse the repository at this point in the history
  • Loading branch information
clauBv23 committed Dec 14, 2024
1 parent f2ac6a2 commit 904af84
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packages/contracts/docs/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
* xref:index.adoc[Overview]
* xref:index.adoc[Overview]
* xref:importing-existent-tokens.adoc[Importing Existing Tokens]
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
= Importing Existing Tokens

For tokens to natively support onchain governance, they must prevent “double voting”—where a holder votes, then transfers tokens to another address, and votes again, effectively using the same tokens twice. To ensure voting power is accurately recorded and cannot be manipulated mid-vote, the recommended approach is to deploy a token using the `ERC20Votes` pattern from link:https://docs.openzeppelin.com/contracts/5.x/api/governance#Votes[OpenZeppelin]. This pattern enables snapshotting, allowing governance contracts to reference a token holder’s voting power at a specific point in time (e.g., when the proposal was created).

*The TokenVoting plugin is only compatible with tokens that implement `ERC20Votes` or provide equivalent snapshotting functionality (`IVotesUpgradeable`)*

The plugin’s setup contract offers three options:

1. *Mint a New `ERC20Votes` Token:*
+
The setup can deploy a new governance token contract already configured with `ERC20Votes`.
+
2. *Import an Existing `ERC20Votes`Compatible Token:*
+
If you already have a token with built-in snapshotting capabilities, you can directly import it. The setup script will verify its compatibility before using it in the TokenVoting plugin.
+
3. *Wrap an Incompatible ERC20 Token:*
+
If your existing token does not support `ERC20Votes`, the setup can wrap it in a `GovernanceWrappedERC20` contract. This approach imposes additional complexity and friction for voters, as tokens must be locked into the wrapper to gain voting power.
+
> *Important:* If you are currently planning to deploy a token for governance, consider choosing `ERC20Votes`. Introducing a wrapper later on can significantly impact token liquidity and increase governance overhead. If you have concerns or need guidance link:https://discord.com/invite/aragonorg[reach out to the Aragon team] for assistance.
>

== Importing an Existing Token

If you already have a token or plan to deploy one on your own, the plugin’s setup script will check your token’s compatibility prior to letting you use it in TokenVoting. To pass these checks, the token must implement the following functions (typically provided by `IVotesUpgradeable`):

- `getPastVotes(address voter, uint256 timepoint)`: Returns the voting power of a given address at a specific block or timestamp.
- `getVotes(address voter)`: Returns the current voting power of the given address.
- `getPastTotalSupply(uint256 timepoint)`: Returns the total voting power at a specific block or timestamp.

These functions ensure reliable historical voting data, preventing double voting. If your token does not have these functions, the setup will wrap it with `GovernanceWrappedERC20` to add them. If your token was recently deployed, explore with your team or community if this wrapped governance experience is acceptable. Alternatively, issuing a new token with the necessary governance functionality built-in may be a better long-term solution.

0 comments on commit 904af84

Please sign in to comment.