-
Notifications
You must be signed in to change notification settings - Fork 97
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
feat(x/ecocredit): Msg Server implementation for buy/sell functionality #613
Conversation
Codecov Report
@@ Coverage Diff @@
## master #613 +/- ##
==========================================
- Coverage 75.23% 74.09% -1.15%
==========================================
Files 104 104
Lines 14628 14899 +271
==========================================
+ Hits 11006 11039 +33
- Misses 2902 3131 +229
- Partials 720 729 +9
Flags with carried forward coverage won't be shown. Click here to find out more. |
Co-authored-by: Cory <cjlevinson@gmail.com>
|
||
m.Orders[i].AskPrice.Validate() | ||
|
||
if !m.Orders[i].AskPrice.Amount.IsPositive() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
coins.Validate checks for negatives. just wondering, are we doing this to avoid 0 amt bids?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. The intention here was to prevent sell orders from being created with a 0 amount ask price and therefore buy orders with a 0 amount bid price (bid price must be ask price at minimum). I think this behavior is desired but let me know if you think otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dtkong thoughts here? @ryanchristo and I had thought that we didn't want to allow buy/sell orders w/ a 0 ask price. If there's a valid use case for it we can change this.
|
||
m.Updates[i].NewAskPrice.Validate() | ||
|
||
if !m.Updates[i].NewAskPrice.Amount.IsPositive() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if anyone would ever do this, but would we want to allow credits to sell for 0 here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My initial thought was that we would not want to support 0 amount ask price but maybe we should?
@@ -577,3 +516,346 @@ func (s serverImpl) isCreatorAllowListed(ctx types.Context, allowlist []string, | |||
} | |||
return false | |||
} | |||
|
|||
// Sell creates new sell orders for credits | |||
func (s serverImpl) Sell(goCtx context.Context, req *ecocredit.MsgSell) (*ecocredit.MsgSellResponse, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
im curious what will happen if a user creates multiple sell orders around the same credits. i think there is a concern with flooding the chain with a bunch of seemingly valid sell orders that are actually all but one invalid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a valid concern. We discussed an escrow model as a potential alternative but at the moment we are only checking the credit balance at the time the sell order is created.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well maybe we should revisit the pros and cons and escrow. Can you guys think a little more about the pros and cons and the threat model here?
} | ||
|
||
// EventBuy is an event emitted when a buy order is created. | ||
message EventBuy { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have separate events when buy orders are created and filled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would this work? We're not storing buy orders in state, so the created event would emit if partial or filled and the filled event would emit only if the buy order was filled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this would work for orders with filters, where buy orders can be made for a credit with X characteristics, but no direct sell order ID listed.. but sounds like it wont work for orders with direct SellOrderId's as with those you either fill it or you don't.
Is there any spec on how the matching engine will work in this scheme for floating buy/sell orders?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the current implementation, it is possible to do a partial fill with a buy order that specifies a sell order id but I'm not sure what we should do with the buy order if the order was only partially filled.
At the moment, if partial fill is enabled, the buyer purchases the available credits from the given sell order and that's it (the buy order does not persist to state and there is no fulfilling the remainder of the order at a later point in time); if the buyer specifies more credits than what is available in the sell order, the buyer ends up purchasing only what is available.
When we implement the filtered option (#623), the same question applies. If partial fill is enabled and an order is only partially filled given the filter criteria, how will the buy order be fulfilled at a later point in time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how will the buy order be fulfilled at a later point in time?
Just like in regular exchanges, if the buy order is partially filled it will stay open and way for new or updated sell orders. Basically in every processing batch an attempt will be made to match it with sell orders.
We should probably have expiration times for both sell and buy orders btw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point we havn't implemented any of the ORM tables for storing buy orders in state, but sounds like we would need this in order to actually process partial-filling correctly (where we keep a buy order open). If we don't implement that in this PR we could also just add it in a follow-up. When persisting the partially filled buy order to state, how would we store the selection
? Would it still reference the original sell_order_id
? Afaiu, the sell order would be exhausted and then closed (removed from state), so there wouldn't be any way for a seller to top up their supply on an existing sell order. They would rather create a new sell order.
If we allow for partial fills I'm not really sure how we can keep those buy orders open seeing that they are against sell order which would have already closed..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we address in a follow-up, it might make sense to include with #623 assuming that we would only need to store a buy order if it was using the filter option (not a direct buy order).
I added a second event for filling buy orders to distinguish from creating buy orders. At the moment the second event seems unnecessary given that only direct buy orders are implemented in this pull request but it makes sense when we implement the filter option. I think this goes in line with #623 as well.
I also added a couple commits to update the remaining quantity if the buy order does not purchase all credits within the sell order and to delete the sell order if there are no remaining credits.
Maybe we should break out a separate issue for adding and handling expiration times..?
Co-authored-by: MD Aleem <72057206+aleem1314@users.noreply.github.com> Co-authored-by: Tyler <48813565+technicallyty@users.noreply.github.com>
Co-authored-by: Tyler <48813565+technicallyty@users.noreply.github.com>
if req.RootAddress != authtypes.NewModuleAddress(govtypes.ModuleName).String() { | ||
return nil, sdkerrors.ErrUnauthorized.Wrap("root address must be governance module address") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ready for another round of reviews. Aside from remaining items that already have issues, here are the remaining items that I can see for this pull request that could either be addressed here or in follow-up pull requests:
Let me know if you think any of these should be addressed here, otherwise I think it might be nice to include them in follow up issues. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
regarding #613 (comment), i think it would make sense to include the buy order table here, just to set it up for the processing PR
Co-authored-by: Tyler <48813565+technicallyty@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great work! 💯 💯 💯 💯 💯 💯 💯
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few small nits, otherwise giving this an ACK 🎉
@ryanchristo can you give an approval for me, since I authored the original PR ?
// total_price is the total price for the purchased credits. | ||
cosmos.base.v1beta1.Coin total_price = 5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// total_price is the total price for the purchased credits. | |
cosmos.base.v1beta1.Coin total_price = 5; | |
// price is the total price for the purchased credits. | |
cosmos.base.v1beta1.Coin price = 5; |
I like price
instead of total_price
, since its not like prices are summed (creating a "total")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The price here is the amount of coin sent (not the price per unit but the calculated amount of coin needed to fill the order). I thought it might help to use total to distinguish from bid price and ask price (per unit) more clearly.
// sell_order_id is the sell order ID against which the buyer is trying to buy. | ||
uint64 sell_order_id = 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine for now, but we'll eventually want to upgrade this to be either a sell_order_id
or some selection criteria, right? I think we can just do so once we add buy orders based on a selection criteria.
No todo in this PR, I think we should just keep in mind to update the event when we add the rest of the buy order functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. This will need to be updated when we introduce filtered buy orders. #623
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ryanchristo can you give an approval for me, since I authored the original PR ?
Description
Closes: #603 #614 #622
This pull request implements the following:
SellOrder
,BuyOrder
, andAskDenom
EventSell
,EventUpdateSellOrder
,EventBuyOrderCreated
,EventBuyOrderFilled
, andEventAllowAskDenom
Sell
,UpdateSellOrders
,Buy
, andAllowAskDenom
ValidateBasic
forMsgSell
,MsgUpdateSellOrders
,MsgBuy
, andMsgAllowAskDenom
Author Checklist
All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.
I have...
!
to the type prefix if API or client breaking changeCHANGELOG.md
Reviewers Checklist
All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.
I have...
!
in the type prefix if API or client breaking change