Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*

.idea
4 changes: 4 additions & 0 deletions docs/develop/modules/injective/exchange/02_other_concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,7 @@ Governance approves a **FeeDiscountProposal** which defines a fee discount **sch
- If the fee discount proposal was passed less than 30 days ago, i.e. `BucketCount * BucketDuration` hasn't passed yet since the creation of the proposal, the fee volume requirement is ignored so we don't unfairly penalize market makers who onboard immediately.

Internally the trading volumes are stored in buckets, typically 30 buckets each lasting 24 hours. When a bucket is older than 30 days, it gets removed. Additionally for performance reasons there is a cache for retrieving the fee discount tier for an account. This cache is updated every 24 hours.

### Stake Delegations/Grants

Staked INJ requirements for fee discount tiers can be met through grants from other addresses that have staked their INJ. The total staked INJ value used for fee discount calculations is `OwnStake + StakeGrantedFromGranter - TotalStakeGrantedToOthers`. Note that although several grants can be made to a single address, **only one grant can be activated** for use at a single time. However, a single address can have multiple grants made to other addresses at the same time. Note that only INJ staked with 25 validators is used to calculate `OwnStake` for stake grant purposes. To ensure all staked INJ can be utilized for grants, stake with 25 or fewer validators. Granted stake cannot be regranted.
37 changes: 37 additions & 0 deletions docs/develop/modules/injective/exchange/03_state.md
Original file line number Diff line number Diff line change
Expand Up @@ -592,3 +592,40 @@ enum ExecutionType {
LimitMatchNewOrder = 4;
}
```

## GrantAuthorization

`GrantAuthorization` is used to track the grantee's address and amount of the granted stake that has been authorized by the granter for trading fee discounts.

```protobuf
type GrantAuthorization struct {
Grantee string
Amount math.Int
}

```

## ActiveGrant

`ActiveGrant` is used to track the granter's address and amount of the granted stake (for trading fee discounts) in the grant that has been activated by the grantee.

```protobuf
type ActiveGrant struct {
Granter string
Amount math.Int
}

```

## EffectiveGrant

`EffectiveGrant` is used to track the total amount of stake a granter has authorized in stake grants for trading fee discounts.

```protobuf
type EffectiveGrant struct {
Granter string
NetGrantedStake math.Int
IsValid bool
}

```
78 changes: 50 additions & 28 deletions docs/develop/modules/injective/exchange/04_state_transitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ This document describes the state transition operations pertaining to:
- Derivative market param update proposal
- Trading rewards launch proposal
- Trading rewards update proposal
- Begin-blocker
- End-blocker
- Fee discount schedule proposal
- Stake grant authorizations
- Stake grant activation

## Deposit into exchange module account
## Deposit Into Exchange Module Account

Deposit action is carried out by `MsgDeposit` which consists of `Sender`, `SubaccountId` and `Amount` fields.

Expand All @@ -51,7 +52,7 @@ Deposit action is carried out by `MsgDeposit` which consists of `Sender`, `Subac
- Increment deposit amount for the `subaccountID` by `msg.Amount`
- Emit event for `EventSubaccountDeposit` with `msg.Sender`, `subaccountID` and `msg.Amount`

## Withdraw from exchange module account
## Withdraw From Exchange Module Account

Withdraw action is carried out by `MsgWithdraw` which consists of `Sender`, `SubaccountId` and `Amount` fields.

Expand All @@ -65,7 +66,7 @@ Withdraw action is carried out by `MsgWithdraw` which consists of `Sender`, `Sub
- Send coins from `exchange` module to `msg.Sender`
- Emit event for `EventSubaccountWithdraw` with `subaccountID`, `msg.Sender`, and `msg.Amount`

## Instant spot market launch
## Instant Spot Market Launch

Instant spot market launch action is carried out by `MsgInstantSpotMarketLaunch` which consists of `Sender`, `Ticker`, `BaseDenom`, `QuoteDenom`, `MinPriceTickSize` and `MinQuantityTickSize` fields.

Expand All @@ -77,7 +78,7 @@ Instant spot market launch action is carried out by `MsgInstantSpotMarketLaunch`
- 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
## Instant Perpetual Market Launch

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.

Expand All @@ -89,7 +90,7 @@ Instant perpetual market launch action is carried out by `MsgInstantPerpetualMar
- 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
## Instant Expiry Futures Market Launch

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.

