-
Notifications
You must be signed in to change notification settings - Fork 223
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Fee Reclamations #57
Comments
@justinjmoses What if each trade sends an oracle request to chainlink with an ID specific to that trade. |
@thebkr7 because that would introduce a delay (of unknown length) while the oracles fetched prices off-chain and before reporting back with the latest price. Like queuing, it breaks composability completely as the execution of the order would no longer happen atomically (i.e. within the same transaction). |
I propose extending this proposal to both directions: gains due to luck or soft front-running are reclaimable and losses due to bad luck are rebatable. If only the reclaimable portion were implemented, lucky trades would be penalized while traders that make unlucky trades would bear the full loss. To non-front running traders, it would average out to be an effective fee increase. Rebatable Implementation: During an exchange or transfer, the rebatable flow is similar to the reclaimable flow, except rebatable amounts are credited to a per-account rebate variable. The user would manually need to call In discussion on discord, one issue mentioned with this implementation of rebatable is that the fee pool may sometimes not have enough funds, which would be a poor user experience. Some possible solutions to this: (1) Instead of fully distributing the fee pool every week to SNX holders, always leave a minimum amount in the fee pool (e.g., 20k sUSD); (2) deduct the outstanding rebates in real-time from the fee pool, so that there will always be enough to cover calls to |
@brian0641 I think adding rebates are a reasonable compromise for this proposal, and I've come around to them (as this was discussed a few weeks ago on our Discord in the As for the fee pool size - I think with the addition of fee reclamation to the fee pool, there should be a sufficient amount to pay for rebates. This feels like quite an edge case regardless (user has negative front-run - presumably by accident - and the fee pool isn't big enough to cover the losses). If we implement and find it is impacting the user experience, we can revisit this (or if griefing does start to occur - which seems unlikely due to cost to the user). That being said, I appreciate the possible suggestions. Of them, (1) is a possible addition. (2) is too tough and doesn't work in all cases - it's possible the first exchange in a new period (where fees are currently |
Hey Justin, Also on the second friction point you raised above, regarding the failure of swap transactions due to unclaimed fees... I don't know about the complexity of the implementation where triggers payment/receipt of unclaimed fees when swapping the synth automatically... |
@ace0999 thanks 🙏
We will initially decide upon a conservative time frame, based on known oracle updates, and monitor it. We also need to integrate this with the remainder of the chainlink migration - so we will need thread the needle a little. I expect the initial rate to be somewhere in the vicinity of 5 minutes, but that is subject to change.
I'm not sure I follow you? If you mean |
Perfect, on the first point.... Thanks |
This is now being discussed in this PR: #77 - please direct comments over there. |
Update: this is now SIP-37 - link to discussions in Discord in the SIP |
Problem
Refer to "Problem" definition via Synthetixio/synthetix#298 for details on the front-running situation in Synthetix.
The Exchanging Queuing Proposal suggests solving front-running with the use of queue, to be processed at some future stage after prices have been received. The concern with this approach is that it turns a synchronous process -
Synthetix.exchange()
- into an ansynchoronous one. That is, whenSynthetix.exchange()
completes, the account will not yet have synths, and has to wait for the queue to be processed at a later block before they appear in the user's balance. As mentioned in the issue, this breaks composibility; any smart contract that tries to do aSynthetix.exchange()
immediately followed by another action that relies on the balance being there will fail.Proposal
Instead of using a queue, and instead of using the current max gwei limitation introduced in SIP-12, we allow all exchanges to be processed at whatever gas price the user wishes. Immediately thereafter, there is a small waiting period (of M minutes, say) within which exchanging or transfering any of that synth will fail for the user.
After the waiting period, if a price was received by the oracle during that window that would have led to more profit than the exchange fee, then this profit is marked as reclaimable. The next exchange of that synth after the waiting period will always send any reclaimable amount to the fee pool before processing the exchange. For transfers, in order to not break
ERC20
conventions, if there is any reclaimable on that synth, instead of reclaiming the fees during transfer we propose to always fail the transaction (not unlike when a user attempts to transfer lockedSNX
). The onus is then user to invoke a function on the synth to repay their reclaimable amount - if any.Workflow
Synthetix.exchange()
invoked from synthsrc
todest
byuser
foramount
src
?user
have anyreclaimable
onsrc
?amount
>reclaimable
?Synthetix.settleFeesReclaimed(src)
for synthsrc
then continue to exchangeamount - reclaimable
Synthetix.settleFeesReclaimed(src)
invoked with synthsrc
byuser
user
have any reclaimable onsrc
?reclaimable
to the fee pool and setreclaimable
to0
Synth.transfer()
invoked from synthsrc
byuser
foramount
src
?user
have anyreclaimable
onsrc
?Concerns
1. Legitimate users have to pay front-running fees
While this post-trade fee reclamation is designed to prevent intentional front-running, it is possible that legitimate users get caught out unintentionally front-running. That is, someone is trading unawares of market volatility, and they happen to place a trade right before an oracle update yields them additional profit. However, this proposal only penalizes them for these immediate profits made. Future oracle updates after this waiting period of M minutes have no impact.
2. Friction to exchange & transfer synths
Under this proposal, two points of friction are introduced:
Exchanging a synth soon after it was exchanged into will fail (if less than M minutes). This is a suboptimal user experience, but it's arguably better than the max gas price solution (SIP-12) which impacts all trades. Instead, this limitation only strikes exchanges out of a synth that was recently traded into.
Transferring a synth could now fail if there are any reclamable fees owing. While this introduces extra friction to the Synthetix ecosystem, it is not dissimilar to locked
SNX
that cannot be transferred. For the sake of protecting the system against front-runners making sprofit from SNX stakers, we propose that this is a worthwhile tradeoff.3. Limitations to composability
The final concern with this approach is that any atomic (i.e. within the same transaction) exchanges or transfers that proceed an exchange will fail - causing the entire transaction to fail. As more an more DeFi projects are composed together in smart contracts, we have legitimate concerns that this friction could impede future compositions which have yet to be created.
We have some ideas around how to prevent this - such as a additional exchange function that circumvents this logic but always pays higher fees. Alternatively, we can take into account on-chain volatility of the
src
synth and if below some volatility threshold (say 50bps) over some time window (say 24 hours), allow any exchange ofsrc
to bypass the reclamation fee process.We welcome any constructive input you may have around this issue.
Examples
Given the following preconditions:
Jessica has a wallet which holds 100 sUSD and this wallet has never exchanged before,
and the price of ETHUSD is 100:1, and BTCUSD is 10000:1
and the reclamation fee waiting period (M) is set to 3 minutes.
When
Then
When
Then
When
Then
When
Then
When
Then
When
Then
When
settle
for sETHThen
settle
invocation sent 2.7% of her exchange amount (0.027) to the fee pool, and transfer detected no reclaimable fees remaining.When
Then
When
Then
The text was updated successfully, but these errors were encountered: