Skip to content

Commit

Permalink
Merge pull request #1111 from vegaprotocol/fees
Browse files Browse the repository at this point in the history
Fees and new rebate program
  • Loading branch information
candida-d authored Sep 30, 2024
2 parents 48d2aad + 3b44ce0 commit da83e15
Show file tree
Hide file tree
Showing 9 changed files with 379 additions and 99 deletions.
20 changes: 14 additions & 6 deletions docs/concepts/trading-framework/fees.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import NetworkParameter from '@site/src/components/NetworkParameter';

The Vega software is designed such that participants in a network who place orders on the order book, provide liquidity and run the network infrastructure receive the fees that traders pay on filled trades and transfers. The protocol does not have a mechanism to charge gas fees for interacting with the network.

Users can offset some of those fees, or earn even more, by receiving discounts or getting rewards based on trading activity. Rewards can be funded by anyone, and can be in any asset.
Users can offset some of those fees, or earn even more, by receiving discounts or getting rewards based on trading activity. Rewards can be funded by anyone, and can be in any asset.

:::note Read more
[Concept: Discounts and rewards](./discounts-rewards.md)
Expand All @@ -34,7 +34,7 @@ The aggressor *buying* the base asset for the quote asset pays more in their tra
### Fee distribution and breakdown
Fees are calculated when a trade is filled, and paid in the market's settlement currency. The fees due are taken from the collateral in the trader's general account.

The fee is divided between the maker for the trade, the infrastructure providers, and the liquidity provider(s) for each market.
If each fee type is set to have a value, the fee is divided between the maker for the trade, the infrastructure providers, the liquidity provider(s) for each market, and the network's treasury.