Expand All @@ -102,7 +103,7 @@ Instant expiry futures market launch action is carried out by `MsgInstantExpiryF
- Trigger `EventExpiryFuturesMarketUpdate` event with market info
- Lastly send the instant listing fee to the community spend pool

## Spot limit order creation
## Spot Limit Order Creation

Spot limit order creation is carried out by `MsgCreateSpotLimitOrder` which consists of `Sender` and `Order`.

Expand All @@ -119,15 +120,15 @@ Spot limit order creation is carried out by `MsgCreateSpotLimitOrder` which cons

**Note:** The order in transient store is executed on endblocker or if not, put on long-live store.

## Batch creation of spot limit orders
## Batch Creation of Spot Limit Orders

Batch creation of spot limit orders is carried out by `MsgBatchCreateSpotLimitOrders` which consists of `Sender` and `Orders`.

**Steps**

- Loop over the `msg.Orders` and create spot limit order as in `MsgCreateSpotLimitOrder`

## Spot market order creation
## Spot Market Order Creation

Spot market order creation is carried out by `MsgCreateSpotMarketOrder` which consists of `Sender` and `Order`.

Expand All @@ -143,7 +144,7 @@ Spot market order creation is carried out by `MsgCreateSpotMarketOrder` which co
- Decrement deposit's AvailableBalance by the balance hold
- Store the order in the transient spot market order store and transient market indicator store

## Cancel spot order
## Cancel Spot Order

Spot order cancellation is carried out by `MsgCancelSpotOrder` which consists of `Sender` and `MarketId`, `SubaccountId` and `OrderHash`.

Expand All @@ -157,15 +158,15 @@ Spot order cancellation is carried out by `MsgCancelSpotOrder` which consists of
- Delete the order state from ordersStore and ordersIndexStore
- Emit `EventCancelSpotOrder` event with marketID and order info

## Batch cancellation of spot orders
## Batch Cancellation of Spot Orders

Batch cancellation of spot orders is carried out by `MsgBatchCancelSpotOrders` which consists of `Sender` and `Data`.

**Steps**

- Loop over the `msg.Data` and cancel spot order as in `MsgCancelSpotOrder`

## Derivative limit order creation
## Derivative Limit Order Creation

Derivative limit order creation is carried out by `MsgCreateDerivativeLimitOrder` which consists of `Sender` and `Order`.

Expand All @@ -188,15 +189,15 @@ Derivative limit order creation is carried out by `MsgCreateDerivativeLimitOrder
- Store the order in the transient limit order store and transient market indicator store
- Update orderbook metadata for subaccount

## Batch creation of derivative limit orders
## Batch Creation of Derivative Limit Orders

Batch creation of derivative limit orders is carried out by `MsgBatchCreateDerivativeLimitOrders` which consists of `Sender` and `Orders`.

**Steps**

- Loop over the `msg.Orders` and create derivative limit order as in `MsgCreateDerivativeLimitOrder`

## Derivative market order creation
## Derivative Market Order Creation

Derivative market order creation is carried out by `MsgCreateDerivativeMarketOrder` which consists of `Sender` and `Order`.

Expand All @@ -222,7 +223,7 @@ Derivative market order creation is carried out by `MsgCreateDerivativeMarketOrd
- 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

## Cancel derivative order
## Cancel Derivative Order

Derivative order cancellation is carried out by `MsgCancelDerivativeOrder` which consists of `Sender`, `MarketId`, `SubaccountId` and `OrderHash`.

Expand All @@ -237,15 +238,15 @@ Derivative order cancellation is carried out by `MsgCancelDerivativeOrder` which
- Update orderbook metadata for subaccount
- Emit `EventCancelDerivativeOrder` event with marketID and order info

## Batch cancellation of derivative orders
## Batch Cancellation of Derivative Orders

Batch cancellation of derivative orders is carried out by `MsgBatchCancelDerivativeOrders` which consists of `Sender` and `Data`.

**Steps**

- Loop over the `msg.Data` and cancel spot order as in `MsgCancelDerivativeOrder`

## Batch order updates
## Batch Order Updates

Batch updating orders is carried out by `MsgBatchUpdateOrders` which consists of `Sender` and `Orders`.

Expand All @@ -257,7 +258,7 @@ Batch updating orders is carried out by `MsgBatchUpdateOrders` which consists of
- 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
## Transfer Between Subaccounts

Transfer between subaccounts is executed by `MsgSubaccountTransfer` which consists of `Sender`, `SourceSubaccountId`, `DestinationSubaccountId` and `Amount`.

Expand All @@ -269,7 +270,7 @@ Transfer between subaccounts is executed by `MsgSubaccountTransfer` which consis

**Note:** With subaccount transfer, no need to transfer actual coins from bank module but changing the records are enough.

## Transfer to external account
## Transfer to External Account

Transfer to external account is executed by `MsgExternalTransfer` which consists of `Sender`, `SourceSubaccountId`, `DestinationSubaccountId` and `Amount`.

Expand All @@ -284,7 +285,7 @@ Transfer to external account is executed by `MsgExternalTransfer` which consists
1. Event should be different for subaccount transfer and external transfer.
2. There's no difference in subaccount transfer and external transfer, still need to keep different messages?

## Liquidating a position
## Liquidating a Position

Liquidating a position is executed by `MsgLiquidatePosition` which consists of `Sender`, `SubaccountId`, `MarketId` and `Order`.

Expand Down Expand Up @@ -315,7 +316,7 @@ Liquidating a position is executed by `MsgLiquidatePosition` which consists of `
- If market is a perpetual market, upgrade VWAP data based on liquidation price and quantity
- If there's remaining in liquidation order, return back remains by cancelling order

