Deposit action is carried out by MsgDeposit which consists of Sender, SubaccountId and Amount fields.Note:SubaccountId is optional and if it’s not available, it’s calculated dynamically from Sender address.Steps
Check that the denom specified in msg.Amount is a valid denom which exists in bank supply
Send coins from individual account to exchange module account and if fail, just revert
Get hash type of subaccountID from msg.SubaccountId, if it’s zero subaccount, calculate dynamically from msg.Sender by using SdkAddressToSubaccountID
Increment deposit amount for the subaccountID by msg.Amount
Emit event for EventSubaccountDeposit with msg.Sender, subaccountID and msg.Amount
Withdraw action is carried out by MsgWithdraw which consists of Sender, SubaccountId and Amount fields.Note: The ownership of msg.SubaccountId by msg.Sender is validated on msg.ValidateBasic function.Steps
Get hash type of subaccountID from msg.SubaccountId
Check the denom specified in msg.Amount is a valid denom which exists in bank supply
Decrement withdraw amount from subaccountID by msg.Amount, if fail, revert
Send coins from exchange module to msg.Sender
Emit event for EventSubaccountWithdraw with subaccountID, msg.Sender, and msg.Amount
Instant spot market launch action is carried out by MsgInstantSpotMarketLaunch which consists of Sender, Ticker, BaseDenom, QuoteDenom, MinPriceTickSize and MinQuantityTickSize fields.Steps
Calculate marketID from msg.BaseDenom and msg.QuoteDenom
Check if same market launch proposal exists by marketID and revert if already exists
Launch spot market with msg.Ticker, msg.BaseDenom, msg.QuoteDenom, msg.MinPriceTickSize, msg.MinQuantityTickSize and revert if fail
Send instant listing fee(params.SpotMarketInstantListingFee) from msg.Sender to exchange module account
Lastly send the instant listing fee to the community spend pool
Instant perpetual market launch action is carried out by MsgInstantPerpetualMarketLaunch which consists of Sender, Ticker, QuoteDenom, OracleBase, OracleQuote, OracleScaleFactor, OracleType, MakerFeeRate, TakerFeeRate, InitialMarginRatio, MaintenanceMarginRatio, MinPriceTickSize and MinQuantityTickSize fields.Steps
Calculate marketID from msg.Ticker, msg.QuoteDenom, msg.OracleBase, msg.OracleQuote and msg.OracleType.
Check if same market launch proposal exists by marketID and revert if already exists
Send instant listing fee(params.DerivativeMarketInstantListingFee) from msg.Sender to exchange module account
Launch perpetual market with required params on msg object and revert if fail
Lastly send the instant listing fee to the community spend pool
Instant expiry futures market launch action is carried out by MsgInstantExpiryFuturesMarketLaunch which consists of Sender, Ticker, QuoteDenom, OracleBase, OracleQuote, OracleScaleFactor, OracleType, Expiry, MakerFeeRate, TakerFeeRate, InitialMarginRatio, MaintenanceMarginRatio, MinPriceTickSize and MinQuantityTickSize fields.Steps
Calculate marketID from msg.Ticker, msg.QuoteDenom, msg.OracleBase, msg.OracleQuote, msg.OracleType and msg.Expiry.
Check if same market launch proposal exists by marketID and revert if already exists
Send instant listing fee(params.DerivativeMarketInstantListingFee) from msg.Sender to exchange module account
Launch expiry futures market with required params on msg object and revert if fail
Trigger EventExpiryFuturesMarketUpdate event with market info
Lastly send the instant listing fee to the community spend pool
Derivative market order creation is carried out by MsgCreateDerivativeMarketOrder which consists of Sender and Order.Steps
Check derivative exchange is enabled to make an order on derivative market and if not revert
Check if SubaccountID that is going to make new order has limit derivative order or market order and reject. Note: Perpetual market can’t place two market orders or both limit / market orders at the same time?
Check order’s price and quantity tick sizes fits market’s min quantity and price tick size
Increment Subaccount’s TradeNonce
Reject if derivative market id does not reference an active derivative market
Calculate unique order hash with TradeNonce
Check that the market order worst price reaches the best opposing resting orderbook price
Check Order/Position Margin amount
If it’s reduce only order
A. Check if position for subaccountID on the market is not nil
B. Check that the order can close the position
C. Reject if position.quantity - AggregateReduceOnlyQuantity - order.quantity < 0
D. Set MarginHold as zero for no margin hold for selling positions
If it’s not reduce only order
A. Check available balance to fund the market order
B. Reject if the subaccount’s available deposits does not have at least the required funds for the trade
C. Decrement deposit’s AvailableBalance by the balance hold
For an opposing position, if AggregateVanillaQuantity > position.quantity - AggregateReduceOnlyQuantity - order.FillableQuantity, the new reduce-only order might invalidate some existing reduce-only orders or itself be invalid, and do operations for that.
Store the order in the transient derivative market order store and transient market indicator store
Batch updating orders is carried out by MsgBatchUpdateOrders which consists of Sender and Orders.Steps
Cancel all orders in all market id specified by SpotMarketIdsToCancelAll and DerivativeMarketIdsToCancelAll for specified subaccount id
Loop over the msg.SpotOrdersToCancel and cancel spot limit order as in MsgCancelSpotOrder. If the cancel fails, continue to next order. The success of cancellations is reflected in the MsgBatchUpdateOrdersResponse as SpotCancelSuccess.
Loop over the msg.DerivativeOrdersToCancel and cancel derivative limit order as in MsgCancelDerivativeOrder. If the cancel fails, continue to next order. The success of cancellations is reflected in the MsgBatchUpdateOrdersResponse as DerivativeCancelSuccess.
Loop over the msg.SpotOrdersToCreate and create spot limit order as in MsgCreateSpotOrder. If the creation fails, continue to next order. Successful creations are reflected in the MsgBatchUpdateOrdersResponse as SpotOrderHashes.
Loop over the msg.DerivativeOrdersToCreate and create derivative limit order as in MsgCreateDerivativeOrder. If the creation fails, continue to next order. Successful creations are reflected in the MsgBatchUpdateOrdersResponse as DerivativeOrderHashes.
Transfer between subaccounts is executed by MsgSubaccountTransfer which consists of Sender, SourceSubaccountId, DestinationSubaccountId and Amount.Steps
Withdraw deposit from msg.SourceSubaccountId for msg.Amount, if fail revert transaction
Increment deposit of msg.DestinationSubaccountId by msg.Amount
Emit event for EventSubaccountBalanceTransfer with SrcSubaccountId, DstSubaccountId and msg.Amount
Note: With subaccount transfer, no need to transfer actual coins from bank module but changing the records are enough.
Increasing position margin is executed by MsgIncreasePositionMargin which consists of Sender, SourceSubaccountId, DestinationSubaccountId, MarketId and Amount.Steps
Check derivative exchange is enabled to increase position margin on derivative market and if not revert
Reject if derivative market id does not reference an active derivative market
Get deposit of sourceSubaccountID
If deposit.AvailableBalance is lower than msg.Amount, revert
Get position by marketID and destinationSubaccountID and if not exist, revert
Reduce deposit amount of sourceSubaccountID by msg.Amount
Increase position margin by msg.Amount and update position in the store
Launch of spot market is handled by SpotMarketLaunchProposal which consists of Title, Description, Ticker, BaseDenom, QuoteDenom, MinPriceTickSize and MinQuantityTickSize fields.Steps
ValidateBasic for proposal
Validate BaseDenom and QuoteDenom are valid
Validate if same market does not exist by msg.BaseDenom and msg.QuoteDenom
Calculate RelayerFeeShareRate based on exchange module params. Note: for INJ currency, relayer share rate is set to 100%
Save spot market with calculated ticker, baseDenom, quoteDenom, exchangeParams.DefaultSpotMakerFeeRate, exchangeParams.DefaultSpotTakerFeeRate, relayerFeeShareRate, minPriceTickSize, minQuantityTickSize, marketID, and MarketStatus_Active.
Expiry futures market launch is handled by ExpiryFuturesMarketLaunchProposal which consists of Title, Description, Ticker, QuoteDenom, OracleBase, OracleQuote, OracleScaleFactor, OracleType, Expiry, MakerFeeRate, TakerFeeRate, InitialMarginRatio, MaintenanceMarginRatio, MinPriceTickSize and MinQuantityTickSize fields.Steps
ValidateBasic for proposal
Validate quoteDenom
Calculate marketID from p.Ticker, p.QuoteDenom, p.OracleBase, p.OracleQuote, p.OracleType and p.Expiry
Validate active or inactive expiry futures market for marketID does not exist
If expiry time passed ctx.BlockTime() already, revert
Try getting derivative market price to check price oracle by oracleBase, oracleQuote, oracleScaleFactor, oracleType
Validate insurance fund exist for marketID
Calculate RelayerFeeShareRate based on exchange module params. Note: for INJ currency, relayer share rate is set to 100%
Execute SetDerivativeMarketWithInfo to set market info into the storage with market, marketInfo objects Note: TwapStartTimestamp is set to expiry - thirtyMinutesInSeconds.
The update of spot market param is handled by SpotMarketParamUpdateProposal which consists of Title, Description, MarketId, MakerFeeRate, TakerFeeRate, RelayerFeeShareRate, MinPriceTickSize, MinQuantityTickSize and Status.Steps
ValidateBasic for proposal
Get spot market by p.MarketId and if not exist, revert
Reset the params for MakerFeeRate, TakerFeeRate, RelayerFeeShareRate, MinPriceTickSize, MinQuantityTickSize and Status if not empty, if empty keep as it is.
Validate MakerFeeRate is bigger than TakerFeeRate.
Derivative market param update is handled by DerivativeMarketParamUpdateProposal which consists of Title, Description, MarketId, InitialMarginRatio, MaintenanceMarginRatio, MakerFeeRate, TakerFeeRate, RelayerFeeShareRate, MinPriceTickSize, MinQuantityTickSize and Status.Steps
ValidateBasic for proposal
Validate Derivative market exists by p.MarketId and if not exist, revert
Reset the params for InitialMarginRatio, MaintenanceMarginRatio, MakerFeeRate, TakerFeeRate, RelayerFeeShareRate, MinPriceTickSize, MinQuantityTickSize and Status if not empty, if empty keep as it is.
Validate MakerFeeRate is bigger than TakerFeeRate.
Validate InitialMarginRatio is bigger than MaintenanceMarginRatio.
Schedule Derivative market param update and update finalization on Endblocker - Note: this is due to the orders update for derivative market param update - should make sure nothing panics here.
Check if an existing grant from the granter already exists for the grantee
Calculate the new total amount of stake granted to the grantee by subtracting the existing grant amounts and adding the new grant amounts (essentially overwrites the existing grant amounts with the new grant amounts)
Ensure valid grant authorizations by making sure total amount granted is less than or equal to total amount staked by granter
Update grant amounts for grantee
Set grant to active if the current active grant is from the same granter or if there is no current active grant
Emit EventGrantAuthorizations with granter and grants