Skip to content
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

Exchange: When settling orders, have the market provide the exchange fee in nhash. #1839

Open
4 tasks
SpicyLemon opened this issue Feb 9, 2024 · 4 comments
Open
4 tasks
Labels
Milestone

Comments

@SpicyLemon
Copy link
Contributor

Summary

Update the MsgMarketSettleRequest endpoint to collect the exchange fees from the market in the chain's fee denom instead of the denoms that the market is collecting.

Problem Definition

When a market collects fees during a MsgMarketSettleRequest, a portion of those fees go to the fee collector and then to validators. Those fees can be in any denom, though. When they are a restricted denom, there can be problems sending them to the fee collector and validators.

Proposal

  1. Add a field to MsgMarketSettleRequest that allows a market to provide NAVs that have a price with the fee denom. The assets can have a denom of anything being collected as a fee.
  2. During a MarketSettle instead of applying the bips to each order fee denom, use NAVs (either provided or from state) to convert each order fee denom to the chain's fee denom and apply the bips to that. Consume this fee the same way that it's done for commitment settlement.
  3. Create a query that takes in a MsgMarketSettleRequest and returns the required fee amount.

For Admin Use

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate contributors tagged
  • Contributor assigned/self-assigned
@iramiller
Copy link
Member

This approach [appears to] matches what was done for the capital commitments which greatly simplifies the process of handling fees since they stay in nhash and are explicitly paid during transaction submission...

@SpicyLemon
Copy link
Contributor Author

There's a small hickup with this approach when it comes to the FillBids and FillAsks endpoints. Specifically, we can no longer pull the exchange's portion of the fees from the market account because the market isn't necessarily receiving the fees in the chain's fee denom, and the market has not given the user permission to use such funds.

A fix would be to require the user (that's calling FillBids or FillAsks) to pay the exchange's portion of the fees. That means users will have to pay more to use those endpoints, but that's probably acceptable.

@iramiller
Copy link
Member

If the bid/ask order fees are from the user and that flow is clear ... then the rates used for those actions should be set appropriately ... the settlement action of crossing orders would definitely be paid by the market though so it likely means that a shift in the configuration of fees is required to make all things line up as intended with this update.

@SpicyLemon
Copy link
Contributor Author

I was hoping that this could be a quick fix in the hopes that we could get it in with v1.18.0, but even this quick fix would probably take too long. And as far as I know, no one is close to creating a market for orders yet.

Rates aren't defined differently for settlement by the market vs by a user. And we already have eight different rate-related configuration fields. Splitting it between market settle vs user settle would add four more, which I'd rather not do.

Until we get a fix, we can just say that all the fees can only be in nhash, and enforce that at the governance proposal level. There is one sticking point with that, though: The seller settlement ratio fee denom must be in the same denom as the order's price. So this limitation would mean that either all prices would need to be in nhash or else the market can't charge a seller settlement ratio fee (they could still charge a seller settlement flat fee, or either of the buyer settlement fees, though).

The root of the problem is that the market is collecting settlement fees, and the exchange should receive a portion of them. But not all settlements are initiated by the market, so adding an extra Tx fee means the market won't always be paying for it. And when an order is created, there's no way to know whether the market will settle it (via MarketSettle) or a user will (via FillBids or FillAsks). If we have different rates for those two, we can't know at order creation which set to use.

We can currently take the settlement fees out of the users accounts because either there's a hold on those funds in their accounts (and they've acknowledged that that amount is going to be eventually taken), or the funds can come out of the price funds the account just received (which they implicitly approved of by creating the order). And we can currently take our cut from the market accounts because we know that they just received more than we're taking out, and they also knew that we would be taking that portion. But if the exchange is getting its fee in a denom not otherwise involved in the settlement or its fees, neither of those actions are possible anymore.

With this issue, I was going to change it so that the fees that the exchange should receive would need to be included as part of the Tx fees for all of MarketSettle, FillBids, and FillAsks. The downside with that is that instead of the market account paying the exchange's portion of the fees, now the account calling those endpoints pays it. It's probably safe to assume that a market actor (with settle permission) would use funds provided by the market to pay that Tx fee, but for FillBids and FillAsks, we'd either need to figure out how to have the market compensate the caller, or else live with the users covering the exchange's portion of fees for those two endpoints.