## Increasing position margin
## Increasing Position Margin

Increasing position margin is executed by `MsgIncreasePositionMargin` which consists of `Sender`, `SourceSubaccountId`, `DestinationSubaccountId`, `MarketId` and `Amount`.

Expand All @@ -329,7 +330,7 @@ Increasing position margin is executed by `MsgIncreasePositionMargin` which cons
- Reduce deposit amount of `sourceSubaccountID` by `msg.Amount`
- Increase position margin by `msg.Amount` and update position in the store

## Exchange enable proposal
## Exchange Enable Proposal

The enable of market type is done by `ExchangeEnableProposal` which consists of `Title`, `Description` and `ExchangeType`.

Expand All @@ -339,7 +340,7 @@ The enable of market type is done by `ExchangeEnableProposal` which consists of
- If `p.ExchangeType` is spot market, enable spot exchange
- If `p.ExchangeType` is derivative market, enable derivative market

## Spot market launch proposal
## Spot Market Launch Proposal

Launch of spot market is handled by `SpotMarketLaunchProposal` which consists of `Title`, `Description`, `Ticker`, `BaseDenom`, `QuoteDenom`, `MinPriceTickSize` and `MinQuantityTickSize` fields.

Expand All @@ -351,7 +352,7 @@ Launch of spot market is handled by `SpotMarketLaunchProposal` which consists of
- 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`.

## Perpetual market launch proposal
## Perpetual Market Launch Proposal

Perpetual market launch is handled by `PerpetualMarketLaunchProposal` which consists of `Title`, `Description`, `Ticker`, `QuoteDenom`, `OracleBase`, `OracleQuote`, `OracleScaleFactor`, `OracleType`, `MakerFeeRate`, `TakerFeeRate`, `InitialMarginRatio`, `MaintenanceMarginRatio`, `MinPriceTickSize` and `MinQuantityTickSize` fields.

Expand All @@ -366,7 +367,7 @@ Perpetual market launch is handled by `PerpetualMarketLaunchProposal` which cons
- Calculate `defaultFundingInterval`, `nextFundingTimestamp`, `relayerFeeShareRate` from `exchange` module params
- Execute `SetDerivativeMarketWithInfo` to set market info into the storage with `market`, `marketInfo` and `funding` objects

## Expiry futures market launch proposal
## Expiry Futures Market Launch Proposal

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.

Expand All @@ -382,7 +383,7 @@ Expiry futures market launch is handled by `ExpiryFuturesMarketLaunchProposal` w
- 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`.

## Spot market param update proposal
## Spot Market Param Update Proposal

The update of spot market param is handled by `SpotMarketParamUpdateProposal` which consists of `Title`, `Description`, `MarketId`, `MakerFeeRate`, `TakerFeeRate`, `RelayerFeeShareRate`, `MinPriceTickSize`, `MinQuantityTickSize` and `Status`.

Expand All @@ -393,7 +394,7 @@ The update of spot market param is handled by `SpotMarketParamUpdateProposal` wh
- 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 proposal
## Derivative Market Param Update Proposal

