2021-12-01 23:06:56 -08:00
|
|
|
# Description
|
|
|
|
|
|
|
|
Voter-stake-registry is a voter weight addin for Solana's
|
|
|
|
[spl-governance program](https://github.com/solana-labs/solana-program-library/tree/master/governance).
|
|
|
|
|
|
|
|
With the addin enabled, the governance realm authority can:
|
|
|
|
|
|
|
|
- Control which token mints can be used to vote, and at what scaling factor.
|
|
|
|
|
|
|
|
That means that tokens from mints other than the governing mint can be used
|
|
|
|
to vote and that their relative weight can be set.
|
|
|
|
|
|
|
|
- Claw back locked tokens from user deposits where the user has enabled it.
|
|
|
|
|
|
|
|
This is intended for use with token grants. Users would not enable clawback
|
|
|
|
for normal deposits.
|
|
|
|
|
|
|
|
Users can:
|
|
|
|
|
|
|
|
- Deposit and withdraw tokens of the chosen mints to gain voting weight.
|
|
|
|
|
|
|
|
When an addin is enabled, the default deposit/withdraw flow of the governing
|
|
|
|
token mints is disabled in spl-governance. The addin adds back the ability
|
|
|
|
to deposit and withdraw without lockup.
|
|
|
|
|
|
|
|
- Lock up tokens with different vesting schedules.
|
|
|
|
|
|
|
|
The tokens will only be withdrawable once vested or the lock up has expired.
|
|
|
|
Locked up tokens may have extra voting weight.
|
|
|
|
|
|
|
|
- Use their voting weight to vote on spl-governance proposals.
|
|
|
|
|
2021-12-16 04:28:37 -08:00
|
|
|
# Development
|
|
|
|
|
|
|
|
* Built and developed using - rust stable(`rustc 1.57.0 (f1edd0429 2021-11-29)`)
|
|
|
|
* Run rust based tests - `cargo test-bpf`
|
|
|
|
|
|
|
|
# Deployment
|
|
|
|
|
|
|
|
Users will likely want to compile their own voter-stake-registry and deploy it to an address they control.
|
|
|
|
|
|
|
|
Before compiling, look at:
|
|
|
|
- `Registrar::voting_mints`: The length of this array defines the number of configurable voting mints. Adjust as needed.
|
2021-12-01 23:06:56 -08:00
|
|
|
|
|
|
|
# Usage Scenarios
|
|
|
|
|
|
|
|
## Setup
|
|
|
|
|
|
|
|
To start using the addin, make a governance proposal with the spl-governance
|
|
|
|
realm authority to:
|
|
|
|
1. Deploy an instance of the voter-stake-registry.
|
|
|
|
2. Create a registrar for the realm with the `CreateRegistrar` instruction.
|
2021-12-03 11:36:42 -08:00
|
|
|
3. Add voting token mints to the registrar by calling the `ConfigureVotingMint`
|
2021-12-01 23:06:56 -08:00
|
|
|
instruction as often as desired.
|
|
|
|
4. Call the `SetRealmConfig` instruction on spl-governance to set the
|
|
|
|
voter-weight-addin program id and thereby enable the addin.
|
|
|
|
|
|
|
|
## Deposit and Vote Without Lockup
|
|
|
|
|
|
|
|
1. Call `CreateVoter` on the addin (first time only). Use the same
|
|
|
|
voter_authority that was used for registering with spl-governance.
|
2021-12-03 01:02:03 -08:00
|
|
|
2. Call `CreateDepositEntry` for the voter with `LockupKind::None`
|
2021-12-01 23:06:56 -08:00
|
|
|
and the token mint for that tokens are to be deposited. (first time only)
|
|
|
|
|
|
|
|
This creates a new deposit entry that can be used for depositing and
|
2021-12-03 01:02:03 -08:00
|
|
|
withdrawing funds without lockup.
|
|
|
|
3. Call `Deposit` for the voter and same deposit entry id to deposit funds.
|
2021-12-02 12:14:37 -08:00
|
|
|
4. To vote, call `UpdateVoterWeightRecord` on the addin and then call `CastVote`
|
|
|
|
on spl-governance in the same transaction, passing the voter weight record
|
|
|
|
to both.
|
2021-12-01 23:06:56 -08:00
|
|
|
5. Withdraw funds with `Withdraw` once proposals have resolved.
|
|
|
|
|
|
|
|
## Give Grants of Locked Tokens
|
|
|
|
|
2021-12-05 13:47:24 -08:00
|
|
|
1. Ask the recepient for their desired address.
|
|
|
|
2. Make a proposal to call `Grant` for depositing tokens into a new locked
|
|
|
|
deposit entry for their address. Use a governance that either is the realm
|
|
|
|
authority or the token mint's grant authority.
|
2021-12-01 23:06:56 -08:00
|
|
|
3. If necessary, later make a proposal to call `Clawback` on their deposit to
|
|
|
|
retrieve all remaining locked tokens.
|
|
|
|
|
2021-12-10 03:46:45 -08:00
|
|
|
## Manage Constant Maturity Deposits
|
|
|
|
|
|
|
|
Constant maturity deposits are useful when there's a vote weight bonus for
|
|
|
|
locking up tokens: With cliff or daily/monthly vested deposits the remaining
|
|
|
|
lockup period decreases as the time of maturity approaches and thus the vote
|
|
|
|
weight decreases over time as well.
|
|
|
|
|
|
|
|
Constant maturity lockup keeps tokens at a fixed maturity. That guarantees a
|
|
|
|
fixed vote weight, but also means they need to be manually transitioned to a
|
|
|
|
different lockup type before they can eventually be withdrawn.
|
|
|
|
|
|
|
|
Setting up a constant maturity lockup is easy:
|
|
|
|
|
|
|
|
1. Create a deposit entry of `Constant` lockup type with the chosen number of
|
|
|
|
days.
|
|
|
|
2. `Deposit` tokens into it.
|
|
|
|
3. Use it to vote.
|
|
|
|
|
|
|
|
If you want access to the tokens again, you need to start the unlocking process
|
|
|
|
by either
|
|
|
|
- changing the whole deposit entry to `Cliff` with `ResetLockup`, or
|
|
|
|
- creating a new `Cliff` deposit entry and transfering some locked tokens from
|
|
|
|
your `Constant` deposit entry over with `InternalTransfer`.
|
|
|
|
|
|
|
|
In both cases you'll need to wait for the cliff to be reached before being able
|
|
|
|
to access the tokens again.
|
|
|
|
|
|
|
|
|
2021-12-03 12:51:46 -08:00
|
|
|
# Instruction Overview
|
|
|
|
|
|
|
|
## Setup
|
|
|
|
|
|
|
|
- [`CreateRegistrar`](programs/voter-stake-registry/src/instructions/create_registrar.rs)
|
|
|
|
|
|
|
|
Creates a Registrar account for a governance realm.
|
|
|
|
|
|
|
|
- [`ConfigureVotingMint`](programs/voter-stake-registry/src/instructions/configure_voting_mint.rs)
|
|
|
|
|
|
|
|
Enables voting with tokens from a mint and sets the exchange rate for vote weight.
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
- [`CreateVoter`](programs/voter-stake-registry/src/instructions/create_voter.rs)
|
|
|
|
|
|
|
|
Create a new voter account for a user.
|
|
|
|
|
|
|
|
- [`CreateDepositEntry`](programs/voter-stake-registry/src/instructions/create_deposit_entry.rs)
|
|
|
|
|
|
|
|
Create a deposit entry on a voter. A deposit entry is where tokens from a voting mint
|
|
|
|
are deposited, and which may optionally have a lockup period and vesting schedule.
|
|
|
|
|
|
|
|
Each voter can have multiple deposit entries.
|
|
|
|
|
|
|
|
- [`Deposit`](programs/voter-stake-registry/src/instructions/deposit.rs)
|
|
|
|
|
|
|
|
Add tokens to a deposit entry.
|
|
|
|
|
|
|
|
- [`Withdraw`](programs/voter-stake-registry/src/instructions/withdraw.rs)
|
|
|
|
|
|
|
|
Remove tokens from a deposit entry, either unlocked or vested.
|
|
|
|
|
|
|
|
- [`ResetLockup`](programs/voter-stake-registry/src/instructions/reset_lockup.rs)
|
|
|
|
|
2021-12-10 03:46:45 -08:00
|
|
|
Re-lock tokens where the lockup has expired, or increase the duration of the lockup or
|
|
|
|
change the lockup kind.
|
|
|
|
|
|
|
|
- [`InternalTransfer`](programs/voter-stake-registry/src/instructions/internal_transfer.rs)
|
|
|
|
|
|
|
|
Transfer locked tokens from one deposit entry to another. Useful for splitting off a
|
|
|
|
chunk of a "constant" lockup deposit entry that you want to start the unlock process on.
|
2021-12-03 12:51:46 -08:00
|
|
|
|
|
|
|
- [`UpdateVoterWeightRecord`](programs/voter-stake-registry/src/instructions/update_voter_weight_record.rs)
|
|
|
|
|
|
|
|
Write the current voter weight to the account that spl-governance can read to
|
|
|
|
prepare for voting.
|
|
|
|
|
|
|
|
- [`CloseDepositEntry`](programs/voter-stake-registry/src/instructions/close_deposit_entry.rs)
|
|
|
|
|
|
|
|
Close an empty deposit entry, so it can be reused for a different mint or lockup type.
|
|
|
|
|
2021-12-03 12:56:53 -08:00
|
|
|
- [`CloseVoter`](programs/voter-stake-registry/src/instructions/close_voter.rs)
|
2021-12-03 12:51:46 -08:00
|
|
|
|
|
|
|
Close an empty voter, reclaiming rent.
|
|
|
|
|
|
|
|
## Special
|
|
|
|
|
2021-12-05 11:46:21 -08:00
|
|
|
- [`Grant`](programs/voter-stake-registry/src/instructions/grant.rs)
|
|
|
|
|
|
|
|
As the realm authority or mint's grant authority: create a voter (if needed), create a
|
|
|
|
new deposit and fund it. This instruction is intended for use with DAO proposals.
|
|
|
|
|
2021-12-03 12:56:53 -08:00
|
|
|
- [`Clawback`](programs/voter-stake-registry/src/instructions/clawback.rs)
|
2021-12-03 12:51:46 -08:00
|
|
|
|
|
|
|
As the clawback authority, claim locked tokens from a voter's deposit entry that
|
|
|
|
has opted-in to clawback.
|
|
|
|
|
|
|
|
- [`UpdateMaxVoteWeight`](programs/voter-stake-registry/src/instructions/update_max_vote_weight.rs)
|
|
|
|
|
|
|
|
Unfinished instruction for telling spl-governance about the total maximum vote weight.
|
|
|
|
|
|
|
|
- [`SetTimeOffset`](programs/voter-stake-registry/src/instructions/set_time_offset.rs)
|
|
|
|
|
|
|
|
Debug instruction for advancing time in tests. Not usable.
|
|
|
|
|
2021-12-01 23:06:56 -08:00
|
|
|
|
|
|
|
# License
|
2021-10-20 13:07:10 -07:00
|
|
|
|
|
|
|
This code is currently not free to use while in development.
|
2021-11-28 21:51:06 -08:00
|
|
|
|
2021-12-01 23:06:56 -08:00
|
|
|
|
2021-11-28 21:51:06 -08:00
|
|
|
# References:
|
2021-12-01 23:06:56 -08:00
|
|
|
* [spl-governance](https://github.com/solana-labs/solana-program-library/tree/master/governance)
|