### Maker fee
The maker portion of the fee is paid by the aggressive party in a trade (the taker), and transferred to the non-aggressive, or passive party in the trade (the maker, as opposed to the taker). This is done as soon as the trade settles.
Expand All @@ -59,19 +59,27 @@ The fees paid are transferred to a liquidity fee account, and distributed to eac
[How the liquidity fee is set](../liquidity/rewards-penalties.md#determining-the-liquidity-fee-percentage)
:::

### Network treasury fee
The network treasury fee is collected from takers and transferred to the [network treasury](../assets/accounts.md#network-treasury-accounts).

The amount charged for this fee is set by a network parameter.

### Buyback fee
The buyback fee is collected from takers and is used to buy specific tokens on a spot market through automated purchase programs. The amount charged for this fee is set by a network parameter.

### Fee calculations
At a high level, the trading fee that someone pays is calculated using the following formulas:

* Total fee = (infrastructure fee factor + maker fee factor + liquidity fee factor) x trade value for fee purposes
* Total fee = (infrastructure fee factor + maker fee factor + liquidity fee factor + buyback fee + network treasury fee) x trade value for fee purposes
* Trade value for fee purposes = notional value of the trade = size of trade x price of trade

#### Fee calculation example
* Trade value for fee purposes: If you were to place an order for 100 at USDC50, the trade value for fee purposes is: *100 x USDC50 = USDC5000*.
* Fee factor: For this example, each of the 3 fees is *0.001*, meaning total fee factor is *0.003*.
* Trade value and fee factor: *USDC5000 x 0.003 = USDC15*
* Fee factor: For this example, each of the 5 fees is *0.001*, meaning total fee factor is *0.005*.
* Trade value and fee factor: *USDC5000 x 0.005 = USDC25*
* The fee is the same regardless of the number of transactions the order needs to be completely filled, as long as they trade at the same price.

Two of the three fee factors are set through network parameters: <NetworkParameter frontMatter={frontMatter} param="market.fee.factors.infrastructureFee" />, <NetworkParameter frontMatter={frontMatter} param="market.fee.factors.makerFee" />. The liquidity fee is set by the liquidity providers on the market.
Four of the five fee factors are set through network parameters. <NetworkParameter frontMatter={frontMatter} param="market.fee.factors.infrastructureFee" />, <NetworkParameter frontMatter={frontMatter} param="market.fee.factors.makerFee" />. The liquidity fee is set by the liquidity providers on the market.

## Transfer fees
You may need to pay a fee to transfer assets, whether from one Vega key to another, or from a Vega key to a reward pool to fund trading rewards. The fee amount is taken when the transfer is executed, on top of the total amount to be transferred. It's charged in the same asset that is being transferred.
Expand Down
11 changes: 7 additions & 4 deletions docs/tutorials/proposals/asset-transfer-proposal.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
sidebar_position: 9
title: Transfer assets
vega_network: TESTNET
hide_title: true
keywords:
- proposal
Expand Down Expand Up @@ -43,6 +42,7 @@ For **one-off transfers** use `deliverOn` to set a delivery date/time for when t
For **recurring transfers**, such as for funding rewards, you'll need to include the following information:
* `startEpoch`: The number of the epoch in which you want the first transfer to be made. It will initiate at the end of that epoch.
* `endEpoch`: The transfer will repeated indefinitely, unless you add this optional parameter to end the recurring transfer in a specified epoch.
* `factor`: Factor that the initial transfer amount is multiplied by for each epoch that it is executed. For example if the initial transfer amount is 1000 and the factor is 0.5, then the amounts transferred per epoch will be 1000, 500, 250, 125, etc.

**Amount** is the cap on how much will be transferred, as whole number with the asset decimal places implied. For example, if the asset has a decimal place of 2 and the transfer is for 100, then the amount needs to be set at 10000. The maximum you can propose to transfer is the value of the network parameter <NetworkParameter frontMatter={frontMatter} param="governance.proposal.transfer.maxAmount" />, which is a multiplier for the asset's [quantum value](../../concepts/assets/asset-framework.md#quantum). Before proposing, make sure the account you're transferring from exists and has a balance. The full amount may not be transferred if there isn't enough to transfer. For specifics on how the final amount is determined, see the [calculations in the transfers spec ↗](https://github.com/vegaprotocol/specs/blob/master/protocol/0057-TRAN-transfers.md#recurring-transfers).

Expand Down Expand Up @@ -139,7 +139,8 @@ These templates show an example of how to fund rewards with a governance transfe
"destinationType": "ACCOUNT_TYPE_REWARD_AVERAGE_POSITION",
"recurring": {
"startEpoch": 116515,
"endEpoch": 116615
"endEpoch": 116615,
"factor": "1"
"dispatchStrategy": {
"assetForMetric": "b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663",
"metric": "DISPATCH_METRIC_MAKER_FEES_PAID",
Expand Down Expand Up @@ -183,6 +184,7 @@ These templates show an example of how to fund rewards with a governance transfe
"recurring": {
"startEpoch": 1111110,
"endEpoch": 1111111,
"factor": "1"
"dispatchStrategy": {
"assetForMetric": "b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663",
"metric": "DISPATCH_METRIC_MAKER_FEES_PAID",
Expand Down Expand Up @@ -228,8 +230,9 @@ vegawallet.exe transaction send --wallet YOUR_WALLETNAME --pubkey YOUR_PUBLIC_KE
\"fractionOfBalance\": `\"0.1\", ^
\"destinationType\": \"ACCOUNT_TYPE_REWARD_AVERAGE_POSITION\", ^
\"recurring\": {^
\"startEpoch\": \"1111110\" ^
\"endEpoch\": \"1111111\" ^
\"startEpoch\": \"1111110\", ^
\"endEpoch\": \"1111111\", ^
\"factor\": \"1\" ^
\"dispatchStrategy\": { ^
\"assetForMetric\": \"b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663\", ^
\"metric\": \"DISPATCH_METRIC_MAKER_FEES_PAID\", ^
Expand Down
179 changes: 179 additions & 0 deletions docs/tutorials/proposals/maker-volume-rebate-program.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
---
sidebar_position: 11
title: Enable or replace maker rebate program
hide_title: false
vega_network: TESTNET
keywords:
- proposal
- governance
---

import NetworkParameter from '@site/src/components/NetworkParameter';
import JSONInstructions from './_json-instructions.md';
import TerminalInstructions from './_terminal-instructions.md';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Batch from './_batch-sample.md';

When a high-volume maker rebate program is enabled, market makers can receive a rebate of a portion of their paid fees. The higher their maker volume across all markets over the program's window length, the greater the rebate that makers can receive.

The program needs to be enabled by governance. Once it's enabled, both the requirements and the benefits can also be replaced with a new program.

This page describes what you need to propose enabling or replacing the program, and provides example proposal templates that you will need to edit before sharing and submitting.

## Requirements

You will need:
* A connected [Vega wallet](../../tools/vega-wallet/index.md), with your wallet name and public key to hand
* A minimum of the value set in the following network parameters. You need whichever amount is larger associated with that public key: <NetworkParameter frontMatter={frontMatter} param="governance.proposal.VolumeRebateProgram.minProposerBalance" hideValue={true}/> or <NetworkParameter frontMatter={frontMatter} param="spam.protection.proposal.min.tokens" hideValue={true}/>.
* Familiarity with [governance](../../concepts/governance/index.md)

## Anatomy of a maker rebate program proposal
The fields below all need to be defined to enable the program or replace an existing one.

If you are suggesting a replacement program, you'll need to include all the fields, even if you don't want to change their values. Just use the existing values from the current maker rebate program program.

**End of program timestamp**: Date and time after which, when the current epoch ends, the program will end and rebates will be disabled.

**Window length**: Number of epochs over which to evaluate each participant's volume of maker trades across all markets.

To end an existing program early, set your proposal up with the exact same parameters. Set the *end of program timestamp* to be the same as the proposal's *enactment* timestamp.

#### Benefit tier fields

| Benefit tier field | Description | Accepted values |
| ----------- | ----------- | ----------- |
| `benefitTiers` | List of values defining the rebate factors for the program | Holds the details of each tier of rebates, listed below. Maximum of <NetworkParameter frontMatter={frontMatter} param="volumeRebateProgram.maxBenefitTiers" hideName={true}/> tiers |
| `minimumPartyMakerVolumeFraction` | To access this tier, the required percentage of trading volume, across all markets, that a party was the maker for, in the window length. This is expresssed as a fraction. | Greater than 0 and up to 1, inclusive |
| `additionalMakerRebate` | Additional fraction of fees a party will receive as a rebate when they are on the maker side of a trade. | Greater than 0 and up to 1, inclusive |

## Submitting proposals in a batch

<Batch />

## Templates and submitting

Below you will find:
* JSON example that can be submitted with the [governance dApp ↗](https://governance.fairground.wtf/proposals/propose/raw)
* Command line examples for different operating systems

<Tabs groupId="UpdateVolumeRebateProgram">
<TabItem value="json" label="Governance dApp (JSON)">
<JSONInstructions />

```json
{
"proposalSubmission": {
"rationale": {
"title": "Maker volume rebate proposal title",
"description": "This enacts or replaces the maker volume rebate program"
},
"terms": {
"UpdateVolumeRebateProgram": {
"changes": {
"endOfProgramTimestamp": 1234567890,

"window_length": 11,
"benefitTiers": [
{
"minimumPartyMakerVolumeFraction": "10000",
"additionalMakerRebate": "0.002"
},
{
"minimumPartyMakerVolumeFraction": "10198",
"additionalMakerRebate": "0.098"
}
],
}
},
"closingTimestamp": 1111111111,
"enactmentTimestamp": 1111111155
}
}
}
```
</TabItem>

<TabItem value="cmd-linux-osx" label="Command line (Linux / OSX)">
<TerminalInstructions />

```
./vegawallet transaction send --wallet YOUR_WALLETNAME --pubkey YOUR_PUBLIC_KEY --network NETWORK_NAME
'{"proposalSubmission": {
"rationale": {
"title": "Maker volume rebate proposal title",
"description": "This enacts or replaces the volume rebate program"
},
"terms": {
"UpdateVolumeRebateProgram": {
"changes": {
"end_of_program_timestamp": 1234567890,
"window_length": 3,
"benefitTiers": [
{
"minimumPartyMakerVolumeFraction": "10020",
"additionalMakerRebate": "0.001"
},
{
"minimumPartyMakerVolumeFraction": "10198",
"additionalMakerRebate": "0.098"
}
],
}
},
"closingTimestamp": 1111111111,
"enactmentTimestamp": 1111111155
}
}
}'
```

</TabItem>
<TabItem value="cmd-windows" label="Command line (Windows)">
<TerminalInstructions />

```
vegawallet.exe transaction send --wallet YOUR_WALLETNAME --pubkey YOUR_PUBLIC_KEY --network NETWORK_NAME ^
"{^
\"proposalSubmission\": {^
\"rationale\": {^
\"title\": \"Maker volume rebate program proposal title\",^
\"description\": \"This explains why I want to enact or replace the volume rebate program\"^
},^
\"terms\": {^
: {
\"UpdateVolumeRebateProgram\":^ {
\"changes\": {^
\"end_of_program_timestamp\": \"1234567890\",:^
\"window_length\": \"3\",
\"benefitTiers\": [
{
\"minimumPartyMakerVolumeFraction\": \"10100\",^
\"additionalMakerRebate\": \"0.001\"^
},
{
\"minimumPartyMakerVolumeFraction\": \"11000\",^
\"additionalMakerRebate\": \"0.098\"^
}
],
}
},
\"closingTimestamp\": \"1111111111\",^
\"enactmentTimestamp\": \"1111111155\"
}^
}^
}'^
```
</TabItem>
</Tabs>

## Voting
To vote, participants need, at a minimum, the larger of the value of the following network parameters: <NetworkParameter frontMatter={frontMatter} param="governance.proposal.VolumeRebateProgram.minVoterBalance" formatter="governanceToken" suffix="tokens" hideName={true} /> or <NetworkParameter frontMatter={frontMatter} formatter="governanceToken" param="spam.protection.voting.min.tokens" suffix="tokens" hideName={true} /> associated to their Vega key.

A proposal will need [participation](../../concepts/governance/lifecycle.md#how-the-outcome-is-calculated) of at least the value of the network parameter <NetworkParameter frontMatter={frontMatter} param="governance.proposal.VolumeRebateProgram.requiredParticipation" /> and a majority that's the value of the network parameter <NetworkParameter frontMatter={frontMatter} param="governance.proposal.VolumeRebateProgram.requiredMajority" />.

## Enactment
If successful, the program changes will go live in the epoch following the time you specify in the `enactmentTimestamp` field.
Loading

0 comments on commit da83e15

Please sign in to comment.