Derivative market param update is handled by `DerivativeMarketParamUpdateProposal` which consists of `Title`, `Description`, `MarketId`, `InitialMarginRatio`, `MaintenanceMarginRatio`, `MakerFeeRate`, `TakerFeeRate`, `RelayerFeeShareRate`, `MinPriceTickSize`, `MinQuantityTickSize` and `Status`.

Expand Down Expand Up @@ -445,3 +446,24 @@ Derivative market param update is handled by `DerivativeMarketParamUpdateProposa
- Set the first fee paid bucket timestamp as the current block time
- Set New Fee Discount Schedule, delete it along with Market Qualifications
- Set New Market Qualifications

## Stake Grant Authorizations

**Steps**

- 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


## Stake Grant Activation

**Steps**

- Check to make sure grant from granter to grantee exists
- Check to make sure granter is not granting more than their total staked amount
- If grant amount is 0, delete the grant, otherwise write new grant amount to store
- Emit `EventGrantActivation` with grantee, granter, and amount
38 changes: 36 additions & 2 deletions docs/develop/modules/injective/exchange/05_messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,6 @@ type MsgLiquidatePosition struct {
`MsgIncreasePositionMargin` describes a message to increase margin of an account.

```go
// A Cosmos-SDK MsgIncreasePositionMargin
type MsgIncreasePositionMargin struct {
Sender string
SourceSubaccountId string
Expand All @@ -417,7 +416,6 @@ type MsgIncreasePositionMargin struct {
`MsgBatchUpdateOrders` allows for the atomic cancellation and creation of spot and derivative limit orders, along with a new order cancellation mode. Upon execution, order cancellations (if any) occur first, followed by order creations (if any).

```go
// A Cosmos-SDK MsgBatchUpdateOrders
// SubaccountId only used for the spot_market_ids_to_cancel_all and derivative_market_ids_to_cancel_all.
type MsgBatchUpdateOrders struct {
Sender string
Expand All @@ -441,3 +439,39 @@ type MsgBatchUpdateOrders struct {
- `DerivativeOrdersToCancel` field describes specific derivative orders the sender wants to cancel.
- `SpotOrdersToCreate` field describes spot orders the sender wants to create.
- `DerivativeOrdersToCreate` field describes derivative orders the sender wants to create.



## Msg/AuthorizeStakeGrants

`MsgAuthorizeStakeGrants` is a message used to grant another address with staked INJ balance for fee discount purposes. It can also be used to revoke/remove grants if the amount granted is set to 0.

```go
type MsgAuthorizeStakeGrants struct {
Sender string
Grants []*GrantAuthorization
}
```

**Fields description**

- `Sender` describes the creator of this msg.
- `Grants` describes a list of grantees' addresses and grant amounts



## Msg/ActivateStakeGrant

`MsgActivateStakeGrant` is a message used to select/activate a stake grant for fee discount purposes.

```go
type MsgAuthorizeStakeGrants struct {
Sender string
Granter string
}
```

**Fields description**

- `Sender` describes the creator of this msg.
- `Granter` describes the address of the granter.
Comment on lines +462 to +477
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

LGTM! Fix struct name and consider adding an example.

The introduction of MsgActivateStakeGrant is well-documented and complements the MsgAuthorizeStakeGrants functionality. However, there's an error in the struct name in the code block.

Please update the struct name in the code block:

-type MsgAuthorizeStakeGrants struct {
+type MsgActivateStakeGrant struct {
 	Sender  string 
 	Granter string 
}

Consider adding a brief example demonstrating how to use this message type to activate a stake grant.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## Msg/ActivateStakeGrant
`MsgActivateStakeGrant` is a message used to select/activate a stake grant for fee discount purposes.
```go
type MsgAuthorizeStakeGrants struct {
Sender string
Granter string
}
```
**Fields description**
- `Sender` describes the creator of this msg.
- `Granter` describes the address of the granter.
## Msg/ActivateStakeGrant
`MsgActivateStakeGrant` is a message used to select/activate a stake grant for fee discount purposes.
```go
type MsgActivateStakeGrant struct {
Sender string
Granter string
}
```
**Fields description**
- `Sender` describes the creator of this msg.
- `Granter` describes the address of the granter.
🧰 Tools
🪛 Markdownlint

469-469: Column: 1
Hard tabs

(MD010, no-hard-tabs)


470-470: Column: 1
Hard tabs

(MD010, no-hard-tabs)


474-474: null
Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

Loading