SIP-56: Differential Fees
Ability for the protocol DAO to configure different exchange fee rates for each
Currently there is one universal exchange rate for exchanging synths which is set onchain in the
FeePool to allow an array of Synths exchange rates to be set allowing unique pricing per asset or class.
There could be multiple pricing options TBD such as;
- Charge the fee rate of the synth being exchanged into.
Charge the sum of the pair. Charge the lowest of the pair.
UPDATE: The proposed pricing method is 1.
With a universal exchange fee rate the protocol is limited in its ability to price markets fairly or apply incentive mechanisms. To deter front runners setting a high exchange rate was used to reduce profiitability affecting all Synth markets and discouraging good actors from trading.
Unique pricing per synth would allow potential outcomes such as;
a) Different price categories such as fiat, crypto, inverse, indices, commodities or stocks.
b) Used as a configurable protocol mechanism via SCCP to increase rates to deter new trades exchanging into a synth where there is an oversupply or potential debt risk to the system.
c) Configure a synth's exchange rate such as sUSD as low as possible to encourage traders to move into it or for SNX stakers to return to sUSD at no cost to be able to burn it to maintain the systems target c-ratio.
Storage of the rates should use the
uint mappings in the
FeePoolEternalStorage contract so
FeePool logic can be upgraded maintaining the exchange fee rate state.
New functions required in the upgradable
Will allow the protocol DAO to set n number of exchangeFeeRates for n number of synths in one transaction.
setExchangeFeeRateForSynths(bytes32 synthKeys, uint256 exchangeFeeRates) onlyOwner
bytes32 synthKeys: The array of currencyKeys for the synths to set
uint256 exchangeFeeRates: The array of rates
Return the exchange fee rate for a synth
exchangeFeeRateForSynth(bytes32 synth) public view returns (uint)
bytes32 synth: synth key to request the rate for
Will allow the protocol DAO to delete n number of synth rate entries freeing up the storage of removed / deprecated synths
deleteExchangeFeeRateForSynths(bytes32 [synthKeys]) onlyOwner
bytes32 [synthKeys]: The array of currencyKeys for the synths to delete
New functions required in the upgradable
Returns the exchange fee in sUSD.
Deprecate existing fee view function
FeePool.exchangeFeeIncurred(uint value) public view returns (uint)
and move to
to accept the Synth trading pair as arguments to determine the exchange fee for the trade.
getAmountsForExchange(uint sourceAmount, bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) public view returns (uint)
uint sourceAmount: Amount of the source Synth to exchange
bytes32 sourceCurrencyKey: Synth exchanging from
bytes32 destinationCurrencyKey: Synth to exchange into
uint amountReceived: The amount recieved after exchange fees
uint fee: The fees payable for the exchange
uint exchangeFeeRate: The exchange rate applied
It was considered that a
Synth should store its own rate by having a setter for
exchangeFeeRate. However the rate storage would be lost on each upgrade and need to be reset again adding overhead to the upgrade process. Also each Synths external
TokenState is already immutable and not upgradable.
- Given the pDAO needs to set multiple rates. When owner sends an array of x Synths and rates then store in the
- Given the pDAO needs to set a single rate. When owner sends an array of x Synths and rates that are already stored then the synth rates are updated.
- Given the pDAO needs to update multiple rates. When owner sends an array of 1 Synths and rates then store in the
- Given the pDAO needs to update 1 rate. When owner sends an array of 1 Synths and rates that are already stored then the synth rates are updated.
- Given a synthKey, anyone can view the exchange fee rates for the synthKey
- When owner sends a rate greater than MAX_EXCHANGE_FEE_RATE then revert
- Given I have a balance of Synth A and want to exchange into Synth B then I can view the
- Given I exchange Synth A into Synth B and then the exchange fee rate applied should be the rate of Synth B
- Given I exchange into a Synth then the exchange rate is stored for fee reclaimation, when I return x seconds later and have a settlement owed to the debt pool or rebate owing to me the exchange fee rate at the time of my exchange is used for settlment and not the current rate in case it has changed.
Copyright and related rights waived via CC0.