SIP 58: Emit every fee reclamation outcome during trade settlement Source

AuthorJackson Chan

Simple Summary

Emit list of individual fee reclamations and rebates during trade settlement for Dapps and Synthetix Exchange.


In order to help users track fees claimed or rebated from individual transactions, emit events during settlement that match each individual exchange being settled with the amount reclaimed or rebated.

Upgrade the Exchanger settle() function to emit individual fee reclaimation / rebate amounts for each trade.

Emit an extra event on each Exchange to provide information on the source and destination currencyKey RoundID the exchange was executed at.


We want to display on Synthetix exchange the corresponding fee reclamation amounts (if any) for each individual exchange made when exchange settlement is invoked.

Currently invoking settle() will only emit one event, if any, with the total aggregated sum of any fee reclamation or rebate amounts. This makes it difficult and complex for users trying to determine the dividual settlement rates on previous trades they’ve made.

It is important that traders can see on each trade the fee reclamation and rebates for calculating trading profits and loses based on the amounts and effective price they recieved on each individual trade.

Vice versa emitting extra information when an exchange transaction occurs such as the RoundID’s for the source and destination currencies will allow Dapp’s to get effective rate for the pair by querying the ExchangeRates contract.



Add an internal function _settlementsOwing that will emit an event ExchangeEntryReclaim for each reclaim and ExchangeEntryRebate for each rebate when Exchanger.settle() is invoked.

Exchanger.settle() will use _settlementsOwing to calculate the fee reclamation amounts.


Emit an event ExchangeEntryReclaim or ExchangeEntryRebate for each exchangeEntry within _settlementsOwing when Exchanger.settle() is invoked.

event ExchangeEntryReclaim(address indexed from, bytes32 src, uint amount, bytes32 dest, uint reclaimAmount, uint srcRoundIdAtPeriodEnd, uint destRoundIdAtPeriodEnd, uint timestamp);
event ExchangeEntryRebate(address indexed from, bytes32 src, uint amount, bytes32 dest, uint rebateAmount, uint srcRoundIdAtPeriodEnd, uint destRoundIdAtPeriodEnd, uint timestamp);


Emit an event ExchangeEntryAppended for each exchangeEntry created when a user makes an exchange. Capture details such as roundIdForSrc, roundIdForDest for Dapps to calculate the effectiveValue of the exchange at anytime by querying the onchain data.

event ExchangeEntryAppended(address indexed account, bytes32 src, uint amount, bytes32 dest, uint amountReceived, uint exchangeFeeRate, uint roundIdForSrc, uint roundIdForDest, uint timestamp);


Add to ISynthetixInternal interface external functions for emitting event off Synthetix proxy.

  • ExchangeEntryReclaim
  • ExchangeEntryRebate
  • ExchangeEntryAppended


The decision to add an internal function _settlementsOwing that will emit individual fee reclaim and rebate events when Exchanger.settle() is invoked allows the public view function settlementOwing(address account, bytes32 currencyKey) to be kept for users to query the total aggregated reclaim and rebate amounts they have to settle.

_settlementsOwing will be used for settlements and emit the individual events persisting them onto the blockchain once the transaction is confirmed.

Test Cases

  • The above events are emitted off the Synthetix Proxy.
  • When Exchanger.settle() is invoked, the _settlementsOwing function is invoked and returns (uint reclaimAmount, uint rebateAmount, uint numEntries).
  • When Exchanger.settle() is invoked, it emits ExchangeEntryReclaim event for each ExchangeEntry that has a reclaim amount - (amountReceived > amountShouldHaveReceived).
  • When Exchanger.settle() is invoked, it emits ExchangeEntryRebate event for each ExchangeEntry that has a rebate amount - (amountShouldHaveReceived > amountReceived).
  • When Exchanger._exchange() is invoked, it emits ExchangeEntryAppended event for each ExchangeEntry appended to the ExchangeState with details combined in.


Configurable Values (Via SCCP)


Copyright and related rights waived via CC0.