I should also point at that, even with this change, we'd still want to restrict order creation fees to nhash (at the gov prop level) until we figure out a fix for that too.


I was curious to get a feel for the exchange's split amount, so I picked some numbers and did some math.

Note that the exchange stuff doesn't allow for fractional amounts, but in these examples, I'm using usd and hash with decimal amounts because they're easier to picture and understand.

Assume that:

  • 1hash = 0.025usd and therefore 1usd = 40hash.
  • The exchange's split bips is 500 (= 5%) for all denoms.
  • The market does not have any flat fees.
  • Fee = <Price> * <Fee Ratio RHS>/<Fee Ratio LHS>
  • Exchange Split = <Fee> * 500/10000 = <Fee> * 500/10000 * 40hash/1usd
Fee Ratio Price Fee
100:1 10usd 0.1usd
100:1 100usd 1usd
100:1 1000usd 10usd
100:1 1000000usd 10000usd
100:5 10usd 0.5usd
100:5 100usd 5usd
100:5 1000usd 50usd
100:5 1000000usd 50000usd
Fee Exchange Split
0.1usd 0.005usd = 0.2hash
0.2usd 0.010usd = 0.4hash
0.5usd 0.025usd = 1hash
1usd 0.050usd = 2hash
2usd 0.100usd = 4hash
10usd 0.500usd = 20hash
100usd 5usd = 200hash
10000usd 500usd = 20000hash
50000usd 2500usd = 100000hash

Now, let's compare some MarketSettle, FillBids, and FillAsks calls using the 100:1 fee ratio, and settling a bid and ask with the same assets and a price of 100usd. There will be a 1usd settlement fee for the bid and another 1usd for the ask; so the total settlement fee is 2usd, and the exchange's portion is 0.1usd = 4hash.

For all three endpoints, here's what currently happens:

  • The buyer pays 1usd to the market. This amount is part of the bid order and a hold was placed on it when the order was created. When the buyer created the order, they also explicitly approved the use of these funds this way.
  • The seller pays 1usd to the market. This amount isn't known until settlement, so it's not part of the data in an ask order and there's never a hold placed on it. We know it'll be in the account because it will always have the same denom as the price, and will always be less than the price. By creating the ask order, the seller implicitly approved the use of the price funds to cover the settlement fees like this.
  • 0.1usd is sent from the market account to the fee collector. We know the market account has this because it's the same denom(s) as the fees it just collected, and is always smaller than the fees it just collected. The market has implicitly approved this by running a market.
  • The buyer has paid 1usd in settlement fees.
  • The seller has paid 1usd in settlement fees.
  • The market ends up with 1.9usd from settlement fees.
  • The exchange gets 0.1usd.

With this change, here's what would happen:

  • MarketSettle:
    • The buyer pays 1usd to the market.
    • The seller pays 1usd to the market.
    • The market actor (caller of MarketSettle) adds an extra 4hash to the Tx Fees, which is then sent to the fee collector.
    • If the market actor is using market funds to pay that 4hash, there isn't really any change to who is paying the exchange's portion of fees here.
  • FillBids:
    • The buyer pays 1usd to the market.
    • The seller (caller of FillBids) pays 1usd to the market out of the price funds they just received.
    • The seller adds an extra 4hash to the Tx Fees, which is then sent to the fee collector.
    • The seller is now effectively paying 1.1usd in settlement fees where they were paying only 1usd before.
    • The market ends up with 2usd where they previously would have only kept 1.9usd.
  • FillAsks:
    • The buyer (caller of FillAsks) includes 1usd in settlement fees with their request, which is then sent to the market.
    • The seller pays 1usd to the market, which is taken out of the price funds they just received.
    • The buyer adds an extra 4hash to the Tx Fees, which is then sent to the fee collector.
    • The buyer is now effectively paying 1.1usd in settlement fees where they were paying only 1usd before.
    • The market ends up with 2usd where they previously would have only kept 1.9usd.

@SpicyLemon SpicyLemon modified the milestones: v1.18.0, v1.19.0 Apr 12, 2024
@SpicyLemon SpicyLemon modified the milestones: v1.19.0, v1.20.0 Jul 15, 2024
@iramiller iramiller modified the milestones: v1.20.0, v1.21.0 Oct 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Development

No branches or pull requests

2 participants