From 9714c6300a7444ea080ff631c772dc7a863294b1 Mon Sep 17 00:00:00 2001 From: Jiajia-Cui Date: Fri, 2 Aug 2024 14:08:12 +0100 Subject: [PATCH 1/5] feat: add ACs for fee mechanic change 0029 --- protocol/0029-FEES-fees.md | 22 +++++++++++++++++++++- protocol/features.json | 20 +++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/protocol/0029-FEES-fees.md b/protocol/0029-FEES-fees.md index 31f40d451..1e19a2110 100644 --- a/protocol/0029-FEES-fees.md +++ b/protocol/0029-FEES-fees.md @@ -184,9 +184,29 @@ For example, Ether is 18 decimals (wei). The smallest unit, non divisible is 1 w - A market is set with [Position Decimal Places" (PDP)](0052-FPOS-fractional_orders_positions.md) set to 2. A market order of size 1.23 is placed which is filled at VWAP of 100. We have fee_factor[infrastructure] = 0.001, fee_factor[maker] = 0.002, fee_factor[liquidity] = 0.05. The total fee charged to the party that placed this order is `1.23 x 100 x (0.001 + 0.002 + 0.05) = 6.519` and is correctly transferred to the appropriate accounts / pools. (0029-FEES-013). For product spot: (0029-FEES-021) - A market is set with [Position Decimal Places" (PDP)](0052-FPOS-fractional_orders_positions.md) set to -2. A market order of size 12300 is placed which is filled at VWAP of 0.01. We have fee_factor[infrastructure] = 0.001, fee_factor[maker] = 0.002, fee_factor[liquidity] = 0.05. The total fee charged to the party that placed this order is `12300 x 0.01 x (0.001 + 0.002 + 0.05) = 6.519` and is correctly transferred to the appropriate accounts / pools. (0029-FEES-014). For product spot: (0029-FEES-022) +- During opening auction, there should be no fees collected.(0029-FEES-036) +- Duing normal auction (including market protection and opening auctions), each side in a matched trade should contribute `0.5*(infrastructure_fee + liquidity_fee + treasury_fee + buyback_fee)`(0029-FEES-037) +- In a matched trade, if the price taker has enough asset to cover the total fee in their general account, then the total fee should be taken from their general account. The total fee should be `infrastructure_fee + maker_fee + liquidity_fee + treasury_fee + buyback_fee`.(0029-FEES-038) +- In a matched trade, if the price taker has insufficient asset to cover the total fee in their general account (but has enough in general + margin account), then the remainder will be taken from their margin account. (0029-FEES-039) +- In continous trading mode, if the price taker has insufficient asset to cover the total fee in their general + margin account, then the trade should be discarded, the orders on the book that would have been hit should remian in place with previous remaining size intact and the incoming order should be rejected (not enough fees error).(0029-FEES-040) +- In auction mode, if the price taker has insufficient asset to cover the total fee in their general + margin account, then the shortfall should be ignored, the orders shoud remian (instead of being rejected)(0029-FEES-041) + +- When there is `high_volume_market_maker_rebate`, `high_volume_maker_fee` sould be taken from the `treasury/buyback_fee` components with value `high_volume_maker_fee = high_volume_factor * trade_value_for_fee_purposes`(0029-FEES-042) +- When there is `high_volume_market_maker_rebate`, treasury fee will be updated to: `treasury_fee = treasury_fee * (1 - high_volume_maker_fee / (treasury_fee + buyback_fee))`(0029-FEES-043) +- When there is `high_volume_market_maker_rebate`, buyback fee will be updated to: `buyback_fee = buyback_fee * (1 - high_volume_maker_fee / (treasury_fee + buyback_fee))`(0029-FEES-044) + +- Once total fee is collected, `infrastructure_fee = infrastructure_fee + maker_fee + liquidity_fee + buyback_fee + treasury_fee` is transferred to infrastructure fee pool for that asset at the end of fee distribution time. (0029-FEES-045) +- Once total fee is collected, `maker_fee = fee_factor[maker] * trade_value_for_fee_purposes` is transferred to maker at the end of fee distribution time. (0029-FEES-046) +- Once total fee is collected, the `high_volume_maker_fee` is transferred to maker at the end of fee distribution time. (0029-FEES-047) +- Once total fee is collected, `liquidity_fee = fee_factor[liquidity] * trade_value_for_fee_purposes` is distributed to liquidity providers as described in [this spec](./0042-LIQF-setting_fees_and_rewarding_lps.md).(0029-FEES-048) +- Once total fee is collected, `treasury_fee = fee_factor[treasury] * trade_value_for_fee_purposes` (with `high_volume_maker_fee` deducted) is transferred to the treasury fee pool for that asset, where it will remain until community governance votes for transfers.(0029-FEES-049) +- Once total fee is collected, `buyback_fee = fee_factor[buyback] * trade_value_for_fee_purposes` (with `high_volume_maker_fee` deducted) is transferred to the buyback fee pool for that asset, where it will remain until community governance votes for transfers or a regular purchase program is set up.(0029-FEES-050) +- If network parameter `market.fee.factors.treasuryFee` is not set during market creation, then it should use the default value of `0`.(0029-FEES-051) +- If network parameter `market.fee.factors.buybackFee` is not set during market creation, then it should use the default value of `0`.(0029-FEES-052) + ### Applying benefit factors -1. Referee discounts are correctly calculated and applied for each taker fee component during continuous trading (assuming no volume discounts due to party) (0029-FEES-023) +1. Referee discounts are correctly calculated and applied for each taker fee component during continuous trading (assuming no volume discounts due to party) (0029-FEES-053) - `infrastructure_fee_referral_discount` - `liquidity_fee_referral_discount` - `maker_fee_referral_discount` diff --git a/protocol/features.json b/protocol/features.json index a9f180c7c..290f4f1b0 100644 --- a/protocol/features.json +++ b/protocol/features.json @@ -21,7 +21,25 @@ "acs": [ "0084-VDPR-015", "0029-FEES-034", - "0029-FEES-035" + "0029-FEES-035", + "0029-FEES-036", + "0029-FEES-037", + "0029-FEES-038", + "0029-FEES-039", + "0029-FEES-040", + "0029-FEES-041", + "0029-FEES-042", + "0029-FEES-043", + "0029-FEES-044", + "0029-FEES-045", + "0029-FEES-046", + "0029-FEES-047", + "0029-FEES-048", + "0029-FEES-049", + "0029-FEES-050", + "0029-FEES-051", + "0029-FEES-052", + "0029-FEES-053" ] }, "vAMMs": { From ac1a6ba0edc55095a68019051cc61e1702440015 Mon Sep 17 00:00:00 2001 From: Jiajia-Cui Date: Mon, 5 Aug 2024 13:09:36 +0100 Subject: [PATCH 2/5] chore: typo --- protocol/0029-FEES-fees.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/protocol/0029-FEES-fees.md b/protocol/0029-FEES-fees.md index 1e19a2110..46e95056c 100644 --- a/protocol/0029-FEES-fees.md +++ b/protocol/0029-FEES-fees.md @@ -185,13 +185,13 @@ For example, Ether is 18 decimals (wei). The smallest unit, non divisible is 1 w - A market is set with [Position Decimal Places" (PDP)](0052-FPOS-fractional_orders_positions.md) set to -2. A market order of size 12300 is placed which is filled at VWAP of 0.01. We have fee_factor[infrastructure] = 0.001, fee_factor[maker] = 0.002, fee_factor[liquidity] = 0.05. The total fee charged to the party that placed this order is `12300 x 0.01 x (0.001 + 0.002 + 0.05) = 6.519` and is correctly transferred to the appropriate accounts / pools. (0029-FEES-014). For product spot: (0029-FEES-022) - During opening auction, there should be no fees collected.(0029-FEES-036) -- Duing normal auction (including market protection and opening auctions), each side in a matched trade should contribute `0.5*(infrastructure_fee + liquidity_fee + treasury_fee + buyback_fee)`(0029-FEES-037) +- During normal auction (including market protection and opening auctions), each side in a matched trade should contribute `0.5*(infrastructure_fee + liquidity_fee + treasury_fee + buyback_fee)`(0029-FEES-037) - In a matched trade, if the price taker has enough asset to cover the total fee in their general account, then the total fee should be taken from their general account. The total fee should be `infrastructure_fee + maker_fee + liquidity_fee + treasury_fee + buyback_fee`.(0029-FEES-038) - In a matched trade, if the price taker has insufficient asset to cover the total fee in their general account (but has enough in general + margin account), then the remainder will be taken from their margin account. (0029-FEES-039) -- In continous trading mode, if the price taker has insufficient asset to cover the total fee in their general + margin account, then the trade should be discarded, the orders on the book that would have been hit should remian in place with previous remaining size intact and the incoming order should be rejected (not enough fees error).(0029-FEES-040) -- In auction mode, if the price taker has insufficient asset to cover the total fee in their general + margin account, then the shortfall should be ignored, the orders shoud remian (instead of being rejected)(0029-FEES-041) +- In continous trading mode, if the price taker has insufficient asset to cover the total fee in their general + margin account, then the trade should be discarded, the orders on the book that would have been hit should remain in place with previous remaining size intact and the incoming order should be rejected (not enough fees error).(0029-FEES-040) +- In auction mode, if the price taker has insufficient asset to cover the total fee in their general + margin account, then the shortfall should be ignored, the orders should remain (instead of being rejected)(0029-FEES-041) -- When there is `high_volume_market_maker_rebate`, `high_volume_maker_fee` sould be taken from the `treasury/buyback_fee` components with value `high_volume_maker_fee = high_volume_factor * trade_value_for_fee_purposes`(0029-FEES-042) +- When there is `high_volume_market_maker_rebate`, `high_volume_maker_fee` should be taken from the `treasury/buyback_fee` components with value `high_volume_maker_fee = high_volume_factor * trade_value_for_fee_purposes`(0029-FEES-042) - When there is `high_volume_market_maker_rebate`, treasury fee will be updated to: `treasury_fee = treasury_fee * (1 - high_volume_maker_fee / (treasury_fee + buyback_fee))`(0029-FEES-043) - When there is `high_volume_market_maker_rebate`, buyback fee will be updated to: `buyback_fee = buyback_fee * (1 - high_volume_maker_fee / (treasury_fee + buyback_fee))`(0029-FEES-044) From 4788ed4d0d3df9e7dda91143e4c85c0d5f6dc79b Mon Sep 17 00:00:00 2001 From: Jiajia-Cui Date: Mon, 5 Aug 2024 14:58:46 +0100 Subject: [PATCH 3/5] chore: typo --- protocol/0029-FEES-fees.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/0029-FEES-fees.md b/protocol/0029-FEES-fees.md index 46e95056c..d8954ff97 100644 --- a/protocol/0029-FEES-fees.md +++ b/protocol/0029-FEES-fees.md @@ -188,7 +188,7 @@ For example, Ether is 18 decimals (wei). The smallest unit, non divisible is 1 w - During normal auction (including market protection and opening auctions), each side in a matched trade should contribute `0.5*(infrastructure_fee + liquidity_fee + treasury_fee + buyback_fee)`(0029-FEES-037) - In a matched trade, if the price taker has enough asset to cover the total fee in their general account, then the total fee should be taken from their general account. The total fee should be `infrastructure_fee + maker_fee + liquidity_fee + treasury_fee + buyback_fee`.(0029-FEES-038) - In a matched trade, if the price taker has insufficient asset to cover the total fee in their general account (but has enough in general + margin account), then the remainder will be taken from their margin account. (0029-FEES-039) -- In continous trading mode, if the price taker has insufficient asset to cover the total fee in their general + margin account, then the trade should be discarded, the orders on the book that would have been hit should remain in place with previous remaining size intact and the incoming order should be rejected (not enough fees error).(0029-FEES-040) +- In continuous trading mode, if the price taker has insufficient asset to cover the total fee in their general + margin account, then the trade should be discarded, the orders on the book that would have been hit should remain in place with previous remaining size intact and the incoming order should be rejected (not enough fees error).(0029-FEES-040) - In auction mode, if the price taker has insufficient asset to cover the total fee in their general + margin account, then the shortfall should be ignored, the orders should remain (instead of being rejected)(0029-FEES-041) - When there is `high_volume_market_maker_rebate`, `high_volume_maker_fee` should be taken from the `treasury/buyback_fee` components with value `high_volume_maker_fee = high_volume_factor * trade_value_for_fee_purposes`(0029-FEES-042) From b0cad6a57c0199f5b698b7c878682d86512ed6e9 Mon Sep 17 00:00:00 2001 From: Jiajia-Cui Date: Tue, 6 Aug 2024 13:33:04 +0100 Subject: [PATCH 4/5] feat: address comments from Witold --- protocol/0029-FEES-fees.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/protocol/0029-FEES-fees.md b/protocol/0029-FEES-fees.md index d8954ff97..155c7b526 100644 --- a/protocol/0029-FEES-fees.md +++ b/protocol/0029-FEES-fees.md @@ -149,7 +149,7 @@ During normal auctions there is no "price maker" both parties are "takers". Each Fees calculated and collected from general + margin as in continuous trading *but* if a party has insufficient capital to cover the trading fee then in auction the trade *still* *goes* *ahead* as long as the margin account should have enough left after paying the fees to cover maintenance level of margin for the orders and then converted trades. The fee is distributed so that the infrastructure_fee is paid first and only then the liquidity_fee/treasury_fee/buyback_fee. -During an opening auction of a market, no fees are collected. +During an opening auction of a market, no makers fees are collected. ### Frequent Batch Auctions @@ -184,7 +184,7 @@ For example, Ether is 18 decimals (wei). The smallest unit, non divisible is 1 w - A market is set with [Position Decimal Places" (PDP)](0052-FPOS-fractional_orders_positions.md) set to 2. A market order of size 1.23 is placed which is filled at VWAP of 100. We have fee_factor[infrastructure] = 0.001, fee_factor[maker] = 0.002, fee_factor[liquidity] = 0.05. The total fee charged to the party that placed this order is `1.23 x 100 x (0.001 + 0.002 + 0.05) = 6.519` and is correctly transferred to the appropriate accounts / pools. (0029-FEES-013). For product spot: (0029-FEES-021) - A market is set with [Position Decimal Places" (PDP)](0052-FPOS-fractional_orders_positions.md) set to -2. A market order of size 12300 is placed which is filled at VWAP of 0.01. We have fee_factor[infrastructure] = 0.001, fee_factor[maker] = 0.002, fee_factor[liquidity] = 0.05. The total fee charged to the party that placed this order is `12300 x 0.01 x (0.001 + 0.002 + 0.05) = 6.519` and is correctly transferred to the appropriate accounts / pools. (0029-FEES-014). For product spot: (0029-FEES-022) -- During opening auction, there should be no fees collected.(0029-FEES-036) +- During opening auction, there should be no maker fees collected.(0029-FEES-036) - During normal auction (including market protection and opening auctions), each side in a matched trade should contribute `0.5*(infrastructure_fee + liquidity_fee + treasury_fee + buyback_fee)`(0029-FEES-037) - In a matched trade, if the price taker has enough asset to cover the total fee in their general account, then the total fee should be taken from their general account. The total fee should be `infrastructure_fee + maker_fee + liquidity_fee + treasury_fee + buyback_fee`.(0029-FEES-038) - In a matched trade, if the price taker has insufficient asset to cover the total fee in their general account (but has enough in general + margin account), then the remainder will be taken from their margin account. (0029-FEES-039) @@ -195,15 +195,15 @@ For example, Ether is 18 decimals (wei). The smallest unit, non divisible is 1 w - When there is `high_volume_market_maker_rebate`, treasury fee will be updated to: `treasury_fee = treasury_fee * (1 - high_volume_maker_fee / (treasury_fee + buyback_fee))`(0029-FEES-043) - When there is `high_volume_market_maker_rebate`, buyback fee will be updated to: `buyback_fee = buyback_fee * (1 - high_volume_maker_fee / (treasury_fee + buyback_fee))`(0029-FEES-044) -- Once total fee is collected, `infrastructure_fee = infrastructure_fee + maker_fee + liquidity_fee + buyback_fee + treasury_fee` is transferred to infrastructure fee pool for that asset at the end of fee distribution time. (0029-FEES-045) +- Once total fee is collected, `infrastructure_fee = fee_factor[infrastucture] * trade_value_for_fee_purposes` is transferred to infrastructure fee pool for that asset at the end of fee distribution time. (0029-FEES-045) - Once total fee is collected, `maker_fee = fee_factor[maker] * trade_value_for_fee_purposes` is transferred to maker at the end of fee distribution time. (0029-FEES-046) - Once total fee is collected, the `high_volume_maker_fee` is transferred to maker at the end of fee distribution time. (0029-FEES-047) - Once total fee is collected, `liquidity_fee = fee_factor[liquidity] * trade_value_for_fee_purposes` is distributed to liquidity providers as described in [this spec](./0042-LIQF-setting_fees_and_rewarding_lps.md).(0029-FEES-048) -- Once total fee is collected, `treasury_fee = fee_factor[treasury] * trade_value_for_fee_purposes` (with `high_volume_maker_fee` deducted) is transferred to the treasury fee pool for that asset, where it will remain until community governance votes for transfers.(0029-FEES-049) -- Once total fee is collected, `buyback_fee = fee_factor[buyback] * trade_value_for_fee_purposes` (with `high_volume_maker_fee` deducted) is transferred to the buyback fee pool for that asset, where it will remain until community governance votes for transfers or a regular purchase program is set up.(0029-FEES-050) +- Once total fee is collected, `treasury_fee = fee_factor[treasury] * trade_value_for_fee_purposes` (with apropriate fraction of `high_volume_maker_fee` deducted) is transferred to the treasury fee pool for that asset, where it will remain until community governance votes for transfers.(0029-FEES-049) +- Once total fee is collected, `buyback_fee = fee_factor[buyback] * trade_value_for_fee_purposes` (with with apropriate fraction of `high_volume_maker_fee` deducted) is transferred to the buyback fee pool for that asset, where it will remain until community governance votes for transfers or a regular purchase program is set up.(0029-FEES-050) - If network parameter `market.fee.factors.treasuryFee` is not set during market creation, then it should use the default value of `0`.(0029-FEES-051) - If network parameter `market.fee.factors.buybackFee` is not set during market creation, then it should use the default value of `0`.(0029-FEES-052) - +op ### Applying benefit factors 1. Referee discounts are correctly calculated and applied for each taker fee component during continuous trading (assuming no volume discounts due to party) (0029-FEES-053) From 7fd08ee3b05373f28ae36518e1d35d5a7e82192f Mon Sep 17 00:00:00 2001 From: Jiajia-Cui Date: Tue, 6 Aug 2024 13:37:06 +0100 Subject: [PATCH 5/5] chore: typo --- protocol/0029-FEES-fees.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/protocol/0029-FEES-fees.md b/protocol/0029-FEES-fees.md index 155c7b526..6580ce2b3 100644 --- a/protocol/0029-FEES-fees.md +++ b/protocol/0029-FEES-fees.md @@ -199,11 +199,11 @@ For example, Ether is 18 decimals (wei). The smallest unit, non divisible is 1 w - Once total fee is collected, `maker_fee = fee_factor[maker] * trade_value_for_fee_purposes` is transferred to maker at the end of fee distribution time. (0029-FEES-046) - Once total fee is collected, the `high_volume_maker_fee` is transferred to maker at the end of fee distribution time. (0029-FEES-047) - Once total fee is collected, `liquidity_fee = fee_factor[liquidity] * trade_value_for_fee_purposes` is distributed to liquidity providers as described in [this spec](./0042-LIQF-setting_fees_and_rewarding_lps.md).(0029-FEES-048) -- Once total fee is collected, `treasury_fee = fee_factor[treasury] * trade_value_for_fee_purposes` (with apropriate fraction of `high_volume_maker_fee` deducted) is transferred to the treasury fee pool for that asset, where it will remain until community governance votes for transfers.(0029-FEES-049) -- Once total fee is collected, `buyback_fee = fee_factor[buyback] * trade_value_for_fee_purposes` (with with apropriate fraction of `high_volume_maker_fee` deducted) is transferred to the buyback fee pool for that asset, where it will remain until community governance votes for transfers or a regular purchase program is set up.(0029-FEES-050) +- Once total fee is collected, `treasury_fee = fee_factor[treasury] * trade_value_for_fee_purposes` (with appropriate fraction of `high_volume_maker_fee` deducted) is transferred to the treasury fee pool for that asset, where it will remain until community governance votes for transfers.(0029-FEES-049) +- Once total fee is collected, `buyback_fee = fee_factor[buyback] * trade_value_for_fee_purposes` (with with appropriate fraction of `high_volume_maker_fee` deducted) is transferred to the buyback fee pool for that asset, where it will remain until community governance votes for transfers or a regular purchase program is set up.(0029-FEES-050) - If network parameter `market.fee.factors.treasuryFee` is not set during market creation, then it should use the default value of `0`.(0029-FEES-051) - If network parameter `market.fee.factors.buybackFee` is not set during market creation, then it should use the default value of `0`.(0029-FEES-052) -op + ### Applying benefit factors 1. Referee discounts are correctly calculated and applied for each taker fee component during continuous trading (assuming no volume discounts due to party) (0029-FEES-053)