Introduction
dVOI is a decentralized application on the Voi Testnet.
It enables users of the Voi testnet to get exposure to consensus participation block rewards without running a node.
The dVOI token will appreciate against VOI via consensus participation rewards.
Users can stake their VOI on the dVOI smart contract to mint dVOI tokens.
dVOI can be redeemed back to VOI at any time, including on Mainnet.
Read more about how it works or navigate to a specific section using the menu.
Testnet token ID: 6543210
Testnet App (contract) ID: 1337
Escrow address: DELEGATEDW322SS7PBDKGZ6WCMU5NE2MC33KO4JX252SNUQNC7U5J5ZSOQ
How it Works
The dVOI contract escrow address participates in consensus and receives consensus rewards. Part of those rewards are proportional to the VOI staked. dVOI allows users who are unable to run a node to participate in the consensus rewards of the Voi Testnet network.
To mint dVOI, users can delegate their VOI to the contract will be allocated the equivalent dVOI according to the dVOI:VOI rate at the time of minting.
The allocated dVOI remains locked in the contract for the duration of the dVOI vesting period - 1 week. This mechanism protects the protocol from users dipping in to dVOI just before the rewards are distributed, and then burn back to VOI immediately, thus diluting honest users' rewards without participating meaningfully in the online stake that generates those rewards.
After receiving their dVOI tokens, users can claim their rewards at any time by burning their dVOI for VOI. Since the vesting period overlaps the consensus participation rewards period, users should always be able to exchange their dVOI for more VOI than they minted it with.
The rate of dVOI to VOI remains constant through minting and burning - the only thing that should change the exchange rate offered by the dVOI contract is disbursement of rewards. This ensures that dVOI holder rewards are not diluted by other users minting or burning dVOI.
The rate of dVOI to VOI will start at 1:1 before any consensus rewards are distributed to the dVOI escrow account, and then dVOI will appreciate with each rewards disbursement.
The mechanism of minting is the only way dVOI enters circulation. No dVOI is allocated to "the team", or any other such back-handed nonsense.
Minting and burning dVOI does not incur any fees. The protocol takes a percentage fee from the distributed rewards.
Minting dVOI
Users can mint dVOI by depositing VOI to the protocol.
The deposited VOI will be used to participate in the Voi Testnet consensus protocol, and receive rewards.
The rewards that the dVOI protocol receives (block rewards) are proportional to block production, which is in turn proportional to the protocol balance over the total online stake in consensus.
The dVOI token and protocol allows users to get exposure to these rewards, as dVOI will appreciate in value against VOI with each rewards distribution.
The maximum amount of VOI allowed in the contract is 65,432,100 VOI. After this balance is reached, minting new dVOI will be disabled.
After minting, dVOI goes through a vesting period of one week, and then is automatically airdropped to the user who minted it. It can then be redeemed for more VOI than was originally deposited during minting.
Vesting Period
Minting dVOI currently has a vesting period of 1 week, during which the dVOI is allocated to the user but not withdrawable. The exchange rate is fixed at the time of minting, but the dVOI is locked in the contract until the week elapses.
Why?
This is a security mechanism.
On the Voi testnet, consensus rewards distributions currently take place weekly at a fixed time (Mondays.)
As such, a well designed delegation token needs a way to ensure that users claiming rewards have contributed meaningfully to the generation of said rewards.
Without a dVOI vesting period, users could mint dVOI on the day of rewards distribution, wait for rewards to be distributed, and then redeem back to VOI. This would be problematic, as they would not contribute to the online stake meaningfully over the week (and thus protocol consensus rewards), but only for a few hours.
Claiming vested dVOI
After the vesting period has elapsed, users will automatically receive their dVOI tokens.
A backend service will call the contract on the user's behalf and trigger an "airdrop" of the dVOI to their wallet - assuming they remain opted in to the dVOI asset (part of the minting process.)
In case this fails, user-initiated claim transactions can be issued through the mint page of the protocol.
Note: the vested dVOI will only be sent directly to the user who minted it, regardless of who issues the transaction to the contract - user or a backend service.
Users who wish to back out of their vesting dVOI will be able to cancel vesting, which will forfeit any accumulated rewards.
Cancel Vesting dVOI
Minted dVOI goes through a 1 week period before it is fully vested, after which it can be claimed from the contract and traded freely.
Users who currently have dVOI in a vesting state will be able to "cancel vesting". This will refund the VOI they paid during mint.
Cancelling forfeits any rewards that may have accumulated during the vesting period.
Most users will opt to wait, claim their dVOI (or have it sent to them automatically) and then redeem it in order to get rewarded for participating in consensus indirectly.
Redeeming
Redeeming is the process of returning dVOI tokens to the contract and receiving VOI in return.
Redeeming, like minting, does not influence the exchange rate of dVOI to VOI - only consensus rewards disbursements and vesting cancellations can do that.
As dVOI has a 1 week vesting period and the consensus rewards are distributed weekly on the Voi testnet, users should always be able to exchange their vested dVOI for more VOI than they originally put in to the system.
Users can only redeem tokens they hold in their wallet. Unclaimed vested dVOI must be claimed first, and then redeemed. This will usually happen automatically.
dVOI:VOI Rate
The dVOI:VOI rate starts at 1:1, with:
- all dVOI in the contract
- dVOI circulation: 0
- no VOI balance to "back" the circulating dVOI
- withdrawable balance: 0
Users who mint dVOI before any rewards are distributed will receive 1 dVOI for each VOI they deposit.
As rewards are distributed, the VOI corresponding to each circulating dVOI will increase, so the dVOI price in VOI will also increase.
Minting and redeeming rates are calculated with a formula that maintains the current dVOI/VOI rate. This aims to protect earlier users' accumulated rewards from being diluted by later users.
Aside from rewards distributions, the process of cancelling vesting may also affect the dVOI:VOI rate (in dVOI holders' favor). This would be apparent if unvested dVOI is cancelled after rewards have been distributed, or more subtly if the unvested dVOI contributed to increased block production during its tenure in the escrow account but was cancelled (refunded) before the rewards distribution.
Rate formula
The formula used to calculate the rate of dVOI to VOI is: m \[\frac{Circulating\ dVOI}{Withdrawable\ VOI}\]
Where:
- "Circulating dVOI" is the total amount of minted dVOI (both vested and unvested.)
- "Withdrawable VOI" is the VOI held in the contract that is redeemable to users via redeeming. It comprises of user VOI deposits, and the rewards distributed to the contract (minus the fees that the protocol takes from each rewards distribution.)
Mint rate formula
The formula used to mint new dVOI without affecting the dVOI:VOI rate is:
\[Minted\ dVOI=\frac{(Withdrawable\ VOI + Deposit) * Circulating\ dVOI}{Withdrawable\ VOI} - Circulating\ dVOI\]
Where:
- Minted dVOI: The amount of dVOI allocated to the user for their deposit
- Withdrawable VOI: The amount of withdrawable VOI before the user deposit
- Deposit: The amount of VOI the user is sending to mint some dVOI
- Circulating dVOI: The previous circulating dVOI amount
Redeem rate formula
The VOI returned when redeeming dVOI is calculated with this formula:
\[Return\ VOI=Withdrawable\ VOI-\frac{(Circulating\ dVOI - Redeemed) * Withdrawable\ VOI}{Circulating\ dVOI}\]
Where:
- Return VOI: The amount of VOI the user receives for their redeem deposit
- Withdrawable VOI: The amount of withdrawable VOI before the dVOI redeem
- Redeemed: The amount of dVOI the user is redeeming/exchanging for VOI
- Circulating dVOI: The previous circulating dVOI amount
Fee Structure
Mint & Redeem fees
Minting, redeeming and cancelling vesting do not incur any platform fees. The only fees you will be charged during these operations are network transaction fees.
The mint and redeem rates will be at the dVOI/VOI rate at the time of transaction - see the Rate section for an explanation.
Cancelling will refund the exact amount of VOI deposited to mint dVOI (regardless of the current dVOI:VOI exchange rate.)
Reward fees
The platform takes fees on each rewards distribution. The percentage is configurable throughout the lifetime of the contract, and can be seen under the global storage key fee_rate. This value is per-mille (%%) so you can divide by 10 to get the percent fee. The initial value 130 corresponds to 13.0%.
There are mechanisms in place to protects dVOI users from the operator changing fees abruptly, see Immutability - Fee Rate.
As an example of the allocation of a rewards payment:
- Rewards deposited: 1,000 VOI
- Fee Rate: 13.0%
- Fee purse increase: 130 VOI
- Withdrawable balance increase: 870 VOI
- This balance is the denominator in the dOVI/VOI exchange rate.
The rate change from these parameters:
- Circulating dVOI: 20,000 dVOI
- Withdrawable Balance: 20,000 VOI
- Rate: 1.0
Would result in:
- Circulating dVOI: 20,000 dVOI
- Withdrawable Balance: 20,870 VOI
- Rate: 1.0435
- withdrawable / circulating = 20870 / 20000
Execution of rewards distribution & rate calculation
The contract keeps track of the last known balance of its escrow address. It will update the withdrawable and fee balances when it is called to mint, redeem or update_balances.
Minting immediately after a rewards distribution is supported. In case the contract hasn't updated the tracked balances yet, it will do so automatically before the mint/redeem operation.
Token and Contract Info
dVOI Testnet token ID: 6543210
dVOI Testnet App (contract) ID: 1337
Escrow address: DELEGATEDW322SS7PBDKGZ6WCMU5NE2MC33KO4JX252SNUQNC7U5J5ZSOQ
Immutability
Upon initial launch and during a brief testing period, the contract will be mutable (update/delete) by the admin (D13). This functionality will be gated by the value of a contract global storage field - updatable_by. The contract will be updatable for as long as this value is set.
After the updatable_by field is cleared, the contract's code will be permanently immutable. Changes to certain configuration values of the contract will still be possible by the fee_admin address and in a controlled manner.
Configuration changes to the contract will be time-delayed. The fee admin will be able to change the fee rate value, but there will be a time delay of at least 1 week before this change will take effect. Certain values may also have restrictions on the change delta, e.g. the fee rate may only be changed +/- 5% at a time. As such, the fee admin would not be able to immediately change the fee rate to 100%, which would compromise dVOI holders' rewards.
Fee Rate
The fee rate value fee_rate will be mutable with by the fee_admin address with a 1 week delay.
The updated fee rate value must be within 50 points of the previous one (up to +/- 5% rate change at a time)
Mint Lock Duration
The minting process' dVOI lock duration value mint_time_lock will be mutable with by the fee_admin address with a 1 week delay.
The update delta does not have any restrictions.
Changing scheduled updates
If an update is issued while a previous update is scheduled, the timer will reset to the initial value of 1 week.
Updates can also be staggered, e.g. the fee rate and the mint time lock values can be part of the same update. The last update value will reset the timer to 1 week, as before.
The update will not apply automatically. When its timestamp elapses, it will either be applied by the fee admin by calling the contract, or they will be able to dismiss the change.
Scheduled updates will be stored as in the next_params_update global storage value.
The structure of this field is:
0: [4 bytes] timestamp_applicable uint32
4: [2 bytes] fee_rate uint16
6: [4 bytes] mint_time_lock uint32
Immediately updatable parameters
Fee admin
The fee admin address fee_admin will be mutable by the fee_admin with immediate effect.
Contract Storage
Global Storage
The global storage of the dVOI contract stores the following values:
| field | type | description |
|---|---|---|
| updatable_by | Byte (address) | Administrator address field. Power to update the contract code. When set to the zero address: the code is immutable. While this is set: the admin can rug. |
| fee_admin | Byte (address) | Operator address field. Has the power to 1) withdraw collected fees 2) update fee_rate and mint_time_lock parameters (with a 1 week time lock and 3) change the fee_admin |
| next_params_update | Byte | Scheduled time-locked updates of fee_rate and/or mint_time_lock parameters. Structure documented here. |
| fee_rate | Number | Fee rate in permille. E.g. 185 means fees of 18.5% on all distributed rewards |
| mint_time_lock | Number | Mint vesting period in seconds |
| init_balance | Number | Initial seed balance of contract escrow. 1 VOI. Used to calculate balances and rewards. |
| circulating | Number | Circulating dVOI (including vesting dVOI). Used in rate calculations. |
| withdrawable_balance | Number | VOI balance available to withdraw by redeeming dVOI. Used in rate calculations. |
| fees_balance | Number | Accumulated protocol fees. Withdrawable by "fee admin". |
| last_known_balance | Number | The last escrow balance seen by the contract. Used to calculate when rewards have been distributed before a mint or a redeem. |
Box Storage
Boxes are used to store users' vesting dVOI.
The box name is the user's address. The value is a concatenation of:
- [uint32] vesting timestamp
- [uint64] dVOI amount
- [uint64] amount of VOI paid. Used for cancelling vesting & refunding.
Contract ABI
Note: "Redeem" is called "burn" here.
{
"name": "dVOI Contract",
"methods": [
{
"name": "register_online",
"args": [
{
"type": "address",
"name": "address"
},
{
"type": "byte[]",
"name": "selection_key"
},
{
"type": "byte[]",
"name": "voting_key"
},
{
"type": "byte[]",
"name": "sp_key"
},
{
"type": "uint64",
"name": "first_round"
},
{
"type": "uint64",
"name": "last_round"
},
{
"type": "uint64",
"name": "key_dilution"
}
],
"returns": {
"type": "void"
},
"desc": "Fee admin method to send keyreg online for an escrow account"
},
{
"name": "register_offline",
"args": [
{
"type": "address",
"name": "address"
}
],
"returns": {
"type": "void"
},
"desc": "Fee admin method to send keyreg offline for an escrow account"
},
{
"name": "queue_update_fee_rate",
"args": [
{
"type": "uint16",
"name": "new_rate"
}
],
"returns": {
"type": "void"
},
"desc": "Fee admin method. Scheudles an update of the fee rate. Changes enforced to +/- 5% delta max"
},
{
"name": "queue_update_mint_lock",
"args": [
{
"type": "uint32",
"name": "new_lock"
}
],
"returns": {
"type": "void"
},
"desc": "Fee admin method. Scheudles an update of the mint lock period"
},
{
"name": "apply_update",
"args": [],
"returns": {
"type": "void"
},
"desc": "Public. Apply a time-delayed updated after the timestamp has elapsed."
},
{
"name": "discard_update",
"args": [],
"returns": {
"type": "void"
},
"desc": "Cancel a scheudled params update"
},
{
"name": "update_fee_admin",
"args": [
{
"type": "address",
"name": "new_admin"
}
],
"returns": {
"type": "void"
},
"desc": "Change the fee admin. Admin or fee admins only"
},
{
"name": "update_arbitrary_bytes",
"args": [
{
"type": "byte[]",
"name": "key"
},
{
"type": "byte[]",
"name": "value"
}
],
"returns": {
"type": "void"
},
"desc": "While updatable only. Update byte storage"
},
{
"name": "update_arbitrary_uint64",
"args": [
{
"type": "byte[]",
"name": "key"
},
{
"type": "uint64",
"name": "value"
}
],
"returns": {
"type": "void"
},
"desc": "While updatable only. Update uint storage"
},
{
"name": "update_updatable_by",
"args": [
{
"type": "byte[]",
"name": "new_updater"
}
],
"returns": {
"type": "void"
},
"desc": "While updatable only. Change or remove admin (updatable_by)"
},
{
"name": "init_storage",
"args": [],
"returns": {
"type": "void"
},
"desc": "Admin method to init storage. this will be needed as I am reusing an existing app"
},
{
"name": "mint_dvoi",
"args": [],
"returns": {
"type": "void"
},
"desc": "Public method. Mint dvoi (with time lock)\nprevious transaction in group must be payment in VOI recalculates fees/rate if the balance had changed before the payment rate must be kept stable during mint/burn dvoi will be allocated to the user in a box for the duration LOCK_PERIOD (1 week in prod)"
},
{
"name": "burn_dvoi",
"args": [],
"returns": {
"type": "void"
},
"desc": "Public method. Swaps dVOI for VOI at the current rate. Previous transaction in group must be payment in dVOI,"
},
{
"name": "nullun",
"args": [],
"returns": {
"type": "void"
},
"desc": "Public empty method for opcode budget increase"
},
{
"name": "withdraw_fees",
"args": [
{
"type": "uint64",
"name": "amount"
}
],
"returns": {
"type": "void"
},
"desc": "fee admin method to withdraw accumulated fees"
},
{
"name": "claim_dvoi",
"args": [],
"returns": {
"type": "void"
},
"desc": "Claim dVOI after the lock period has elapsed.\nSent to the first foreign account ref, so it can be called by anyone. Sends all vested dVOI. Unvested dVOI rewritten to box if needed"
},
{
"name": "undo_mint_dvoi",
"args": [
{
"type": "uint64",
"name": "ts"
}
],
"returns": {
"type": "void"
},
"desc": "Public. Undo dvoi minting & receive back the voi paid. Used when dVOi is not yet vested.\nAccepts timestamp of voi mint. This method can influence the dVOI/VOI rate favorably to dVOI holders (if rewards have dropped since mint)"
},
{
"name": "update_balances",
"args": [],
"returns": {
"type": "void"
},
"desc": "Public method to recalculate balances after rewards are received"
},
{
"name": "update_balances_get_rate",
"args": [],
"returns": {
"type": "uint64"
},
"desc": "Public method to update balance and return rate. For contract-to-contract calls."
}
],
"networks": {}
}
Bug Bounty
The dVOI protocol will offer a bug bounty pending approval of a testnet council proposal for funding.
Failing that, there will be a self-funded bug bounty for critical vulnerabilities equalling 90% of the protocol fees generated on testnet between launch and snapshot.
The bug bounty program will allocate funds for responsible disclosures of protocol vulnerabilities.
Links
Protocol frontend: d.voi.green
Docs: docs.voi.green ⬅ You are here
For contract and token details see Token and Contract Info
For contact details see Contact
Contact
Email: d@voi.green
Twitter: @D13_co