diff --git a/.gitbook/developers/modules/core/README.md b/.gitbook/developers/modules/core/README.md
deleted file mode 100644
index b0790a93..00000000
--- a/.gitbook/developers/modules/core/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-import {
- HomepageSection as Section
-} from "../../../../src/components/HomepageComponents";
-import ComponentsGrid from "@theme/DocCardList";
-
-# Core Modules
-
-
diff --git a/.gitbook/developers/modules/core/genutils.md b/.gitbook/developers/modules/core/genutils.md
deleted file mode 100644
index ccf79c83..00000000
--- a/.gitbook/developers/modules/core/genutils.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# Genutils
-
diff --git a/.gitbook/developers/modules/injective/auction/02_messages.md b/.gitbook/developers/modules/injective/auction/02_messages.md
index 33336723..97f7253f 100644
--- a/.gitbook/developers/modules/injective/auction/02_messages.md
+++ b/.gitbook/developers/modules/injective/auction/02_messages.md
@@ -1,11 +1,11 @@
---
sidebar_position: 2
-title: Messages
+title: Messages
---
# Messages
-In this section, we describe the processing of the auction messages and the corresponding updates to the state.
+In this section we describe the processing of the auction messages and the corresponding updates to the state.
## Msg/Bid
@@ -26,7 +26,7 @@ message MsgBid {
This service message is expected to fail if:
-* `Round` does not equal the current auction round
-* `BidAmount` does not exceed the previous highest bid amount by at least `min_next_increment_rate` percent.
+- `Round` does not equal the current auction round
+- `BidAmount` does not exceed the previous highest bid amount by at least `min_next_increment_rate` percent.
This service message transfers the `BidAmount` of INJ from the `Sender` to the auction module, stores the bid, and refunds the last bidder's bid amount.
diff --git a/.gitbook/developers/modules/injective/auction/03_end_block.md b/.gitbook/developers/modules/injective/auction/03_end_block.md
index fa20553a..88018bc3 100644
--- a/.gitbook/developers/modules/injective/auction/03_end_block.md
+++ b/.gitbook/developers/modules/injective/auction/03_end_block.md
@@ -1,21 +1,21 @@
---
sidebar_position: 3
-title: End-Block
+title: End-Block
---
-# EndBlock
+# End-Block
### Auction Settlement
-The settlement of a given auction round occurs when `blockTime ≥ EndingTimeStamp.` If a non-zero INJ bid was placed during this period (i.e., there exists a `LastBid`), the following procedure will take place:
+The settlement of a given auction round occurs when `blockTime ≥ EndingTimeStamp.` If a non-zero INJ bid was placed during this period (i.e. there exists a `LastBid`), the following procedure will take place:
-* The winning INJ bid amount is burned.
-* The basket of coins held by the auction module is transferred to the winning bidder.
-* `LastAuctionResult` is written to state and `EventAuctionResult` is emitted.
-* The `LastBid` is cleared.
-* The AuctionRound is incremented by 1 and the EndingTimestamp is incremented by `AuctionPeriod`.
-* The accumulated exchange fees are transferred from the `exchange` module to the `auction` module for the new upcoming auction.
+- The winning INJ bid amount is burned.
+- The basket of coins held by the auction module is transferred to the winning bidder.
+- `LastAuctionResult` is written to state and `EventAuctionResult` is emitted.
+- The `LastBid` is cleared.
+- The AuctionRound is incremented by 1 and the EndingTimestamp is incremented by `AuctionPeriod`.
+- The accumulated exchange fees are transferred from the `exchange` module to the `auction` module for the new upcoming auction.
-If the round closed without any successful bids, the existing coin basket will be rolled over into the next auction and combined with the new accumulated fee basket.
+If the round closed without any successful bids, the existing coin basket will be rolled over into the next auction and combined with the new accumulated fee basket.
-![img.png](img.png)
+![img.png](./img.png)
\ No newline at end of file
diff --git a/.gitbook/developers/modules/injective/auction/README.md b/.gitbook/developers/modules/injective/auction/README.md
index 672d9595..55f22fdc 100644
--- a/.gitbook/developers/modules/injective/auction/README.md
+++ b/.gitbook/developers/modules/injective/auction/README.md
@@ -1,13 +1,15 @@
-# Auction
+# `Auction`
## Abstract
-The `auction` module periodically obtains a basket of tokens accumulated from trading fees from the `exchange` module and auctions the basket to the highest bidder in an open English auction for INJ. The winner of this auction receives the basket of tokens, and the winning INJ bid amount from this auction is burned.
+The `auction` module periodically obtains a basket of tokens accumulated from trading fees from the `exchange` module and auctions the basket to the highest bidder in an open English auction for INJ. The winner of this auction receives the basket of tokens and the winning INJ bid amount from this auction is burned.
## Contents
-1. [**State**](01_state.md)
-2. [**Messages**](02_messages.md)
-3. [**End Block**](03_end_block.md)
-4. [**Events**](04_events.md)
-5. [**Params**](05_params.md)
+1. **[State](./01_state.md)**
+2. **[Messages](./02_messages.md)**
+3. **[End Block](./03_end_block.md)**
+4. **[Events](./04_events.md)**
+5. **[Params](./05_params.md)**
+
+
diff --git a/.gitbook/developers/modules/injective/exchange/00_derivative_market_concepts.md b/.gitbook/developers/modules/injective/exchange/00_derivative_market_concepts.md
index 59615452..f1227953 100644
--- a/.gitbook/developers/modules/injective/exchange/00_derivative_market_concepts.md
+++ b/.gitbook/developers/modules/injective/exchange/00_derivative_market_concepts.md
@@ -3,15 +3,19 @@ sidebar_position: 1
title: Derivative Market Concept
---
-# Derivative Markets Concepts
+# Derivative Market Concepts
## Definitions
-In a derivative market using linear contracts (as opposed to inverse contracts), a contract with ticker **AAA/BBB** offers exposure to the underlying AAA using the quote currency BBB for margin and settlement. For each contract, the quotation unit is the BBB price of one unit of AAA, e.g. the USDT price of one unit of ETH.
+In a derivative market using linear contracts (as opposed to inverse contracts), a contract with ticker **AAA/BBB**
+offers exposure to the underlying AAA using the quote currency BBB for margin and settlement. For each contract, the
+quotation unit is the BBB price of one unit of AAA, e.g. the USDT price of one unit of ETH.
**Notional** - the notional value of a position is: `notional = quantity * price`.
-**Refunds -** In our clearing system, a refund refers to the action of incrementing the **available balance** of an account. This liberation of funds occurs as the result of an encumbrance being lifted from the account (e.g. cancelling a limit order, reducing an order's payable fee to a maker fee, using less margin to fund a market order, etc.).
+**Refunds -** In our clearing system, a refund refers to the action of incrementing the **available balance** of an
+account. This liberation of funds occurs as the result of an encumbrance being lifted from the account (e.g. cancelling
+a limit order, reducing an order's payable fee to a maker fee, using less margin to fund a market order, etc.).
## Perpetual Market Trading Lifecycle
@@ -23,25 +27,32 @@ A market is first created either by the instant launch functionality through `Ms
#### Depositing Funds into Exchange
-A trader can deposit funds, e.g., USDT, into the exchange by sending a `MsgDeposit` which transfers coins from the Cosmos-SDK bank module to the trader's subaccount deposits on the exchange module.
+A trader can deposit funds, e.g., USDT, into the exchange by sending a `MsgDeposit` which transfers coins from the
+Cosmos-SDK bank module to the trader's subaccount deposits on the exchange module.
-Depositing a given `Amount` of coin will increment both the trader's subaccount deposit `AvailableBalance` and `TotalBalance` by `Amount`.
+Depositing a given `Amount` of coin will increment both the trader's subaccount deposit `AvailableBalance`
+and `TotalBalance` by `Amount`.
#### Withdrawing Funds from Exchange
-A trader can withdraw funds from the exchange by sending a `MsgWithdraw` which transfers coins from the trader's subaccount on the exchange module.
+A trader can withdraw funds from the exchange by sending a `MsgWithdraw` which transfers coins from the trader's subaccount
+on the exchange module.
-**Withdrawal Requirement:** Withdrawing a given `Amount` of coin will decrement both the trader's subaccount deposit `AvailableBalance` and `TotalBalance` by `Amount`. Note: `Amount` must be less than or equal to `AvailableBalance`.
+**Withdrawal Requirement:** Withdrawing a given `Amount` of coin will decrement both the trader's subaccount
+deposit `AvailableBalance` and `TotalBalance` by `Amount`. Note: `Amount` must be less than or equal
+to `AvailableBalance`.
#### Transferring Funds between Subaccounts
-A trader can transfer funds between his own subaccounts sending a `MsgSubaccountTransfer` which transfer coins from one of the trader's subaccount deposits to another subaccount also owned by the trader.
+A trader can transfer funds between his own subaccounts sending a `MsgSubaccountTransfer` which transfer coins from one of
+the trader's subaccount deposits to another subaccount also owned by the trader.
Subaccount transfers have the same Withdrawal Requirement as normal withdrawals.
#### Transferring Funds to another Exchange Account
-A trader can transfer funds to an external account by sending a `MsgExternalTransfer` which transfers funds from the trader's subaccount to another third-party account.
+A trader can transfer funds to an external account by sending a `MsgExternalTransfer` which transfers funds from the
+trader's subaccount to another third-party account.
External Funds transfers have the same Withdrawal Requirement as normal withdrawals.
@@ -49,20 +60,26 @@ External Funds transfers have the same Withdrawal Requirement as normal withdraw
#### Placing Limit Orders
-A trader can post a limit buy or sell order by sending a `MsgCreateDerivativeLimitOrder`. Upon submission, the order can be:
+A trader can post a limit buy or sell order by sending a `MsgCreateDerivativeLimitOrder`. Upon submission, the order can
+be:
-1. Immediately (fully or partially) matched against other opposing resting orders on the orderbook in the Endblocker batch auction, thus establishing a position for the user.
+1. Immediately (fully or partially) matched against other opposing resting orders on the orderbook in the Endblocker
+ batch auction, thus establishing a position for the user.
2. Added to the orderbook.
-Note that it is possible for an order to be partially matched and for the remaining unmatched portion to be added to the orderbook.
+Note that it is possible for an order to be partially matched and for the remaining unmatched portion to be added to the
+orderbook.
#### Placing Market Orders
-A trader can post a market buy or sell order by sending a `MsgCreateDerivativeMarketOrder`. Upon submission, the market order will be executed against other opposing resting orders on the orderbook in the Endblocker batch auction, thus establishing a position for the user.
+A trader can post a market buy or sell order by sending a `MsgCreateDerivativeMarketOrder`. Upon submission, the market
+order will be executed against other opposing resting orders on the orderbook in the Endblocker batch auction, thus
+establishing a position for the user.
#### Cancelling Limit Orders
-User cancels a limit buy or sell order by sending a `MsgCancelDerivativeOrder` which removes the user's limit order from the orderbook.
+User cancels a limit buy or sell order by sending a `MsgCancelDerivativeOrder` which removes the user's limit order from
+the orderbook.
### Increasing Position Margin
@@ -70,35 +87,34 @@ A user can increase the margin of a position by sending a `MsgIncreasePositionMa
### Liquidating Insolvent Positions
-A third party can liquidate any user's position if the position's maintenance margin ratio is breached by sending a `MsgLiquidatePosition`.
+A third party can liquidate any user's position if the position's maintenance margin ratio is breached by sending a
+`MsgLiquidatePosition`.
**Initial Margin Requirement**
-This is the requirement for the ratio of margin to the order's notional as well as the mark price when creating a new position. The idea behind the additional mark price requirement is to minimize the liquidation risk when traded prices and mark prices temporally diverge too far from each other. Given the initial margin ratio, an order must fulfill two requirements:
+This is the requirement for the ratio of margin to the order's notional as well as the mark price when creating a new position.
+The idea behind the additional mark price requirement is to minimize the liquidation risk when traded prices and mark prices
+temporally diverge too far from each other. Given the initial margin ratio, an order must fulfill two requirements:
-* The margin must fulfill: `Margin ≥ InitialMarginRatio * Price * Quantity`, e.g., in a market with maximally 20x leverage, the initial margin ratio would be 0.05. Any new position will have a margin which is at least 0.05 of its notional.
-* The margin must fulfill the mark price requirement:
-* `Margin >= Quantity * (InitialMarginRatio * MarkPrice - PNL)`
+- The margin must fulfill: `Margin ≥ InitialMarginRatio * Price * Quantity`, e.g., in a market with maximally 20x leverage,
+ the initial margin ratio would be 0.05. Any new position will have a margin which is at least 0.05 of its notional.
+- The margin must fulfill the mark price requirement:
-PNL is the expected profit and loss of the position if it was closed at the current MarkPrice. Solved for MarkPrice this results in:
-
-* For Buys:
+- `Margin >= Quantity * (InitialMarginRatio * MarkPrice - PNL)`
- $$
- \mathrm{MarkPrice} \geq \frac{\mathrm{Margin} - \mathrm{Price} \times \mathrm{Quantity}}{(\mathrm{InitialMarginRatio} - 1) \times \mathrm{Quantity}}
- $$
-* For Sells:
+PNL is the expected profit and loss of the position if it was closed at the current MarkPrice. Solved for MarkPrice this results in:
- $$
- \mathrm{MarkPrice} \leq \frac{\mathrm{Margin} + \mathrm{Price} \times \mathrm{Quantity}}{(\mathrm{InitialMarginRatio} + 1) \times \mathrm{Quantity}}
- $$
+- For Buys: $\mathrm{MarkPrice}$ ≥ $\mathrm{\frac{Margin - Price * Quantity}{(InitialMarginRatio - 1) * Quantity}}$
+- For Sells: $\mathrm{MarkPrice}$ ≤ $\mathrm{\frac{Margin + Price * Quantity}{(InitialMarginRatio + 1) * Quantity}}$
**Maintenance Margin Requirement**
-Throughout the lifecycle of an active position, if the following margin requirement is not met, the position is subject to liquidation. (Note: for simplicity of notation but without loss of generality, we assume the position considered does not have any funding).
+Throughout the lifecycle of an active position, if the following margin requirement is not met, the position is subject
+to liquidation. (Note: for simplicity of notation but without loss of generality, we assume the position considered does
+not have any funding).
-* For Longs: `Margin >= Quantity * MaintenanceMarginRatio * MarkPrice - (MarkPrice - EntryPrice)`
-* For Shorts: `Margin >= Quantity * MaintenanceMarginRatio * MarkPrice - (EntryPrice - MarkPrice)`
+- For Longs: `Margin >= Quantity * MaintenanceMarginRatio * MarkPrice - (MarkPrice - EntryPrice)`
+- For Shorts: `Margin >= Quantity * MaintenanceMarginRatio * MarkPrice - (EntryPrice - MarkPrice)`
**Liquidation Payouts**
@@ -110,101 +126,119 @@ Also note that liquidations are executed immediately in a block before any other
### Funding Payments
-Funding exists only for perpetual markets as a mechanism to align trading prices with the mark price. It refers to the periodic payments exchanged between the traders that are long or short of a contract at the end of every funding epoch, e.g. every hour. When the funding rate is positive, longs pay shorts. When it is negative, shorts pay longs.
+Funding exists only for perpetual markets as a mechanism to align trading prices with the mark price. It refers to the
+periodic payments exchanged between the traders that are long or short of a contract at the end of every funding epoch,
+e.g. every hour. When the funding rate is positive, longs pay shorts. When it is negative, shorts pay longs.
-* `Position Size = Position Quantity * MarkPrice`
-* `Funding Payment = Position Size * Hourly Funding Rate (HFR)`
-* `HFR = Cap((TWAP((SyntheticVWAPExecutionPrice - MarkPrice)/MarkPrice) + DailyInterestRate) * 1/24)`
-* `SyntheticVWAPExecutionPrice = (Price_A*Volume_A +Price_B*Volume_B +Price_C*Volume_C)/(Volume_A + Volume_B + Volume_C)`
- * `A` is the market buy batch execution
- * `B` is the market sell batch execution
- * `C` is the limit matching batch execution
+- `Position Size = Position Quantity * MarkPrice`
+- `Funding Payment = Position Size * Hourly Funding Rate (HFR)`
+- `HFR = Cap((TWAP((SyntheticVWAPExecutionPrice - MarkPrice)/MarkPrice) + DailyInterestRate) * 1/24)`
+- `SyntheticVWAPExecutionPrice = (Price_A*Volume_A +Price_B*Volume_B +Price_C*Volume_C)/(Volume_A + Volume_B + Volume_C)`
+ - `A` is the market buy batch execution
+ - `B` is the market sell batch execution
+ - `C` is the limit matching batch execution
Funding payments are applied to the whole market by modifying the `CumulativeFunding` value. Each position stores the current `CumulativeFunding` as `CumulativeFundingEntry`. Subsequent funding payments are only applied upon position changes and can be calculated as:
-* FundingPayment
- * For Longs: `FundingPayment ← PositionQuantity * (CumulativeFunding - CumulativeFundingEntry)`
- * For Shorts: `FundingPayment ← PositionQuantity * (CumulativeFundingEntry - CumulativeFunding)`
-* `Margin' ← Margin + FundingPayment`
-* `CumulativeFundingEntry' ← CumulativeFunding`
+- FundingPayment
+ - For Longs: `FundingPayment ← PositionQuantity * (CumulativeFunding - CumulativeFundingEntry)`
+ - For Shorts: `FundingPayment ← PositionQuantity * (CumulativeFundingEntry - CumulativeFunding)`
+- `Margin' ← Margin + FundingPayment`
+- `CumulativeFundingEntry' ← CumulativeFunding`
## Perpetual Market Trading Specification
### Positions
-A trader's position records the conditions under which the trader has entered into the derivative contract and is defined as follows
+A trader's position records the conditions under which the trader has entered into the derivative contract and is
+defined as follows
-* Position Definition:
- * `Quantity`
- * `EntryPrice`
- * `Margin`
- * `HoldQuantity`
- * `CumulativeFundingEntry`
+- Position Definition:
+ - `Quantity`
+ - `EntryPrice`
+ - `Margin`
+ - `HoldQuantity`
+ - `CumulativeFundingEntry`
As an example, consider the following position in the ETH/USDT market:
-* `Quantity` = -2
-* `EntryPrice` = 2200
-* `Margin` = 800
-* `HoldQuantity` = 1
-* `CumulativeFundingEntry` = 4838123
+- `Quantity` = -2
+- `EntryPrice` = 2200
+- `Margin` = 800
+- `HoldQuantity` = 1
+- `CumulativeFundingEntry` = 4838123
-This position represents short exposure for 2 contracts of the ETH/USDT market collateralized with 800 USDT, with an entry price of 2200. The `HoldQuantity` represents the quantity of the position that the trader has opposing orders for. `CumulativeFundingEntry` represents the cumulative funding value that the position was last updated at.
+This position represents short exposure for 2 contracts of the ETH/USDT market collateralized with 800 USDT, with an
+entry price of 2200. The `HoldQuantity` represents the quantity of the position that the trader has opposing orders for.
+`CumulativeFundingEntry` represents the cumulative funding value that the position was last updated at.
Position Netting:
-When a new vanilla order is matched for a subaccount with an existing position, the new position will be the result from netting the existing position with the new vanilla order. A matched vanilla order produces a position delta defined by `FillQuantity`, `FillMargin` and `ClearingPrice`.
+When a new vanilla order is matched for a subaccount with an existing position, the new position will be the result from
+netting the existing position with the new vanilla order. A matched vanilla order produces a position delta defined by
+`FillQuantity`, `FillMargin` and `ClearingPrice`.
-* Applying Position Delta to a position in the same direction:
- * `Entry Price' ← (Quantity \* EntryPrice + FillQuantity \* ClearingPrice) / (Quantity + FillQuantity)`
- * `Quantity' ← Quantity + FillQuantity`
- * `Margin' ← Margin + FillMargin`
-* Apply Position Delta to a position in the opposing direction:
- * `Entry Price - no change`
- * `Quantity' ← Quantity - FillQuantity`
- * `Margin' ← Margin \* (Quantity - FillQuantity) / Quantity`
+- Applying Position Delta to a position in the same direction:
+ - `Entry Price' ← (Quantity \* EntryPrice + FillQuantity \* ClearingPrice) / (Quantity + FillQuantity)`
+ - `Quantity' ← Quantity + FillQuantity`
+ - `Margin' ← Margin + FillMargin`
+- Apply Position Delta to a position in the opposing direction:
+ - `Entry Price - no change`
+ - `Quantity' ← Quantity - FillQuantity`
+ - `Margin' ← Margin \* (Quantity - FillQuantity) / Quantity`
### Limit Buy Order
-A limit buy order seeks to purchase a specified Quantity of a derivative contract at a specified Price by providing a specified amount of margin as collateral.
+A limit buy order seeks to purchase a specified Quantity of a derivative contract at a specified Price by providing a
+specified amount of margin as collateral.
### Limit Sell Order
-A limit sell order seeks to sell a specified Quantity of a derivative contract at a specified Price by providing a specified amount of margin as collateral.
+A limit sell order seeks to sell a specified Quantity of a derivative contract at a specified Price by providing a
+specified amount of margin as collateral.
-A matched position will have **subtracted fees** which depend on whether the limit order becomes executed as a maker order or a taker order.
+A matched position will have **subtracted fees** which depend on whether the limit order becomes executed as a
+maker order or a taker order.
### Market Buy Order
-A market buy order seeks to purchase a specified Quantity of a derivative contract at a specified worst price using the subaccount's available balance as margin collateral.
+A market buy order seeks to purchase a specified Quantity of a derivative contract at a specified worst price using
+the subaccount's available balance as margin collateral.
-Handler and EndBlocker Execution of the market order are conceptually identical to the Limit Buy Order (Immediately Matched case), since the trader passes the margin which implicitly sets a maximum price limit due to the initial min margin requirements.
+Handler and EndBlocker Execution of the market order are conceptually identical to the Limit Buy Order
+(Immediately Matched case), since the trader passes the margin which implicitly sets a maximum price limit due to the
+initial min margin requirements.
### Market Sell Order
-A market sell order seeks to sell a specified Quantity of a derivative contract at a specified worst price using the subaccount's available balance as margin collateral.
+A market sell order seeks to sell a specified Quantity of a derivative contract at a specified worst price using the
+subaccount's available balance as margin collateral.
-Handler and EndBlocker Execution of the market order are conceptually identical to the Limit Sell Order (Immediately Matched case), since the trader passes the margin which implicitly sets a minimum price limit due to the initial min margin requirements.
+Handler and EndBlocker Execution of the market order are conceptually identical to the Limit Sell Order
+(Immediately Matched case), since the trader passes the margin which implicitly sets a minimum price limit due to the
+initial min margin requirements.
### Order Types
-* BUY (1): A standard buy order to purchase an asset at either the current market price or a set limit price.
-* SELL (2): A standard sell order to sell an asset at either the current market price or a set limit price.
-* STOP_BUY (3): A stop-buy order converts into a regular buy order once the oracle price reaches or surpasses a specified trigger price.
-* STOP_SELL (4): A stop-sell order becomes a regular sell order once the oracle price drops to or below a specified trigger price.
-* TAKE_BUY (5): A take-buy order converts into a regular buy order once the oracle price reaches or drops below a specified trigger price.
-* TAKE_SELL (6):A stop-sell order becomes a regular sell order once the oracle price reaches or surpasses a specified trigger price.
-* BUY_PO (7): Post-Only Buy. This order type ensures that the order will only be added to the order book and not match with a pre-existing order. It guarantees that you will be the market "maker" and not the "taker".
-* SELL_PO (8): Post-Only Sell. Similar to BUY_PO, this ensures that your sell order will only add liquidity to the order book and not match with a pre-existing order.
-* BUY_ATOMIC (9): An atomic buy order is a market order that gets executed instantly, bypassing the Frequent Batch Auctions (FBA). It's intended for smart contracts that need to execute a trade instantly. A higher fee is paid defined in the global exchange parameters.
-* SELL_ATOMIC (10): An atomic sell order is similar to a BUY_ATOMIC, and it gets executed instantly at the current market price, bypassing the FBA.
+- BUY (1): A standard buy order to purchase an asset at either the current market price or a set limit price.
+- SELL (2): A standard sell order to sell an asset at either the current market price or a set limit price.
+- STOP_BUY (3): A stop-buy order converts into a regular buy order once the oracle price reaches or surpasses a specified trigger price.
+- STOP_SELL (4): A stop-sell order becomes a regular sell order once the oracle price drops to or below a specified trigger price.
+- TAKE_BUY (5): A take-buy order converts into a regular buy order once the oracle price reaches or drops below a specified trigger price.
+- TAKE_SELL (6):A stop-sell order becomes a regular sell order once the oracle price reaches or surpasses a specified trigger price.
+- BUY_PO (7): Post-Only Buy. This order type ensures that the order will only be added to the order book and not match with a pre-existing order. It guarantees that you will be the market "maker" and not the "taker".
+- SELL_PO (8): Post-Only Sell. Similar to BUY_PO, this ensures that your sell order will only add liquidity to the order book and not match with a pre-existing order.
+- BUY_ATOMIC (9): An atomic buy order is a market order that gets executed instantly, bypassing the Frequent Batch Auctions (FBA). It's intended for smart contracts that need to execute a trade instantly. A higher fee is paid defined in the global exchange parameters.
+- SELL_ATOMIC (10): An atomic sell order is similar to a BUY_ATOMIC, and it gets executed instantly at the current market price, bypassing the FBA.
### Reduce-Only Orders (Selling Positions)
-#### Limit Buy Reduce-Only Order
+### Limit Buy Reduce-Only Order
-A limit buy reduce-only order seeks to reduce existing long exposure by a specified `Quantity` ETH (**base currency**). The payout for closing a position will have **subtracted fees**.
+A limit buy reduce-only order seeks to reduce existing long exposure by a specified `Quantity` ETH (**base currency**).
+The payout for closing a position will have **subtracted fees**.
-#### Limit Sell Reduce-Only Order
+### Limit Sell Reduce-Only Order
-A limit sell reduce-only order seeks to reduce existing short exposure by a specified `Quantity` ETH (**base currency**). The payout for closing a position will have **subtracted fees**.
+A limit sell reduce-only order seeks to reduce existing short exposure by a specified `Quantity` ETH (**base currency**).
+The payout for closing a position will have **subtracted fees**.
diff --git a/.gitbook/developers/modules/injective/exchange/01_spot_market_concepts.md b/.gitbook/developers/modules/injective/exchange/01_spot_market_concepts.md
index c7b4ee66..6d413d33 100644
--- a/.gitbook/developers/modules/injective/exchange/01_spot_market_concepts.md
+++ b/.gitbook/developers/modules/injective/exchange/01_spot_market_concepts.md
@@ -3,7 +3,7 @@ sidebar_position: 2
title: Spot Market Concepts
---
-# Spot Markets Concepts
+# Spot Market Concepts
## Definitions
@@ -11,60 +11,71 @@ In a Spot Market with ticker **AAA/BBB, AAA is the base asset, BBB is the quote
For example, in the ETH/USDT market
-* ETH is base asset
-* USDT is the quote asset
+- ETH is base asset
+- USDT is the quote asset
-The spot market's **price** refers to how much USDT (the quote asset) is required for one unit of ETH (the base asset). For all spot markets, **fees are always paid in the quote asset**, e.g., USDT.
+The spot market's **price** refers to how much USDT (the quote asset) is required for one unit of ETH (the base
+asset). For all spot markets, **fees are always paid in the quote asset**, e.g., USDT.
-**Debit vs. Credit**
+**Debit vs Credit**
-* **Debit Amount** refers to the amount of asset that is withdrawn from an account.
-* **Credit Amount** refers to the amount of asset that is deposited to an account.
+- **Debit Amount** refers to the amount of asset that is withdrawn from an account.
+- **Credit Amount** refers to the amount of asset that is deposited to an account.
**Refunds**
-In our system, a refund refers to the action of incrementing the **available balance** of an account. This liberation of funds occurs as the result of an encumbrance being lifted from the account (e.g. cancelling a limit order, reducing an order's payable fee to a maker fee, using less margin to fund a market order, etc.).
+In our system, a refund refers to the action of incrementing the **available balance** of an account. This liberation of
+funds occurs as the result of an encumbrance being lifted from the account (e.g. cancelling a limit order, reducing an
+order's payable fee to a maker fee, using less margin to fund a market order, etc.).
### Limit Buy Order
-A limit buy order seeks to buy a specified `Quantity` ETH (**base asset**) in exchange for `Quantity * Price` amount of USDT (**quote asset**) **plus fees,** which depend on whether the limit order becomes executed as a maker order or a taker order.
+A limit buy order seeks to buy a specified `Quantity` ETH (**base asset**) in exchange for `Quantity * Price` amount of
+USDT (**quote asset**) **plus fees** which depend on whether the limit order becomes executed as a maker order or a
+taker order.
### Limit Sell Order
-A limit sell order seeks to sell a specified `Quantity` ETH (**base asset**) in exchange for `Quantity * Price` amount of USDT (**quote asset**) **minus fees,** which depend on whether the limit order becomes executed as a maker order or a taker order.
+A limit sell order seeks to sell a specified `Quantity` ETH (**base asset**) in exchange for `Quantity * Price` amount
+of USDT (**quote asset**) **minus fees** which depend on whether the limit order becomes executed as a maker order or a
+taker order.
### Market Buy Order
-A market buy order seeks to buy a specified `Quantity` ETH (**base asset**) at a specified worst price which is at or near the current ask using the respective account quote asset balance (USDT) as collateral\*\* (inclusive of fees).
+A market buy order seeks to buy a specified `Quantity` ETH (**base asset**) at a specified worst price which is at or near
+the current ask using the respective account quote asset balance (USDT) as collateral\*\* (inclusive of fees).
-As a result, each market buy order implicitly has a maximum acceptable price associated with it, as filling the market order beyond that price would simply fail due to a lack of funds.
+As a result, each market buy order implicitly has a maximum acceptable price associated with it, as filling the market
+order beyond that price would simply fail due to a lack of funds.
### Market Sell Order
-A market sell order seeks to sell a specified `Quantity` ETH (**base asset**) at a specified worst price which is at or near the current bid in exchange for any amount of the quote asset (USDT) available in the market.
+A market sell order seeks to sell a specified `Quantity` ETH (**base asset**) at a specified worst price which is at or
+near the current bid in exchange for any amount of the quote asset (USDT) available in the market.
As a result, each market sell order implicitly has a zero price associated with it.
### Order Types
-* BUY (1): A standard buy order to purchase an asset at either the current market price or a set limit price.
-* SELL (2): A standard sell order to sell an asset at either the current market price or a set limit price.
-* STOP_BUY (3): This order type is not supported for spot markets.
-* STOP_SELL (4): This order type is not supported for spot markets.
-* TAKE_BUY (5): This order type is not supported for spot markets.
-* TAKE_SELL (6): This order type is not supported for spot markets.
-* BUY_PO (7): Post-Only Buy. This order type ensures that the order will only be added to the order book and not match with a pre-existing order. It guarantees that you will be the market "maker" and not the "taker".
-* SELL_PO (8): Post-Only Sell. Similar to BUY_PO, this ensures that your sell order will only add liquidity to the order book and not match with a pre-existing order.
-* BUY_ATOMIC (9): An atomic buy order is a market order that gets executed instantly, bypassing the Frequent Batch Auctions (FBA). It's intended for smart contracts that need to execute a trade instantly. A higher fee is paid, defined in the global exchange parameters.
-* SELL_ATOMIC (10): An atomic sell order is similar to a BUY_ATOMIC, and it gets executed instantly at the current market price, bypassing the FBA.
+- BUY (1): A standard buy order to purchase an asset at either the current market price or a set limit price.
+- SELL (2): A standard sell order to sell an asset at either the current market price or a set limit price.
+- STOP_BUY (3): This order type is not supported for spot markets.
+- STOP_SELL (4): This order type is not supported for spot markets.
+- TAKE_BUY (5): This order type is not supported for spot markets.
+- TAKE_SELL (6): This order type is not supported for spot markets.
+- BUY_PO (7): Post-Only Buy. This order type ensures that the order will only be added to the order book and not match with a pre-existing order. It guarantees that you will be the market "maker" and not the "taker".
+- SELL_PO (8): Post-Only Sell. Similar to BUY_PO, this ensures that your sell order will only add liquidity to the order book and not match with a pre-existing order.
+- BUY_ATOMIC (9): An atomic buy order is a market order that gets executed instantly, bypassing the Frequent Batch Auctions (FBA). It's intended for smart contracts that need to execute a trade instantly. A higher fee is paid defined in the global exchange parameters.
+- SELL_ATOMIC (10): An atomic sell order is similar to a BUY_ATOMIC, and it gets executed instantly at the current market price, bypassing the FBA.
### Market Data Requirements
-Orderbook data aside, so long as our Chain supports the **base capability** to obtain Tick by Tick trading data, aggregations can be applied to obtain most of the necessary higher order data, including
+Orderbook data aside, so long as our Chain supports the **base capability** to obtain Tick by Tick trading data,
+aggregations can be applied to obtain most of the necessary higher order data, including
-* OHLCV data
-* Account Trading History
-* Market Statistics
+- OHLCV data
+- Account Trading History
+- Market Statistics
## Spot Market Lifecycle
@@ -74,9 +85,10 @@ A market is first created either by the instant launch functionality through `Ms
### Listing Fee based Spot Market Creation
-Allow anyone to create an active spot market of their choice without requiring governance approval by burning a pre-set SpotMarketInstantListingFee of INJ.
+Allow anyone to create an active spot market of their choice without requiring governance approval by burning a pre-set
+SpotMarketInstantListingFee of INJ.
-We should still check that the denom is valid, though.
+We should still check that the denom is valid though.
### Spot Market Status Update
@@ -89,15 +101,17 @@ A Spot Market can exist in four different states:
#### **Active State**
-If a spot market is in an active state, it can accept orders and trades.
+If a spot market is an active state, it can accept orders and trades.
#### Paused State
-If a spot market is in a paused state, it will no longer accept orders and trades and will also not allow any users to take actions on that market (no order cancellations).
+If a spot market is a paused state, it will no longer accept orders and trades and will also not allow any users to take
+actions on that market (no order cancellations).
#### Suspended State
-If a spot market is in a suspended state, it will no longer accept orders and trades, and will only allow traders to cancel their orders.
+If a spot market is a suspended state, it will no longer accept orders and trades, and will only allow traders to cancel
+their orders.
## Demolished State
@@ -107,15 +121,15 @@ When a market becomes demolished, all outstanding orders are cancelled.
There are three state transitions that correspond to the following status changes
-* Activate Action - **Paused or Suspended Status → Active Status**
-* Pause Action - **Active or Suspended Status → Paused Status**
-* Suspend Action - **Active or Paused Status → Suspended Status**
-* Demolish Action - **Paused or Suspended Status → Demolished Status**
+- Activate Action - **Paused or Suspended Status → Active Status**
+- Pause Action - **Active or Suspended Status → Paused Status**
+- Suspend Action - **Active or Paused Status → Suspended Status**
+- Demolish Action - **Paused or Suspended Status → Demolished Status**
### Spot Market Parameter Update
The following parameters exist for Spot Markets
-* SpotMarketInstantListingFee
-* DefaultSpotMakerFeeRate
-* DefaultSpotTakerFeeRate
+- SpotMarketInstantListingFee
+- DefaultSpotMakerFeeRate
+- DefaultSpotTakerFeeRate
diff --git a/.gitbook/developers/modules/injective/exchange/02_binary_options_markets.md b/.gitbook/developers/modules/injective/exchange/02_binary_options_markets.md
index e3af04d6..8e9dc11f 100644
--- a/.gitbook/developers/modules/injective/exchange/02_binary_options_markets.md
+++ b/.gitbook/developers/modules/injective/exchange/02_binary_options_markets.md
@@ -3,7 +3,7 @@ sidebar_position: 2
title: Binary Options Markets
---
-# Binary Option Markets Concepts
+# Binary Options Markets
## Concept
@@ -11,34 +11,33 @@ Binary options markets don't have base asset as other markets do, and they are q
For all binary options markets, **fees are always paid in the quote asset**, e.g., USDT.
-There is no leverage in these type of markets, as users trade against each other in a zero-sum market. From this the other requirement is implied: if one side of a bet believes the event will occur (YES side), and current market probability for this exact event is _P_ (which means the current market price is _P_), opposing side of the bet should be certain that the event will not happen with _(1-P)_ probability. Thus, if the person on YES side buys _Q_ number of contracts with the price _P_, he locks _Q\*P_ of his balance as his margin, while opposing NO side (seller side) should lock _Q\*(1-P)_ of his quote balance as margin.
+There is no leverage in these type of markets, as users trade against each other in a zero-sum market. From this the other requirement is implied: if one side of a bet believes the event will occur (YES side), and current market probability for this exact event is *P* (which means the current market price is *P*), opposing side of the bet should be certain that the event will not happen with *(1-P)* probability. Thus, if the person on YES side buys *Q* number of contracts with the price *P*, he locks *Q\*P* of his balance as his margin, while opposing NO side (seller side) should lock *Q\*(1-P)* of his quote balance as margin.
**Example:**
Alice buys 1 contract at $0.20 (margined with $0.20) against Bob who sells 1 contract at $0.20 (margined with $0.80), creating positions for both of them.
-* Alice wins $0.80 if the market settles at $1 and Bob wins $0.2 if the market settles at $0.
+- Alice wins $0.80 if the market settles at $1 and Bob wins $0.2 if the market settles at $0.
## Oracle
-Binary options markets are tightly coupled to the Provider Oracle type, which allows a governance-registered provider to relay price feed data for arbitrary new price feeds under the provider's subtype without the need for extra governance for adding successively new price feeds. Each binary options market comprises the following oracle parameters:
-
-* Oracle symbol (e.g., UFC-KHABIB-TKO-09082022)
-* Oracle provider (e.g., frontrunner)
+Binary options markets are tightly coupled to the Provider Oracle type, which allows a governance-registered provider to relay price feed data for arbitrary new price feeds under the provider's subtype without the need for extra governance for adding successively new price feeds. Each binary options market is comprised of the following oracle parameters:
+* Oracle symbol (e.g. UFC-KHABIB-TKO-09082022)
+* Oracle provider (e.g. frontrunner)
* Oracle type (required to be provider)
-* Oracle scale factor (e.g., 6 if the quote denom is USDT)
+* Oracle scale factor (e.g. 6 if the quote denom is USDT)
The main goal of the oracle is to post the final outcome of the event. This final price settles the market at that exact price. This price is expected to be equal to be 0 or 1 most of the time, reflective of the binary outcome.
-Moreover, the market could be settled at any price within the (0, 1) price band. In case the _settlement_price_ posted by oracle is between 0 or 1, all positions will be closed at the _settlement_price_ (e.g., 0.42). If the oracle price exceeds 1, the settlement price will be rounded down to 1.
+Moreover, the market could be settled at any price within the (0, 1) price band. In case the *settlement_price* posted by oracle is between 0 or 1, all positions will be closed at the *settlement_price* (e.g. 0.42). If the oracle price exceeds 1, the settlement price will be rounded down to 1.
-Oracle can also post the final price of **-1**, which is the flag price that triggers refunding of all positions in the current market and demolishes the market. If there is no oracle update ever prior to settlement, then an oracle price of -1 will be used by default to trigger the refunds of all positions.
+Oracle can also post the final price of **-1**, which is the flag price than triggers refunding of all positions in the current market and demolishes the market. If there is no oracle update ever prior to settlement, then an oracle price of -1 will be used by default to trigger the refunds of all positions.
-Further documentation on the oracle provider type can be found in the Oracle module documentation.
+Further documentation on the oracle provider type can be found in the Oracle module documentation.
### Registering an oracle provider
-To register your oracle provider, you need to submit a `GrantProviderPrivilegeProposal` governance proposal. This proposal will register your provider and will allow your address to relay price feeds.
+To register your oracle provider, you need to submit a `GrantProviderPrivilegeProposal` governance proposal. This proposal will register your provider and will allow your address to relay price feeds.
```go
type GrantProviderPrivilegeProposal struct {
@@ -49,42 +48,39 @@ type GrantProviderPrivilegeProposal struct {
}
```
-Once the proposal passes, your provider will be registered, and you'll be able to relay your price feeds (example below).
+Once the proposal passes, your provider will be registered and you'll be able to relay your price feeds (example below).
## Market Lifecycle
### Market Creation
+A binary options market can be created through an instant launch (through a `MsgInstantBinaryOptionsMarketLaunch`) or through governance (through a `BinaryOptionsMarketLaunchProposal`).
-A binary options market can be created through an instant launch (through a `MsgInstantBinaryOptionsMarketLaunch`) or through governance (through a `BinaryOptionsMarketLaunchProposal`).
-
-The market may be optionally configured with a market admin which has the ability to trigger settlement, change the market status as well as modify the expiration and settlement timestamp of the given market. If the market does not specify an admin, then the market parameters can only be modified through governance and that the settlement procedure will be fully based on the associated oracle provider price feed.
+The market may be optionally configured with a market admin which has the ability to trigger settlement, change the market status as well as modify the expiration and settlement timestamp of the given market. If the market does not specify an admin, then the market parameters can only be modified through governance and that the settlement procedure will be fully based on the associated oracle provider price feed.
### Market State Transitions
-
Binary options markets can take one of three statuses on Injective: Active, Expired or Demolished. After the market is created, the market has an `Active` status, which signifies that individuals can begin trading.
-Pertinently, binary options markets also have a characteristic `ExpirationTimestamp` which specifies the deadline at which trading activity for the market ceases, as well as a `SettlementTimestamp`, which specifies the deadline at which settlement will occur by (which must be after expiration).
+Pertinently, binary options markets also have a characteristic `ExpirationTimestamp` which specifies the deadline at which trading activity for the market ceases as well as a `SettlementTimestamp` which specifies the deadline at which settlement will occur by (which must be after expiration).
* **Active** = trading is open
-* **Expired** = trading is closed, open orders are cancelled, no change to positions.
+* **Expired** = trading is closed, open orders are cancelled, no change to positions.
* **Demolished** = positions are settled / refunded (depending on the settlement), market is demolished
The nature of the status transitions for binary options markets are as follows:
-| Status Change | Workflow |
-| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| Active → Expired | Expiration is part of the standard workflow for a market. Trading is halted immediately for the market and all open orders are cancelled. The market can now be settled immediately (forcefully) by the admin or oracle or be settled naturally using the latest oracle price when we reach SettlementTimestamp. |
-| Expired → Demolished (Settlement) | All positions are settled at either the price set by forceful settlement or natural settlement. The market can never be traded on or reactivated again. For natural settlement, upon the SettlementTimestamp time, the last oracle price is recorded and used for settlement. For ‘force-settle’, Admin should post the MarketUpdate msg with SettlementPrice in it being set in a price band of \[0, 1]. |
-| Active/Expired → Demolished (Refund) | All positions get refunded. The market can never be traded on or reactivated again. Admin should post the MarketUpdate msg with SettlementPrice in it being set to -1. |
+| Status Change | Workflow |
+| --- | --- |
+| Active → Expired | Expiration is part of the standard workflow for a market. Trading is halted immediately for the market and all open orders are cancelled. The market can now be settled immediately (forcefully) by the admin or oracle or be settled naturally using the latest oracle price when we reach SettlementTimestamp.
+| Expired → Demolished (Settlement) | All positions are settled at either the price set by forceful settlement or natural settlement. The market can never be traded on or reactivated again. For natural settlement, upon the SettlementTimestamp time, the last oracle price is recorded and used for settlement. For ‘force-settle’, Admin should post the MarketUpdate msg with SettlementPrice in it being set in a price band of [0, 1].
+| Active/Expired → Demolished (Refund) | All positions get refunded. The market can never be traded on or reactivated again. Admin should post the MarketUpdate msg with SettlementPrice in it being set to -1. |
-### Market Settlement
-The settlement price options are explained above in the [oracle](02_binary_options_markets.md#oracle) section.
-
-Settling a market can be achieved using one of these two options:
+### Market Settlement
-1. Using the registered provider oracle for the particular market. Once the provider oracle is granted privileges to relay prices (explained above), the address with the privileges can relay prices for a particular price feed using the `MsgRelayProviderPrices` message.
+The settlement price options are explained above in the [oracle](#oracle) section.
+Settling a market can be achieved using one of these two options:
+1. Using the registered provider oracle for the particular market. Once the provider oracle is granted privileges to relay prices (explained above), the address with the privileges can relay prices for a particular price feed using the `MsgRelayProviderPrices` message.
```go
// MsgRelayProviderPrices defines a SDK message for setting a price through the provider oracle.
type MsgRelayProviderPrices struct {
@@ -95,8 +91,7 @@ type MsgRelayProviderPrices struct {
}
```
-2. Using the `MsgAdminUpdateBinaryOptionsMarket` which allows the market's admin (creator) to submit a settlement price directly to the market.
-
+2. Using the `MsgAdminUpdateBinaryOptionsMarket` which allows the market's admin (creator) to submit a settlement price directly to the market.
```go
type MsgAdminUpdateBinaryOptionsMarket struct {
// new price at which market will be settled
diff --git a/.gitbook/developers/modules/injective/exchange/02_other_concepts.md b/.gitbook/developers/modules/injective/exchange/02_other_concepts.md
index 4aed628e..e971f931 100644
--- a/.gitbook/developers/modules/injective/exchange/02_other_concepts.md
+++ b/.gitbook/developers/modules/injective/exchange/02_other_concepts.md
@@ -7,24 +7,27 @@ title: Other Concepts
## Concurrency-Friendly Market Order Clearing Price Algorithm
-We apply the [split-apply-combine](https://stackoverflow.com/tags/split-apply-combine/info) paradigm to leverage concurrency for efficient data processing.
+We apply the [split-apply-combine](https://stackoverflow.com/tags/split-apply-combine/info) paradigm to leverage
+concurrency for efficient data processing.
1. Match all matchable orders (see order matching for details) concurrently in all markets.
-* The intermediate result is a clearing price and a list of matched orders with their fill quantities.
-* The final result is a temporary cache of all new events and all changes to positions, orders, subaccount deposits, trading reward points and fees paid.
+- The intermediate result is a clearing price and a list of matched orders with their fill quantities.
+- The final result is a temporary cache of all new events and all changes to positions, orders, subaccount deposits,
+ trading reward points and fees paid.
2. Wait for execution on all markets and persist all data.
-Note: beyond just executing settlement, the design must also take into account market data dissemination requirements for off-chain consumption.
+Note: beyond just executing settlement, the design must also take into account market data dissemination requirements
+for off-chain consumption.
## Atomic Market Order Execution
A common request from new applications built on Cosmwasm is for the ability to be notified upon the execution of an order. In the regular order execution flow, this would not be possible, since the Frequent Batch Auctions (FBA) are executed inside the EndBlocker. To circumvent the FBA, the new type of atomic market orders is introduced. For the privilege of executing such an atomic market order instantly, an additional trading fee is imposed. To calculate the fee of an atomic market order, the market's taker fee is multiplied by the market types's `AtomicMarketOrderFeeMultiplier`.
-* `SpotAtomicMarketOrderFeeMultiplier`
-* `DerivativeAtomicMarketOrderFeeMultiplier`
-* `BinaryOptionsAtomicMarketOrderFeeMultiplier`
+- `SpotAtomicMarketOrderFeeMultiplier`
+- `DerivativeAtomicMarketOrderFeeMultiplier`
+- `BinaryOptionsAtomicMarketOrderFeeMultiplier`
These multipliers are defined the global exchange parameters. In addition, the exchange parameters also define the `AtomicMarketOrderAccessLevel` which specifies the minimum access level required to execute an atomic market order.
@@ -41,17 +44,17 @@ const (
Governance approves a **TradingRewardCampaignLaunchProposal** which specifies:
-* The first campaign's starting timestamp
-* The **TradingRewardCampaignInfo** which specifies
- * The campaign duration in seconds
- * The accepted trading fee quote currency denoms
- * The optional market-specific **boost** info
- * The disqualified marketIDs for markets in which trades will not earn rewards
-* The **CampaignRewardPools** which specifies the maximum epoch rewards that constitute the trading rewards pool for each successive campaign
+- The first campaign's starting timestamp
+- The **TradingRewardCampaignInfo** which specifies
+ - The campaign duration in seconds
+ - The accepted trading fee quote currency denoms
+ - The optional market-specific **boost** info
+ - The disqualified marketIDs for markets in which trades will not earn rewards
+- The **CampaignRewardPools** which specifies the maximum epoch rewards that constitute the trading rewards pool for each successive campaign
During a given campaign, the exchange will record each trader's cumulative trading reward points obtained from trading volume (with boosts applied, if applicable) from all eligible markets, i.e., markets with a matching quote currency that are not in the disqualified list.
-At the end of each campaign, i.e., after the `campaign starting timestamp + campaign duration` has elapsed, each trader will receive a pro rata percentage of the trading rewards pool based off their trading rewards points from that campaign epoch.
+At the end of each campaign, i.e., after the `campaign starting timestamp + campaign duration` has elapsed, each trader will receive a pro-rata percentage of the trading rewards pool based off their trading rewards points from that campaign epoch.
Campaigns will not auto-rollover. If there are no additional campaigns defined inside **CampaignRewardPools**, the trading reward campaigns will finish.
@@ -59,8 +62,8 @@ Campaigns will not auto-rollover. If there are no additional campaigns defined i
Governance approves a **FeeDiscountProposal** which defines a fee discount **schedule** which specifies fee discount **tiers** which each specify the maker and taker discounts rates a trader will receive if they satisfy the specified minimum INJ staked amount AND have had at least the specified trading volume (based on the specified **quote denoms**) over the specified time period (`bucket count * bucket duration seconds`, which should equal 30 days). The schedule also specifies a list of disqualified marketIDs for markets whose trading volume will not count towards the volume contribution.
-* Spot markets where the base and quote are both in the accepted quote currencies list will not be rewarded (e.g., the USDC/USDT spot market).
-* Maker fills in markets with negative maker fees will NOT give the trader any fee discounts.
-* 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.
+- Spot markets where the base and quote are both in the accepted quote currencies list will not be rewarded (e.g. the USDC/USDT spot market).
+- Maker fills in markets with negative maker fees will NOT give the trader any fee discounts.
+- 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.
+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.
diff --git a/.gitbook/developers/modules/injective/exchange/03_state.md b/.gitbook/developers/modules/injective/exchange/03_state.md
index 84b1ff4b..719cc7b2 100644
--- a/.gitbook/developers/modules/injective/exchange/03_state.md
+++ b/.gitbook/developers/modules/injective/exchange/03_state.md
@@ -61,7 +61,8 @@ type GenesisState struct {
## Params
-`Params` is a module-wide configuration that stores system parameters and defines overall functioning of the exchange module. This configuration is modifiable by governance using params update proposal natively supported by `gov` module.
+`Params` is a module-wide configuration that stores system parameters and defines overall functioning of the exchange module.
+This configuration is modifiable by governance using params update proposal natively supported by `gov` module.
It defines default fee objects to be used for spot and derivative markets and funding parameters for derivative markets and instant listing fees.
@@ -183,7 +184,8 @@ type MarketOrderIndicator struct {
## SpotMarket
-`SpotMarket` is the structure to store all the required information and state for a spot market. Spot markets are stored by hash of the market to query the market efficiently.
+`SpotMarket` is the structure to store all the required information and state for a spot market.
+Spot markets are stored by hash of the market to query the market efficiently.
```go
// An object describing trade pair of two assets.
@@ -213,7 +215,8 @@ type SpotMarket struct {
## SpotOrderBook
-`SpotOrderBook` is a structure to store spot limit orders for a specific market. Two objects are created, one for buy orders and one for sell orders.
+`SpotOrderBook` is a structure to store spot limit orders for a specific market.
+Two objects are created, one for buy orders and one for sell orders.
```go
// Spot Exchange Limit Orderbook
@@ -258,7 +261,8 @@ type SpotMarketOrder struct {
## DerivativeMarket
-`DerivativeMarket` is the structure to store all the required information and state for a derivative market. Derivative markets are stored by hash of the market to query the market efficiently.
+`DerivativeMarket` is the structure to store all the required information and state for a derivative market.
+Derivative markets are stored by hash of the market to query the market efficiently.
```go
// An object describing a derivative market in the Injective Futures Protocol.
@@ -300,7 +304,8 @@ type DerivativeMarket struct {
## DerivativeOrderBook
-`DerivativeOrderBook` is a structure to store derivative limit orders for a specific market. Two objects are created, one for buy orders and one for sell orders.
+`DerivativeOrderBook` is a structure to store derivative limit orders for a specific market.
+Two objects are created, one for buy orders and one for sell orders.
```go
// Spot Exchange Limit Orderbook
@@ -361,9 +366,7 @@ type DerivativeMarketOrderCancel struct {
`DerivativePosition` is a structure to store derivative positions for a subaccount on a specific market.
-{% hint style="info" %}
**Note:** Derivative orders represent intent while positions represent possession.
-{% endhint %}
```go
type Position struct {
@@ -395,7 +398,8 @@ type SubaccountPosition struct {
## ExpiryFuturesMarketInfo
-`ExpiryFuturesMarketInfo` is a structure to keep the information of expiry futures market. It is stored by the id of the market.
+`ExpiryFuturesMarketInfo` is a structure to keep the information of expiry futures market.
+It is stored by the id of the market.
```go
type ExpiryFuturesMarketInfo struct {
diff --git a/.gitbook/developers/modules/injective/exchange/04_state_transitions.md b/.gitbook/developers/modules/injective/exchange/04_state_transitions.md
index 639fb152..99b858ee 100644
--- a/.gitbook/developers/modules/injective/exchange/04_state_transitions.md
+++ b/.gitbook/developers/modules/injective/exchange/04_state_transitions.md
@@ -7,67 +7,63 @@ title: State Transitions
This document describes the state transition operations pertaining to:
-* Deposit into exchange module account
-* Withdraw from exchange module account
-* Instant spot market launch
-* Instant perpetual market launch
-* Instant expiry futures market launch
-* Spot limit order creation
-* Batch creation of spot limit orders
-* Spot market order creation
-* Cancel spot order
-* Batch cancellation of spot order
-* Derivative limit order creation
-* Batch derivative limit order creation
-* Derivative market order creation
-* Cancel derivative order
-* Batch cancellation of derivative orders
-* Transfer between subaccounts
-* Transfer to external account
-* Liquidating a position
-* Increasing position margin
-* Spot market param update proposal
-* Exchange enable proposal
-* Spot market launch proposal
-* Perpetual market launch proposal
-* Expiry futures market launch proposal
-* Derivative market param update proposal
-* Trading rewards launch proposal
-* Trading rewards update proposal
-* Begin-blocker
-* End-blocker
+- Deposit into exchange module account
+- Withdraw from exchange module account
+- Instant spot market launch
+- Instant perpetual market launch
+- Instant expiry futures market launch
+- Spot limit order creation
+- Batch creation of spot limit orders
+- Spot market order creation
+- Cancel spot order
+- Batch cancellation of spot order
+- Derivative limit order creation
+- Batch derivative limit order creation
+- Derivative market order creation
+- Cancel derivative order
+- Batch cancellation of derivative orders
+- Transfer between subaccounts
+- Transfer to external account
+- Liquidating a position
+- Increasing position margin
+- Spot market param update proposal
+- Exchange enable proposal
+- Spot market launch proposal
+- Perpetual market launch proposal
+- Expiry futures market launch proposal
+- Derivative market param update proposal
+- Trading rewards launch proposal
+- Trading rewards update proposal
+- Begin-blocker
+- End-blocker
## Deposit into exchange module account
Deposit action is carried out by `MsgDeposit` which consists of `Sender`, `SubaccountId` and `Amount` fields.
-{% hint style="info" %}
**Note:** `SubaccountId` is optional and if it's not available, it's calculated dynamically from `Sender` address.
-{% endhint %}
**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`
+- 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 from exchange module account
Withdraw action is carried out by `MsgWithdraw` which consists of `Sender`, `SubaccountId` and `Amount` fields.
-{% hint style="info" %}
**Note:** The ownership of `msg.SubaccountId` by `msg.Sender` is validated on `msg.ValidateBasic` function.
-{% endhint %}
**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`
+- 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
@@ -75,11 +71,11 @@ Instant spot market launch action is carried out by `MsgInstantSpotMarketLaunch`
**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
+- 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
@@ -87,11 +83,11 @@ Instant perpetual market launch action is carried out by `MsgInstantPerpetualMar
**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
+- 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
@@ -99,12 +95,12 @@ Instant expiry futures market launch action is carried out by `MsgInstantExpiryF
**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
+- 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
## Spot limit order creation
@@ -112,18 +108,16 @@ Spot limit order creation is carried out by `MsgCreateSpotLimitOrder` which cons
**Steps**
-* Check spot exchange is enabled to make an order on spot market and if not revert
-* Check order's price and quantity tick sizes fits market's min quantity and price tick size
-* Increment subaccount's `TradeNonce`
-* Reject if spot market id does not reference an active spot market
-* Calculate unique order hash with `TradeNonce`
-* Reject if the subaccount's available deposits does not have at least the required funds for the trade
-* Decrement the available balance by the funds amount needed to fund the order
-* Store the order in the transient limit order store and transient market indicator store
+- Check spot exchange is enabled to make an order on spot market and if not revert
+- Check order's price and quantity tick sizes fits market's min quantity and price tick size
+- Increment subaccount's `TradeNonce`
+- Reject if spot market id does not reference an active spot market
+- Calculate unique order hash with `TradeNonce`
+- Reject if the subaccount's available deposits does not have at least the required funds for the trade
+- Decrement the available balance by the funds amount needed to fund the order
+- Store the order in the transient limit order store and transient market indicator store
-{% hint style="info" %}
**Note:** The order in transient store is executed on endblocker or if not, put on long-live store.
-{% endhint %}
## Batch creation of spot limit orders
@@ -131,7 +125,7 @@ Batch creation of spot limit orders is carried out by `MsgBatchCreateSpotLimitOr
**Steps**
-* Loop over the `msg.Orders` and create spot limit order as in `MsgCreateSpotLimitOrder`
+- Loop over the `msg.Orders` and create spot limit order as in `MsgCreateSpotLimitOrder`
## Spot market order creation
@@ -139,15 +133,15 @@ Spot market order creation is carried out by `MsgCreateSpotMarketOrder` which co
**Steps**
-* Check spot exchange is enabled to make an order on spot market and if not revert
-* Check order's price and quantity tick sizes fits market's min quantity and price tick size
-* Increment subaccount's `TradeNonce`
-* Reject if spot market id does not reference an active spot market
-* Calculate unique order hash with `TradeNonce`
-* Check available balance to fund the market order
-* Calculate the worst acceptable price for the market order
-* Decrement deposit's AvailableBalance by the balance hold
-* Store the order in the transient spot market order store and transient market indicator store
+- Check spot exchange is enabled to make an order on spot market and if not revert
+- Check order's price and quantity tick sizes fits market's min quantity and price tick size
+- Increment subaccount's `TradeNonce`
+- Reject if spot market id does not reference an active spot market
+- Calculate unique order hash with `TradeNonce`
+- Check available balance to fund the market order
+- Calculate the worst acceptable price for the market order
+- 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
@@ -155,13 +149,13 @@ Spot order cancellation is carried out by `MsgCancelSpotOrder` which consists of
**Steps**
-* Check spot exchange is enabled to execute the action and if not revert
-* Reject if spot market id does not reference an active, suspended or demolished spot market
-* Check spot limit order exists by `marketID`, `subaccountID` and `orderHash`
-* Add back the margin hold to available balance
-* Increment the available balance margin hold
-* Delete the order state from ordersStore and ordersIndexStore
-* Emit `EventCancelSpotOrder` event with marketID and order info
+- Check spot exchange is enabled to execute the action and if not revert
+- Reject if spot market id does not reference an active, suspended or demolished spot market
+- Check spot limit order exists by `marketID`, `subaccountID` and `orderHash`
+- Add back the margin hold to available balance
+- Increment the available balance margin hold
+- Delete the order state from ordersStore and ordersIndexStore
+- Emit `EventCancelSpotOrder` event with marketID and order info
## Batch cancellation of spot orders
@@ -169,7 +163,7 @@ Batch cancellation of spot orders is carried out by `MsgBatchCancelSpotOrders` w
**Steps**
-* Loop over the `msg.Data` and cancel spot order as in `MsgCancelSpotOrder`
+- Loop over the `msg.Data` and cancel spot order as in `MsgCancelSpotOrder`
## Derivative limit order creation
@@ -177,22 +171,22 @@ Derivative limit order creation is carried out by `MsgCreateDerivativeLimitOrder
**Steps**
-* Check derivative exchange is enabled to make an order on derivative market and if not revert
-* Reject if market order is already placed on the market by `subaccountID` (**Note:** Can't the market order and limit order core exist?)
-* Get derivative market and markPrice by `marketID`
-* Get orderbook metadata (`SubaccountOrderbookMetadata`) the for specified `marketID` and `subaccountID`
-* Ensure limit order is valid:
- * Market config (market id and tick sizes)
- * Subaccount trade nonce
- * Subaccount max order count
- * If reduce-only order:
- * Position with valid quantity and opposite direction exists
- * If order would result in other reduce-only orders becoming stale, reject it
- * If limit order:
- * Enough subaccount deposits for margin hold
- * If order is in opposite direction of existing position and results in other reduce-only orders becoming stale, cancel the stale reduce-only orders
-* Store the order in the transient limit order store and transient market indicator store
-* Update orderbook metadata for subaccount
+- Check derivative exchange is enabled to make an order on derivative market and if not revert
+- Reject if market order is already placed on the market by `subaccountID` (**Note:** Can't the market order and limit order core exist?)
+- Get derivative market and markPrice by `marketID`
+- Get orderbook metadata (`SubaccountOrderbookMetadata`) the for specified `marketID` and `subaccountID`
+- Ensure limit order is valid:
+ - Market config (market id and tick sizes)
+ - Subaccount trade nonce
+ - Subaccount max order count
+ - If reduce-only order:
+ - Position with valid quantity and opposite direction exists
+ - If order would result in other reduce-only orders becoming stale, reject it
+ - If limit order:
+ - Enough subaccount deposits for margin hold
+ - If order is in opposite direction of existing position and results in other reduce-only orders becoming stale, cancel the stale reduce-only orders
+- 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
@@ -200,7 +194,7 @@ Batch creation of derivative limit orders is carried out by `MsgBatchCreateDeriv
**Steps**
-* Loop over the `msg.Orders` and create derivative limit order as in `MsgCreateDerivativeLimitOrder`
+- Loop over the `msg.Orders` and create derivative limit order as in `MsgCreateDerivativeLimitOrder`
## Derivative market order creation
@@ -208,35 +202,25 @@ Derivative market order creation is carried out by `MsgCreateDerivativeMarketOrd
**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:
-
-1. 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\
-
-2. 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
+- 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
+- 1. 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
+- 2. 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
## Cancel derivative order
@@ -244,14 +228,14 @@ Derivative order cancellation is carried out by `MsgCancelDerivativeOrder` which
**Steps**
-* Check derivative exchange is enabled to execute the operation and if not revert
-* Reject if derivative market id does not reference an active derivative market
-* Check resting derivative limit order exists by `marketID`, `subaccountID` and `orderHash`
-* Add back the margin hold to available balance
-* Skip cancelling limit orders if their type shouldn't be cancelled
-* Delete the order state from ordersStore, ordersIndexStore and subaccountOrderStore
-* Update orderbook metadata for subaccount
-* Emit `EventCancelDerivativeOrder` event with marketID and order info
+- Check derivative exchange is enabled to execute the operation and if not revert
+- Reject if derivative market id does not reference an active derivative market
+- Check resting derivative limit order exists by `marketID`, `subaccountID` and `orderHash`
+- Add back the margin hold to available balance
+- Skip cancelling limit orders if their type shouldn't be cancelled
+- Delete the order state from ordersStore, ordersIndexStore and subaccountOrderStore
+- Update orderbook metadata for subaccount
+- Emit `EventCancelDerivativeOrder` event with marketID and order info
## Batch cancellation of derivative orders
@@ -259,7 +243,7 @@ Batch cancellation of derivative orders is carried out by `MsgBatchCancelDerivat
**Steps**
-* Loop over the `msg.Data` and cancel spot order as in `MsgCancelDerivativeOrder`
+- Loop over the `msg.Data` and cancel spot order as in `MsgCancelDerivativeOrder`
## Batch order updates
@@ -267,11 +251,11 @@ Batch updating orders is carried out by `MsgBatchUpdateOrders` which consists of
**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`.
+- 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
@@ -279,13 +263,11 @@ Transfer between subaccounts is executed by `MsgSubaccountTransfer` which consis
**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`
+- 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`
-{% hint style="info" %}
**Note:** With subaccount transfer, no need to transfer actual coins from bank module but changing the records are enough.
-{% endhint %}
## Transfer to external account
@@ -293,9 +275,9 @@ Transfer to external account is executed by `MsgExternalTransfer` which consists
**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`
+- 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.
@@ -308,30 +290,30 @@ Liquidating a position is executed by `MsgLiquidatePosition` which consists of `
**Steps**
-* Check derivative exchange is enabled to liquidate a position on derivative market and if not revert
-* Reject if derivative market id does not reference an active derivative market
-* Get derivative market and markPrice by `marketID`
-* Get position for `marketID` and `subaccountID`
-* Calculate `liquidationPrice` and `bankruptcyPrice` from the position info
-* Determine vaporize or liquidate and if not all of them, revert
-* Cancel all reduce-only limit orders created by the position holder in the given market
-* Apply funding and update position
-* Cancel all market orders created by the position holder in the given market
-* Check and increment subaccount nonce, compute order hash
-* Calculate `liquidationOrder` hash
-* Set the liquidation order into the storage
-* Execute liquidation by matching position and liquidation order
-* Handle differently based on the payout is positive or negative (insurance fund is involved here in calculation)
- * Positive Payout:
+- Check derivative exchange is enabled to liquidate a position on derivative market and if not revert
+- Reject if derivative market id does not reference an active derivative market
+- Get derivative market and markPrice by `marketID`
+- Get position for `marketID` and `subaccountID`
+- Calculate `liquidationPrice` and `bankruptcyPrice` from the position info
+- Determine vaporize or liquidate and if not all of them, revert
+- Cancel all reduce-only limit orders created by the position holder in the given market
+- Apply funding and update position
+- Cancel all market orders created by the position holder in the given market
+- Check and increment subaccount nonce, compute order hash
+- Calculate `liquidationOrder` hash
+- Set the liquidation order into the storage
+- Execute liquidation by matching position and liquidation order
+- Handle differently based on the payout is positive or negative (insurance fund is involved here in calculation)
+ - Positive Payout:
1. Send half of the payout to liquidator (incentive for running liquidator bots)
2. Send the other half to the insurance fund (incentive for participating in insurance funds)
- * Negative Payout - Four levels of escalation to retrieve the funds:
+ - Negative Payout - Four levels of escalation to retrieve the funds:
1. From trader's available balance
2. From trader's locked balance by cancelling his vanilla limit orders
3. From the insurance fund
4. Not enough funds available. Pause the market and add markets to the storage to be settled in next block, see `BeginBlocker` specs.
-* 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
+- 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
@@ -339,13 +321,13 @@ Increasing position margin is executed by `MsgIncreasePositionMargin` which cons
**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
+- 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
## Exchange enable proposal
@@ -353,9 +335,9 @@ The enable of market type is done by `ExchangeEnableProposal` which consists of
**Steps**
-* `ValidateBasic` for proposal
-* If `p.ExchangeType` is spot market, enable spot exchange
-* If `p.ExchangeType` is derivative market, enable derivative market
+- `ValidateBasic` for proposal
+- If `p.ExchangeType` is spot market, enable spot exchange
+- If `p.ExchangeType` is derivative market, enable derivative market
## Spot market launch proposal
@@ -363,11 +345,11 @@ Launch of spot market is handled by `SpotMarketLaunchProposal` which consists of
**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`.
+- `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`.
## Perpetual market launch proposal
@@ -375,14 +357,14 @@ Perpetual market launch is handled by `PerpetualMarketLaunchProposal` which cons
**Steps**
-* `ValidateBasic` for proposal
-* Validate `quoteDenom`.
-* Calculate `marketID` from `ticker`, `quoteDenom`, `oracleBase`, `oracleQuote`, `oracleType`
-* Validate active or inactive perpetual market for `marketID` does not exist
-* Try getting derivative market price to check price oracle by `oracleBase`, `oracleQuote`, `oracleScaleFactor`, `oracleType`
-* Validate insurance fund exist for `marketID`
-* Calculate `defaultFundingInterval`, `nextFundingTimestamp`, `relayerFeeShareRate` from `exchange` module params
-* Execute `SetDerivativeMarketWithInfo` to set market info into the storage with `market`, `marketInfo` and `funding` objects
+- `ValidateBasic` for proposal
+- Validate `quoteDenom`.
+- Calculate `marketID` from `ticker`, `quoteDenom`, `oracleBase`, `oracleQuote`, `oracleType`
+- Validate active or inactive perpetual market for `marketID` does not exist
+- Try getting derivative market price to check price oracle by `oracleBase`, `oracleQuote`, `oracleScaleFactor`, `oracleType`
+- Validate insurance fund exist for `marketID`
+- 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
@@ -390,15 +372,15 @@ Expiry futures market launch is handled by `ExpiryFuturesMarketLaunchProposal` w
**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`.
+- `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`.
## Spot market param update proposal
@@ -406,10 +388,10 @@ The update of spot market param is handled by `SpotMarketParamUpdateProposal` wh
**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`.
+- `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 proposal
@@ -417,49 +399,49 @@ Derivative market param update is handled by `DerivativeMarketParamUpdateProposa
**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.
+- `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.
## Trading Rewards Campaign Launch Proposal
**Steps**
-* `ValidateBasic` for proposal
-* No existing campaign may exist.
-* Campaign start timestamps must be in the future.
-* Campaign quote denoms must exist.
-* All start timestamps must match the duration.
-* Set Campaign Data (Reward Pools, Info, Market Qualifications and Market Point Multipliers)
-* Emit `EventTradingRewardCampaignUpdate`
+- `ValidateBasic` for proposal
+- No existing campaign may exist.
+- Campaign start timestamps must be in the future.
+- Campaign quote denoms must exist.
+- All start timestamps must match the duration.
+- Set Campaign Data (Reward Pools, Info, Market Qualifications and Market Point Multipliers)
+- Emit `EventTradingRewardCampaignUpdate`
## Trading Rewards Campaign Update Proposal
**Steps**
-* `ValidateBasic` for proposal
-* All `StartTimestamp` inside `CampaignRewardPoolsUpdates` must equal an existing campaign.
-* `CampaignDurationSeconds` cannot be modified, but must match the current campaign.
-* `CampaignRewardPoolsUpdates` cannot modify the current campaign and may contain nil values to delete a reward pool.
-* Campaign start timestamps from `CampaignRewardPoolsAdditions` must be in the future.
-* Any campaign quote denoms must exist.
-* Delete Current Campaign Data (Info, Market Qualifications and Market Point Multipliers)
-* Set Campaign Data (Info, Market Qualifications and Market Point Multipliers)
-* Set Reward Pool Updates
-* Set Reward Pool Additions
-* Emit `EventTradingRewardCampaignUpdate`
+- `ValidateBasic` for proposal
+- All `StartTimestamp` inside `CampaignRewardPoolsUpdates` must equal an existing campaign.
+- `CampaignDurationSeconds` cannot be modified, but must match the current campaign.
+- `CampaignRewardPoolsUpdates` cannot modify the current campaign and may contain nil values to delete a reward pool.
+- Campaign start timestamps from `CampaignRewardPoolsAdditions` must be in the future.
+- Any campaign quote denoms must exist.
+- Delete Current Campaign Data (Info, Market Qualifications and Market Point Multipliers)
+- Set Campaign Data (Info, Market Qualifications and Market Point Multipliers)
+- Set Reward Pool Updates
+- Set Reward Pool Additions
+- Emit `EventTradingRewardCampaignUpdate`
## Fee Discount Schedule Proposal
**Steps**
-* `ValidateBasic` for proposal
-* If Current Fee Discount Schedule exists, delete it along with Market Qualifications
-* Defined quote denoms must exist.
-* If a restart of the fee cycle is required (bucket count, bucket duration or quote denoms changed), delete all account fee buckets and restart cycle.
-* 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
+- `ValidateBasic` for proposal
+- If Current Fee Discount Schedule exists, delete it along with Market Qualifications
+- Defined quote denoms must exist.
+- If a restart of the fee cycle is required (bucket count, bucket duration or quote denoms changed), delete all account fee buckets and restart cycle.
+- 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
diff --git a/.gitbook/developers/modules/injective/exchange/07_begin_block.md b/.gitbook/developers/modules/injective/exchange/07_begin_block.md
index 2be1cfa8..6d0f1bf8 100644
--- a/.gitbook/developers/modules/injective/exchange/07_begin_block.md
+++ b/.gitbook/developers/modules/injective/exchange/07_begin_block.md
@@ -3,16 +3,16 @@ sidebar_position: 8
title: BeginBlocker
---
-# BeginBlock
+# BeginBlocker
The exchange [BeginBlocker](https://docs.cosmos.network/master/building-modules/beginblock-endblock.html) runs at the start of every block in our defined order as the last module.
### 1. Process Hourly Fundings
1. Check the first to receive funding payments market. If the first market is not yet due to receive fundings (funding timestamp not reached), skip all fundings.
-2. Otherwise, go through each market one by one:
+2. Otherwise go through each market one by one:
1. Skip market if funding timestamp is not yet reached.
- 2. Compute funding as `twap + hourlyInterestRate` where $\mathrm{twap = \frac{cumulativePrice}{timeInterval \* 24\}}$ with $\mathrm{timeInterval = lastTimestamp - startingTimestamp}$. The `cumulativePrice` is previously calculated with every trade as the time weighted difference between VWAP and mark price: $\mathrm{\frac{VWAP - markPrice}{markPrice} \* timeElapsed}$.
+ 2. Compute funding as `twap + hourlyInterestRate` where $\mathrm{twap = \frac{cumulativePrice}{timeInterval * 24}}$ with $\mathrm{timeInterval = lastTimestamp - startingTimestamp}$. The `cumulativePrice` is previously calculated with every trade as the time weighted difference between VWAP and mark price: $\mathrm{\frac{VWAP - markPrice}{markPrice} * timeElapsed}$.
3. Cap funding if required to the maximum defined by `HourlyFundingRateCap`.
4. Set next funding timestamp.
5. Emit `EventPerpetualMarketFundingUpdate`.
@@ -22,7 +22,7 @@ The exchange [BeginBlocker](https://docs.cosmos.network/master/building-modules/
For each market in the list of markets to settle:
1. Settle market with zero closing fee and current mark price.
- 1. Run socialized loss. This will calculate the total amount of funds missing in across the market, and then reduce the payout proportionally for each profitable position. For example, a market with a total amount of 100 USDT missing funds and 10 profitable positions with identical quantity would result in a payout reduction of 10 USDT for each of the positions.
+ 1. Run socialized loss. This will calculate the total amount of funds missing in all of the market and then reduce the payout proportionally for each profitable position. For example a market with a total amount of 100 USDT missing funds and 10 profitable positions with identical quantity would result in a payout reduction of 10 USDT for each of the positions.
2. All positions are forcibly closed.
2. Delete from storage.
@@ -42,22 +42,24 @@ For each time expiry market, iterate through starting with first to expire:
1. Check if the current trading rewards campaign is finished.
2. If the campaign is finished, distribute reward tokens to eligible traders.
+
1. Compute the available reward for each reward denom as `min(campaignRewardTokens, communityPoolRewardTokens)`
2. Get the trader rewards based on the trading share from the respective trader calculated as `accountPoints * totalReward / totalTradingRewards`.
3. Send reward tokens from community pool to trader.
4. Reset total and all account trading reward points.
5. Delete the current campaign ending timestamp.
+
3. If a new campaign is launched, set the next current campaign ending timestamp as `CurrentCampaignStartTimestamp + CampaignDurationSeconds`.
4. If no current campaign is ongoing and no new campaigns are launched, delete campaign info, market qualifications and market multipliers from storage.
### 5. Process Fee Discount Buckets
-* If the oldest bucket's end timestamp is older than the `block.timestamp - bucketCount * bucketDuration`:
- * Prune the oldest bucket
- * Iterate over all `bucketStartTimestamp + account → FeesPaidAmount`:
- * Subtract the `FeesPaidAmount` from each account's `totalPastBucketFeesPaidAmount`
- * Delete the account's `account → {tier, TTL timestamp}`. Note that this technically isn't necessary for correctness since we check the TTL timestamps in the Endblocker but is a state pruning strategy.
- * Update the `CurrBucketStartTimestamp ← CurrBucketStartTimestamp + BucketDuration`.
+- If the oldest bucket's end timestamp is older than the `block.timestamp - bucketCount * bucketDuration`:
+ - Prune the oldest bucket
+ - Iterate over all `bucketStartTimestamp + account → FeesPaidAmount`:
+ - Subtract the `FeesPaidAmount` from each account's `totalPastBucketFeesPaidAmount`
+ - Delete the account's `account → {tier, TTL timestamp}`. Note that this technically isn't necessary for correctness since we check the TTL timestamps in the Endblocker but is a state pruning strategy.
+ - Update the `CurrBucketStartTimestamp ← CurrBucketStartTimestamp + BucketDuration`.
```
bucket count 5 and with 100 sec duration
diff --git a/.gitbook/developers/modules/injective/exchange/08_end_block.md b/.gitbook/developers/modules/injective/exchange/08_end_block.md
index ec3be8ca..b536c118 100644
--- a/.gitbook/developers/modules/injective/exchange/08_end_block.md
+++ b/.gitbook/developers/modules/injective/exchange/08_end_block.md
@@ -3,73 +3,76 @@ sidebar_position: 9
title: EndBlocker
---
-# EndBlock
+# EndBlocker
-The exchange [EndBlocker](https://docs.cosmos.network/main/build/building-modules/beginblock-endblock) runs at the end of every block in our defined order after governance and staking modules, and before the peggy, auction and insurance modules. It is particularly important that the governance module's EndBlocker runs before the exchange module's.
+The exchange [EndBlocker](https://docs.cosmos.network/master/building-modules/beginblock-endblock.html) runs at the end of every block in our defined order after governance and staking modules, and before the peggy, auction and insurance modules. It is particularly important that the governance module's EndBlocker runs before the exchange module's.
-* Stage 0: Determine the fee discounts for all the accounts that have placed an order in a fee-discount supported market in the current block.
-* Stage 1: Process all market orders in parallel - spot market and derivative market orders
- * Markets orders are executed against the resting orderbook at the time of the beginning of the block.
- * Note that market orders may be invalidated in the EndBlocker due to subsequently incoming oracle updates or limit order cancels.
-* Stage 2: Persist market order execution to store
- * Spot Markets
- * Persist Spot market order execution data
- * Emit relevant events
- * `EventBatchSpotExecution`
- * Derivative Markets
- * Persist Derivative market order execution data
- * Emit relevant events
- * `EventBatchDerivativeExecution`
- * `EventCancelDerivativeOrder`
-* Stage 3: Process all limit orders in parallel - spot and derivative limit orders that are matching
- * Limit orders are executed in a frequent batch auction mode to ensure fair matching prices, see below for details.
- * Note that vanilla limit orders may be invalidated in the EndBlocker due to subsequently incoming oracle updates, and reduce-only limit orders may be invalidated in the EndBlocker due to subsequently incoming orders which flip a position.
-* Stage 4: Persist limit order matching execution + new limit orders to store
- * Spot Markets
- * Persist Spot Matching execution data
- * Emit relevant events
- * `EventNewSpotOrders`
- * `EventBatchSpotExecution`
- * Derivative Markets
- * Persist Derivative Matching execution data
- * Emit relevant events
- * `EventNewDerivativeOrders`
- * `EventBatchDerivativeExecution`
- * `EventCancelDerivativeOrder`
-* Stage 5: Persist perpetual market funding info
-* Stage 6: Persist trading rewards total and account points.
-* Stage 7: Persist new fee discount data, i.e., new fees paid additions and new account tiers.
-* Stage 8: Process Spot Market Param Updates if any
-* Stage 9: Process Derivative Market Param Updates if any
-* Stage 10: Emit Deposit and Position Update Events
+- Stage 0: Determine the fee discounts for all the accounts that have placed an order in a fee-discount supported market in the current block.
+- Stage 1: Process all market orders in parallel - spot market and derivative market orders
+ - Markets orders are executed against the resting orderbook at the time of the beginning of the block.
+ - Note that market orders may be invalidated in the EndBlocker due to subsequently incoming oracle updates or limit order cancels.
+- Stage 2: Persist market order execution to store
+
+ - Spot Markets
+ - Persist Spot market order execution data
+ - Emit relevant events
+ - `EventBatchSpotExecution`
+ - Derivative Markets
+ - Persist Derivative market order execution data
+ - Emit relevant events
+ - `EventBatchDerivativeExecution`
+ - `EventCancelDerivativeOrder`
+
+- Stage 3: Process all limit orders in parallel - spot and derivative limit orders that are matching
+ - Limit orders are executed in a frequent batch auction mode to ensure fair matching prices, see below for details.
+ - Note that vanilla limit orders may be invalidated in the EndBlocker due to subsequently incoming oracle updates and reduce-only limit orders may be invalidated in the EndBlocker due to subsequently incoming orders which flip a position.
+- Stage 4: Persist limit order matching execution + new limit orders to store
+
+ - Spot Markets
+ - Persist Spot Matching execution data
+ - Emit relevant events
+ - `EventNewSpotOrders`
+ - `EventBatchSpotExecution`
+ - Derivative Markets
+ - Persist Derivative Matching execution data
+ - Emit relevant events
+ - `EventNewDerivativeOrders`
+ - `EventBatchDerivativeExecution`
+ - `EventCancelDerivativeOrder`
+
+- Stage 5: Persist perpetual market funding info
+- Stage 6: Persist trading rewards total and account points.
+- Stage 7: Persist new fee discount data, i.e., new fees paid additions and new account tiers.
+- Stage 8: Process Spot Market Param Updates if any
+- Stage 9: Process Derivative Market Param Updates if any
+- Stage 10: Emit Deposit and Position Update Events
## Order Matching: Frequent Batch Auction (FBA)
The goal of FBA is to prevent any [Front-Running](https://www.investopedia.com/terms/f/frontrunning.asp). This is achieved by calculating a single clearing price for all matched orders in a given block.
1. Market orders are filled first against the resting orderbook at the time of the beginning of the block. While the resting orders are filled at their respective order prices, the market orders are all filled at a uniform clearing price with the same mechanism as limit orders. For an example for the market order matching in FBA fashion, look at the API docs [here](https://api.injective.exchange/#examples-market-order-matching).
-2. Likewise, limit orders are filled at a uniform clearing price. New limit orders are combined with the resting orderbook and orders are matched as long as there is still negative spread. The clearing price is either:\
-
+2. Likewise limit orders are filled at a uniform clearing price. New limit orders are combined with the resting orderbook and orders are matched as long as there is still negative spread. The clearing price is either
- a. the best buy/sell order in case the last matched order crosses the spread in that direction,\
- b. the mark price in case of derivative markets and the mark price is between the last matched orders, or\
- c. the mid-price.
+a. the best buy/sell order in case the last matched order crosses the spread in that direction, the,
+b. the mark price in case of derivative markets and the mark price is between the last matched orders or
+c. the mid price.
For an example for the limit order matching in FBA fashion, look at the API docs [here](https://api.injective.exchange/#examples-limit-order-matching).
## Single Trade Calculations
-* For a qualifying market compute the fee discounts:
- * Fee discounts are applied as refunds and the fee paid contribution is recorded.
- * Relayer fees are applied AFTER the fee discount is taken.
-* For a qualifying market compute the trade reward point contribution:
- * Obtain the FeePaidMultiplier for maker and taker.
- * Compute the trade reward point contribution.
- * Trade reward points are based on the discounted trading fee.
-* Calculate fee refunds (or charges). There are several reasons why an order might get a fee refund after matching:
+- For a qualifying market compute the fee discounts:
+ - Fee discounts are applied as refunds and the fee paid contribution is recorded.
+ - Relayer fees are applied AFTER the fee discount is taken.
+- For a qualifying market compute the trade reward point contribution:
+ - Obtain the FeePaidMultiplier for maker and taker.
+ - Compute the trade reward point contribution.
+ - Trade reward points are based on the discounted trading fee.
+- Calculate fee refunds (or charges). There are several reasons why an order might get a fee refund after matching:
1. It's a limit order which is not matched or only partially matched which means it will become a resting limit order and switch from a taker to maker fee. The refund is `UnmatchedQuantity * (TakerFeeRate - MakerFeeRate)`. Note that for negative maker fees, we refund the `UnmatchedQuantity * TakerFeeRate` instead.
- 2. Fee discounts are applied. We refund the difference between the original fee paid, and the fee paid after the discount.
+ 2. Fee discounts are applied. We refund the difference between the original fee paid and the fee paid after the discount.
3. The order is matched at a better price resulting in a different fee.
- * For buy orders, a better price means a lower price and thus a lower fee. We refund the fee price delta.
- * For sell orders, a better price means a higher price and thus a higher fee. We charge the fee price delta.
- 4. You can find the respective code with an example [here](https://github.com/InjectiveLabs/injective-core/blob/80dbc4e9558847ff0354be5d19a4d8b0bba7da96/injective-chain/modules/exchange/keeper/derivative_orders_processor.go#L502). Please check the master branch for the latest chain code.
+ - For buy orders a better price means a lower price and thus a lower fee. We refund the fee price delta.
+ - For sell orders a better price means a higher price and thus a higher fee. We charge the fee price delta.
+ - You can find the respective code with an example [here](https://github.com/InjectiveLabs/injective-core/blob/80dbc4e9558847ff0354be5d19a4d8b0bba7da96/injective-chain/modules/exchange/keeper/derivative_orders_processor.go#L502). Please check the master branch for the latest chain code.
diff --git a/.gitbook/developers/modules/injective/exchange/11_msg_privileged_execute_contract.md b/.gitbook/developers/modules/injective/exchange/11_msg_privileged_execute_contract.md
index e58335f0..16995856 100644
--- a/.gitbook/developers/modules/injective/exchange/11_msg_privileged_execute_contract.md
+++ b/.gitbook/developers/modules/injective/exchange/11_msg_privileged_execute_contract.md
@@ -22,10 +22,10 @@ type MsgPrivilegedExecuteContract struct {
**Fields description**
-* `Sender` describes the creator of this msg.
-* `Funds` defines the user's bank coins used to fund the execution (e.g., 100inj).
-* `ContractAddress` defines the contract address to execute.
-* `Data` defines the call data used when executing the contract, see further details below.
+- `Sender` describes the creator of this msg.
+- `Funds` defines the user's bank coins used to fund the execution (e.g. 100inj).
+- `ContractAddress` defines the contract address to execute.
+- `Data` defines the call data used when executing the contract, see further details below.
**Contract Interface**
@@ -39,9 +39,9 @@ InjectiveExec {
}
```
-* The `origin` field is the address of the user who sent the privileged action. You don't have to set this field yourself, it will be set by the exchange module.
-* The `name` field is the name of the privileged action. You can define these to be whatever you want.
-* The `args` field is the arguments of the privileged action. You can define these to be whatever you want.
+- The `origin` field is the address of the user who sent the privileged action. You don't have to set this field yourself, it will be set by the exchange module.
+- The `name` field is the name of the privileged action. You can define these to be whatever you want.
+- The `args` field is the arguments of the privileged action. You can define these to be whatever you want.
A complete definition of the Data string in Golang is:
@@ -93,9 +93,9 @@ response = response.set_data(to_binary(&privileged_action)?);
**PositionTransfer**
-The position transfer allows a contract to transfer a derivative position from its own subaccount to a user's subaccount. The position may not be liquidable. Solely, the receiver pays a taker trading fee deducted from his balances.
+The position transfer allows a contract to transfer a derivative position from its own subaccount to a user's subaccount. The position may not be liquidable. Solely the receiver pays a taker trading fee deducted from his balances.
-Currently, only transfers from the contract's subaccount to a user's subaccount are supported.
+Currently only transfers from the contract's subaccount to a user's subaccount are supported.
```go
type PositionTransfer struct {
diff --git a/.gitbook/developers/modules/injective/exchange/README.md b/.gitbook/developers/modules/injective/exchange/README.md
index 042cb94c..d9c8423d 100644
--- a/.gitbook/developers/modules/injective/exchange/README.md
+++ b/.gitbook/developers/modules/injective/exchange/README.md
@@ -1,11 +1,12 @@
-# Exchange
+# `Exchange`
## Abstract
-The `exchange` module is the heart of the Injective Chain, which enables fully decentralized spot and derivative exchange.\
+The `exchange` module is the heart of the Injective Chain which enables fully decentralized spot and derivative exchange.
It is the _sine qua non_ module of the chain and integrates tightly with the `auction`, `insurance`, `oracle`, and `peggy` modules.
-The exchange protocol enables traders to create and trade on arbitrary spot and derivative markets. The entire process of orderbook management, trade execution, order matching and settlement occurs on chain through the logic codified by the exchange module.
+The exchange protocol enables traders to create and trade on arbitrary spot and derivative markets.
+The entire process of orderbook management, trade execution, order matching and settlement occurs on chain through the logic codified by the exchange module.
The `exchange` module enables the exchange of tokens on two types of markets:
@@ -14,15 +15,15 @@ The `exchange` module enables the exchange of tokens on two types of markets:
## Contents
-1. [**Derivative Market Concepts**](00_derivative_market_concepts.md)
-2. [**Spot Market Concepts**](01_spot_market_concepts.md)
-3. [**Other Concepts**](02_other_concepts.md)
-4. [**State**](03_state.md)
-5. [**State Transitions**](04_state_transitions.md)
-6. [**Messages**](05_messages.md)
-7. [**Proposals**](06_proposals.md)
-8. [**Begin Block**](07_begin_block.md)
-9. [**End Block**](08_end_block.md)
-10. [**Events**](09_events.md)
-11. [**Params**](10_params.md)
-12. [**MsgPrivilegedExecuteContract**](11_msg_privileged_execute_contract.md)
+1. **[Derivative Market Concepts](00_derivative_market_concepts.md)**
+2. **[Spot Market Concepts](01_spot_market_concepts.md)**
+3. **[Other Concepts](02_other_concepts.md)**
+4. **[State](03_state.md)**
+5. **[State Transitions](04_state_transitions.md)**
+6. **[Messages](05_messages.md)**
+7. **[Proposals](06_proposals.md)**
+8. **[Begin Block](07_begin_block.md)**
+9. **[End Block](08_end_block.md)**
+10. **[Events](09_events.md)**
+11. **[Params](10_params.md)**
+12. **[MsgPrivilegedExecuteContract](11_msg_privileged_execute_contract.md)**
diff --git a/.gitbook/developers/modules/injective/exchange/improvements.md b/.gitbook/developers/modules/injective/exchange/improvements.md
deleted file mode 100644
index c45e7cda..00000000
--- a/.gitbook/developers/modules/injective/exchange/improvements.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# Improvements
-
diff --git a/.gitbook/developers/modules/injective/insurance/01_state.md b/.gitbook/developers/modules/injective/insurance/01_state.md
index 7c3e6f6a..b7c3402c 100644
--- a/.gitbook/developers/modules/injective/insurance/01_state.md
+++ b/.gitbook/developers/modules/injective/insurance/01_state.md
@@ -9,7 +9,7 @@ title: State
`Params` is a module-wide configuration structure that stores system parameters and defines overall functioning of the insurance module.
-* Params: `Paramsspace("insurance") -> legacy_amino(params)`
+- Params: `Paramsspace("insurance") -> legacy_amino(params)`
```go
@@ -53,7 +53,7 @@ type InsuranceFund struct {
}
```
-`RedemptionSchedule` defines redemption schedules from users - redemption is not executed instantly, but there's `redemption_notice_period_duration` specified per market.
+`RedemptionSchedule` defines redemption schedules from users - redemption is not executed instantly but there's `redemption_notice_period_duration` specified per market.
```go
type RedemptionSchedule struct {
@@ -70,7 +70,8 @@ type RedemptionSchedule struct {
}
```
-Additionally, we introduce `next_share_denom_id` and `next_redemption_schedule_id` to manage insurance fund share token denom and redemption schedules from various users.
+Additionally, we introduce `next_share_denom_id` and `next_redemption_schedule_id` to manage insurance fund share token
+denom and redemption schedules from various users.
```go
// GenesisState defines the insurance module's genesis state.
@@ -86,4 +87,6 @@ type GenesisState struct {
## Pending Redemptions
-Pending Redemptions Objects are kept to store all the information about redemption requests and to auto-withdraw when the duration pass.
+Pending Redemptions Objects are kept to store all the information about redemption requests and to auto-withdraw when
+the duration pass.
+
diff --git a/.gitbook/developers/modules/injective/insurance/03_messages.md b/.gitbook/developers/modules/injective/insurance/03_messages.md
index fb7596c2..416b1a03 100644
--- a/.gitbook/developers/modules/injective/insurance/03_messages.md
+++ b/.gitbook/developers/modules/injective/insurance/03_messages.md
@@ -5,7 +5,7 @@ title: Messages
# Messages
-In this section, we describe the processing of the exchange messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](02_state_transitions.md) section.
+In this section we describe the processing of the exchange messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](02_state_transitions.md) section.
## Msg/CreateInsuranceFund
@@ -37,13 +37,14 @@ message MsgCreateInsuranceFund {
**Fields description**
-* `Sender` field describes the creator of an insurance fund.
-* `Ticker`, `QuoteDenom`, `OracleBase`, `OracleQuote`, `OracleType`, `Expiry` fields describe the derivative market info that the insurance fund corresponds to.
-* `InitialDeposit` specifies the initial deposit amount used to underwrite the insurance fund.
+- `Sender` field describes the creator of an insurance fund .
+- `Ticker`, `QuoteDenom`, `OracleBase`, `OracleQuote`, `OracleType`, `Expiry` fields describe the derivative market info
+ that the insurance fund corresponds to.
+- `InitialDeposit` specifies the initial deposit amount used to underwrite the insurance fund.
-Disclaimer: When creating an insurance fund, a small portion of shares (1%) will be reserved by the fund itself (protocol owned liquidity). A value of 1 USD is recommended as first subscription.
+Disclaimer: When creating an insurance fund a small portion of shares (1%) will be reserved by the fund itself (protocol owned liquidity). A value of 1 USD is recommended as first subscription.
-The motivation behind this feature is to avoid potential rounding issues when underwriting to a fund. For example, without having protocol owned liquidity, if the original fund creator would take out most of their shares leaving but a small amount, the value of the share token could diverge drastically from the original value. The next underwriter would then have to provide a much larger deposit despite gaining the same amount of shares.
+Motivation behind this feature is to avoid potential rounding issues when underwriting to a fund. For example, without having protocol owned liquidity, if the original fund creator would take out most of their shares leaving but a small amount, the value of the share token could diverge drastically from the original value. The next underwriter would then have to provide a much larger deposit despite gaining the same amount of shares.
## Msg/Underwrite
@@ -65,9 +66,9 @@ message MsgUnderwrite {
**Fields description**
-* `Sender` field describes the underwriter of an insurance fund.
-* `MarketId` field describes the derivative market id to the insurance fund.
-* `Deposit` field describes the deposit amount to be added to the insurance fund.
+- `Sender` field describes the underwriter of an insurance fund .
+- `MarketId` field describes the derivative market id to the insurance fund.
+- `Deposit` field describes the deposit amount to be added on the insurance fund.
## Msg/RequestRedemption
@@ -89,6 +90,6 @@ message MsgRequestRedemption {
**Fields description**
-* `Sender` field describes the redemption requester of an insurance fund.
-* `MarketId` field describes the derivative market id associated to the insurance fund.
-* `Amount` field describes the share token amount to be redeemed.
+- `Sender` field describes the redemption requester of an insurance fund .
+- `MarketId` field describes the derivative market id associated to the insurance fund.
+- `Amount` field describes the share token amount to be redeemed.
diff --git a/.gitbook/developers/modules/injective/insurance/04_end_block.md b/.gitbook/developers/modules/injective/insurance/04_end_block.md
index 29711d1e..8fece042 100644
--- a/.gitbook/developers/modules/injective/insurance/04_end_block.md
+++ b/.gitbook/developers/modules/injective/insurance/04_end_block.md
@@ -3,6 +3,6 @@ sidebar_position: 4
title: End-Block
---
-# EndBlock
+# End-Block
-At each EndBlock, redemption requests that have matured are automatically processed, resulting in the insurance pool token for the redemption being burned and the pro rata quote currency amount corresponding to the redemption being withdrawn from the insurance module to the underwriter's balances. More details can be found in the in Automatic withdrawal of pending redemptions in the [state transitions](02_state_transitions.md) section.
+At each EndBlock, redemption requests that have matured are automatically processed, resulting in the insurance pool token for the redemption being burned and the pro-rata quote currency amount corresponding to the redemption being withdrawn from the insurance module to the underwriter's balances. More details can be found in the in Automatic withdrawal of pending redemptions in the [state transitions](./02_state_transitions.md) section.
diff --git a/.gitbook/developers/modules/injective/insurance/05_events.md b/.gitbook/developers/modules/injective/insurance/05_events.md
index 095232f3..5add6de2 100644
--- a/.gitbook/developers/modules/injective/insurance/05_events.md
+++ b/.gitbook/developers/modules/injective/insurance/05_events.md
@@ -11,16 +11,29 @@ The insurance module emits the following events:
### MsgCreateInsuranceFund
-
Type | Attribute Key | Attribute Value |
---|
injective.insurance.v1beta1.EventInsuranceFundUpdate | fund | {fundJSON} |
+| Type | Attribute Key | Attribute Value |
+| ---------------------------------------------------- | ------------- | --------------- |
+| injective.insurance.v1beta1.EventInsuranceFundUpdate | fund | {fundJSON} |
### MsgUnderwrite
-Type | Attribute Key | Attribute Value |
---|
injective.insurance.v1beta1.EventInsuranceFundUpdate | fund | {fundJSON} |
+| Type | Attribute Key | Attribute Value |
+| ---------------------------------------------------- | ------------- | --------------- |
+| injective.insurance.v1beta1.EventInsuranceFundUpdate | fund | {fundJSON} |
### MsgRequestRedemption
-Type | Attribute Key | Attribute Value |
---|
injective.insurance.v1beta1.EventRequestRedemption | schedule | {scheduleJSON} |
+| Type | Attribute Key | Attribute Value |
+| -------------------------------------------------- | ------------- | --------------- |
+| injective.insurance.v1beta1.EventRequestRedemption | schedule | {scheduleJSON} |
+
+
## EndBlocker
-Type | Attribute Key | Attribute Value |
---|
injective.insurance.v1beta1.EventInsuranceFundUpdate | fund | {fundJSON} |
injective.insurance.v1beta1.EventWithdrawRedemption | schedule | {scheduleJSON} |
injective.insurance.v1beta1.EventWithdrawRedemption | redeem_coin | {redeemCoin} |
+| Type | Attribute Key | Attribute Value |
+| ---------------------------------------------------- | ------------- | --------------- |
+| injective.insurance.v1beta1.EventInsuranceFundUpdate | fund | {fundJSON} |
+| injective.insurance.v1beta1.EventWithdrawRedemption | schedule | {scheduleJSON} |
+| injective.insurance.v1beta1.EventWithdrawRedemption | redeem_coin | {redeemCoin} |
+
diff --git a/.gitbook/developers/modules/injective/insurance/README.md b/.gitbook/developers/modules/injective/insurance/README.md
index 94b4adeb..172cdb49 100644
--- a/.gitbook/developers/modules/injective/insurance/README.md
+++ b/.gitbook/developers/modules/injective/insurance/README.md
@@ -1,19 +1,19 @@
-# Insurance
+# `Insurance`
## Abstract
-This paper specifies the insurance module of the Injective Chain.
+This paper specifies the insurance module of the Injective Chain.
-This module provides insurance funds for derivative markets in the `exchange` module of the Injective Chain to use in order to support higher leverage trading. On a high level, insurance funds for each derivative market are funded by a permissionless group of underwriters, who each own a proportional claim (represented through insurance fund share tokens) over the underlying assets in the insurance fund.
+This module provides insurance funds for derivative markets in the `exchange` module of the Injective Chain to use in order to support higher leverage trading. On a high level, insurance funds for each derivative market are funded by a permissionless group of underwriters who each own a proportional claim (represented through insurance fund share tokens) over the underlying assets in the insurance fund.
-Each insurance fund grows when positions in its corresponding derivative market are liquidated with positive equity, as half of the positive equity is sent to the insurance fund upon liquidation. When a position with negative equity is liquidated (i.e., the position has surpassed bankruptcy), the insurance fund is utilized to cover the missing equity.
+Each insurance fund grows when positions in its corresponding derivative market are liquidated with positive equity, as half of the positive equity is sent to the insurance fund upon liquidation. When a position with negative equity is liquidated (i.e. the position has surpassed bankruptcy), the insurance fund is utilized to cover the missing equity.
## Contents
-1. [**State**](01_state.md)
-2. [**State Transitions**](02_state_transitions.md)
-3. [**Messages**](03_messages.md)
-4. [**End Block**](04_end_block.md)
-5. [**Events**](05_events.md)
-6. [**Params**](06_params.md)
-7. [**Future Improvements**](07_future_improvements.md)
+1. **[State](01_state.md)**
+2. **[State Transitions](02_state_transitions.md)**
+3. **[Messages](03_messages.md)**
+4. **[End Block](04_end_block.md)**
+5. **[Events](05_events.md)**
+6. **[Params](06_params.md)**
+7. **[Future Improvements](07_future_improvements.md)**
\ No newline at end of file
diff --git a/.gitbook/developers/modules/injective/insurance/state-transitions.md b/.gitbook/developers/modules/injective/insurance/state-transitions.md
deleted file mode 100644
index a39a5251..00000000
--- a/.gitbook/developers/modules/injective/insurance/state-transitions.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# State Transitions
-
diff --git a/.gitbook/developers/modules/injective/ocr/01_concepts.md b/.gitbook/developers/modules/injective/ocr/01_concepts.md
index c467a887..c42047f4 100644
--- a/.gitbook/developers/modules/injective/ocr/01_concepts.md
+++ b/.gitbook/developers/modules/injective/ocr/01_concepts.md
@@ -5,21 +5,21 @@ title: Concepts
# Concepts
-The `ocr` module is to store Chainlink's OCR information into on-chain by verified members.
+The `ocr` module is to store chainlink's OCR information into on-chain by verified members.
Off-chain reporting consists of N nodes (oracles), gathering data from external sources. Reports are being exchanged in a p2p fashion between oracles to get signatures of approval. A subset of nodes (transmitters) is identified by the `ocr` module on-chain, they must submit the reports to module, the first transmitter who hits the chain gets an extra reward to cover gas costs. Other transmitters are not. All oracles participating in the round are getting paid. `ocr` module stores median value from the reports.
## OCR Terminology
-The protocol periodically sends **oracle reports** to the OCR module. The reporting protocol comprises three components: **pacemaker**, **report generation** and **transmission**.
+The protocol periodically sends **oracle reports** to the OCR module. The reporting protocol is comprised of three components: **pacemaker**, **report generation** and **transmission**.
**Pacemaker**
-The pacemaker drives the report generation process, which is structured in **epochs**. Each epoch has a designated leader who the pacemaker then tasks with starting the report generation protocol. If the leader does not produce a valid report in time, the pacemaker also aborts the current report generation and starts a new epoch.
+The pacemaker drives the report generation process which is structured in **epochs**. Each epoch has a designatd leader who the pacemaker then tasks with starting the report generation protocol. If the leader does not produce a valid report in time, the pacemaker also aborts the current report generation and starts a new epoch.
**Report Generation**
-For a given epoch, the report generation protocol enters into **rounds** where **observations** are gathered and (given conditions are met such as heartbeat and deviation) a signed oracle **report** is generated. The rounds are controlled by a leader node who controls the frequency of rounds, gathers the observations and generates the report.
+For a given epoch, the report generation protocol enters into **rounds** where **observations** are gathered and (given conditions are met such as heartbeat and deviation) a signed oracle **report** is generated. The rounds are controlled by a leader node who controls the frequency of rounds, gathers the observations and generates the report.
**Transmission**
@@ -27,34 +27,34 @@ The transmission protocol then transmits the generated report to the OCR module.
## Off-chain OCR integration
-* Provide means to communicate with Injective using sdk-go
-* Read data from the module, such as a list of approved oracles
-* Submit reports as Msgs (Implement `ContractTransmitter`)
-* Implement `OffchainConfigDigester`
-* Implement `OnchainKeyring` for producing signatures that will work on the target chain module
-* Implement `ContractConfigTracker` for tracking changes of the chain module config (gov approved)
+- Provide means to communicate with Injective using sdk-go
+- Read data from the module, such as a list of approved oracles
+- Submit reports as Msgs (Implement `ContractTransmitter`)
+- Implement `OffchainConfigDigester`
+- Implement `OnchainKeyring` for producing signatures that will work on the target chain module
+- Implement `ContractConfigTracker` for tracking changes of the chain module config (gov approved)
Notes:
-* Reports are timestamped in Epoch-Round fashion
-* `ocr` module verifies the signatures of oracles on the report
-* `ocr` module records oracles who contributed to a report, for the payout
-* `ocr` module stores the median of the observations
-* `ocr` module provides extra reward for the first submitter of a Msg
+- Reports are timestamped in Epoch-Round fashion
+- `ocr` module verifies the signatures of oracles on the report
+- `ocr` module records oracles who contributed to a report, for the payout
+- `ocr` module stores the median of the observations
+- `ocr` module provides extra reward for the first submitter of a Msg
### Integration Overview
-Chainlink has several [price data feeds](https://data.chain.link/feeds) including:
+Chainlink has several [price data feeds](https://data.chain.link/ethereum/mainnet/stablecoins) including:
-* 80 Crypto/USD pairs (e.g., ETH/USD, BTC/USD)
-* 17 Stablecoin pairs (e.g., USDT/USD, USDC/USD)
-* 73 ETH pairs (e.g., LINK/ETH)
-* 17 Forex pairs (e.g., GBP/USD, CNY/USD)
+- 80 Crypto/USD pairs (e.g. ETH/USD, BTC/USD)
+- 17 Stablecoin pairs (e.g. USDT/USD, USDC/USD)
+- 73 ETH pairs (e.g. LINK/ETH)
+- 17 Forex pairs (e.g. GBP/USD, CNY/USD)
A derivative market on Injective specifies the following oracle parameters:
-* An oracleBase (e.g., BTC)
-* An oracleQuote (e.g., USDT)
-* An oracleType (e.g., Chainlink)
+- An oracleBase (e.g. BTC)
+- An oracleQuote (e.g. USDT)
+- An oracleType (e.g. Chainlink)
-Thus, for a BTC/USDT derivative market on Injective, the oracleBase would be BTC/USD, the oracleQuote would be USDT/USD and the oracleType would be Chainlink. The price for the market would then be obtained by dividing the BTC/USD price with the USDT/USD price, leaving the BTC/USDT price.
+Thus for a BTC/USDT derivative market on Injective, the oracleBase would be BTC/USD, the oracleQuote would be USDT/USD and the oracleType would be Chainlink. The price for the market would then be obtained by dividing the BTC/USD price with the USDT/USD price, leaving the BTC/USDT price.
diff --git a/.gitbook/developers/modules/injective/ocr/02_state.md b/.gitbook/developers/modules/injective/ocr/02_state.md
index e3ce59ec..5ab39bbd 100644
--- a/.gitbook/developers/modules/injective/ocr/02_state.md
+++ b/.gitbook/developers/modules/injective/ocr/02_state.md
@@ -5,7 +5,7 @@ title: State
# State
-Genesis state defines the initial state of the module to be used to set up the module.
+Genesis state defines the initial state of the module to be used to setup the module.
```go
// GenesisState defines the OCR module's genesis state.
@@ -30,13 +30,12 @@ type GenesisState struct {
PendingPayeeships []*PendingPayeeship
}
```
-
## Params
-`Params` is a module-wide configuration that stores system parameters and defines overall functioning of the ocr module. This module is modifiable by governance using params update proposal natively supported by the `gov` module.
+`Params` is a module-wide configuration that stores system parameters and defines overall functioning of the ocr module.
+This module is modifiable by governance using params update proposal natively supported by `gov` module.
Struct for the `ocr` module params store.
-
```go
type Params struct {
// Native denom for LINK coin in the bank keeper
@@ -50,7 +49,7 @@ type Params struct {
## FeedConfig
-`FeedConfig` is to manage the configurations of feed, and it exists one per feed.
+`FeedConfig` is to manage the configurations of feed and it exists one per feed.
```go
type FeedConfig struct {
@@ -176,7 +175,6 @@ type ContractConfig struct {
OffchainConfig []byte
}
```
-
### FeedProperties
`FeedProperties` is a unit to store the properties of feed by id.
@@ -208,7 +206,8 @@ type FeedProperties struct {
### PendingPayeeship
-`PendingPayeeship` is a record that is stored when a person is delegating payeeship to another address. When proposed payee accept this, this record is removed.
+`PendingPayeeship` is a record that is stored when a person is delegating payeeship to another address.
+When proposed payee accept this, this record is removed.
```go
type PendingPayeeship struct {
@@ -216,4 +215,4 @@ type PendingPayeeship struct {
Transmitter string
ProposedPayee string
}
-```
+```
\ No newline at end of file
diff --git a/.gitbook/developers/modules/injective/ocr/03_messages.md b/.gitbook/developers/modules/injective/ocr/03_messages.md
index 35f2e40b..ee0823ff 100644
--- a/.gitbook/developers/modules/injective/ocr/03_messages.md
+++ b/.gitbook/developers/modules/injective/ocr/03_messages.md
@@ -5,11 +5,11 @@ title: Messages
# Messages
-In this section, we describe the processing of the ocr messages and the corresponding updates to the state.
+In this section we describe the processing of the ocr messages and the corresponding updates to the state.
## Msg/CreateFeed
-`MsgCreateFeed` is a message to create feed config, and it is a restricted message that is executable by module admin.
+`MsgCreateFeed` is a message to create feed config and it is restricted message that is executable by module admin.
```protobuf
message MsgCreateFeed {
@@ -22,17 +22,17 @@ message MsgCreateFeed {
**Steps**
-* Ensure `Sender` is module admin
-* Ensure `msg.Config.OnchainConfig.LinkDenom` is module param's `LinkDenom`
-* Set `OnchainConfig.ChainId` from `ctx.ChainID`
-* Ensure `FeedConfig` with same `FeedId` does not exist
-* Set latest `EpochAndRound` to `(0, 0)`
-* Set feed config for `feedId`
-* Set feed transmissions count and observations count to 1
+- Ensure `Sender` is module admin
+- Ensure `msg.Config.OnchainConfig.LinkDenom` is module param's `LinkDenom`
+- Set `OnchainConfig.ChainId` from `ctx.ChainID`
+- Ensure `FeedConfig` with same `FeedId` does not exist
+- Set latest `EpochAndRound` to `(0, 0)`
+- Set feed config for `feedId`
+- Set feed trasmissions count and observations count to 1
## Msg/UpdateFeed
-`MsgCreateFeed` is a message to update feed config, and it is restricted message that is executable by feed admin or feed billing admin.
+`MsgCreateFeed` is a message to update feed config and it is restricted message that is executable by feed admin or feed billing admin.
```protobuf
message MsgUpdateFeed {
@@ -66,13 +66,13 @@ message MsgUpdateFeed {
**Steps**
-* Get previous feed config by `feedId` and ensure it exists
-* Ensure `Sender` is feed admin or feed billing admin
-* Ensure billing admin is not changing Signers, Transmitters, and feed admin
-* Process rewards payout for previous feed config
-* Delete previous feed transmission and observation counts
-* Set latest `EpochAndRound` to `(0, 0)`
-* Update signers, transmitters, `LinkPerObservation`, `LinkPerTransmission`, `LinkDenom`, `FeedAdmin`, `BillingAdmin` if set.
+- Get previous feed config by `feedId` and ensure it exists
+- Ensure `Sender` is feed admin or feed billing admin
+- Ensure billing admin is not changing Signers, Transmitters and feed admin
+- Process rewards payout for previous feed config
+- Delete previous feed transmission and observation counts
+- Set latest `EpochAndRound` to `(0, 0)`
+- Update signers, transmitters, `LinkPerObservation`, `LinkPerTransmission`, `LinkDenom`, `FeedAdmin`, `BillingAdmin` if set.
## Msg/Transmit
@@ -96,15 +96,15 @@ message MsgTransmit {
**Steps**
-* Get epoch and round for `feedId`
-* Ensure that the report is not staled one by checking `msg.Epoch` and `msg.Round`
-* Get feed config and config info from `feedId`
-* Check msg.ConfigDigest equals to feed config info's latest config digest
-* Check if transmitter is valid transmitter configured in `feedConfig`
-* Save transmitter report
-* Emit event for transmission
-* Validate signatures and the number of signatures
-* Increment feed observation and transmission counts
+- Get epoch and round for `feedId`
+- Ensure that the report is not staled one by checking `msg.Epoch` and `msg.Round`
+- Get feed config and config info from `feedId`
+- Check msg.ConfigDigest equals to feed config info's latest config digest
+- Check if transmitter is valid transmitter configured in `feedConfig`
+- Save transmitter report
+- Emit event for trasmission
+- Validate signatures and the number of signatures
+- Increment feed observation and transmission counts
## Msg/FundFeedRewardPool
@@ -123,12 +123,12 @@ message MsgFundFeedRewardPool {
**Steps**
-* Get previous reward pool amount from `feedId`
-* If previous amount is empty, initiate the pool amount with zero integer
-* Ensure previous amount denom is not different from deposit denom if exist
-* Send coins from account to the module account (`ocr` module)
-* Update reward pool amount with `amount` field addition
-* Call `AfterFundFeedRewardPool` hook if hooks is set
+- Get previous reward pool amount from `feedId`
+- If previous amount is empty, initiate the pool amount with zero integer
+- Ensure previous amount denom is not different from deposit denom if exist
+- Send coins from account to the module account (`ocr` module)
+- Update reward pool amount with `amount` field addition
+- Call `AfterFundFeedRewardPool` hook if hooks is set
## Msg/WithdrawFeedRewardPool
@@ -147,10 +147,10 @@ message MsgWithdrawFeedRewardPool {
**Steps**
-* Get feed config from `feedId`
-* Ensure `msg.Sender` is `feedAdmin` or `billingAdmin`
-* Process reward for the feed
-* Withdraw specified amount `msg.Amount` from module account
+- Get feed config from `feedId`
+- Ensure `msg.Sender` is `feedAdmin` or `billingAdmin`
+- Process reward for the feed
+- Withdraw specified amount `msg.Amount` from module account
## Msg/SetPayees
@@ -172,13 +172,11 @@ message MsgSetPayees {
**Steps**
-* Get feed config from `feedId` and ensure that feed config exists
-* Ensure `msg.Sender` is feed admin
-* Iterating `msg.Transmitters`,
-*
- 1. Ensure payee is set already for the transmitter
-*
- 2. Set payee for the transmitter
+- Get feed config from `feedId` and ensure that feed config exists
+- Ensure `msg.Sender` is feed admin
+- Iterating `msg.Transmitters`,
+- 1. Ensure payee is set already for the transmitter
+- 2. Set payee for the transmitter
## Msg/TransferPayeeship
@@ -200,10 +198,10 @@ message MsgTransferPayeeship {
**Steps**
-* Get feed config from `feedId` and ensure that feed config exists
-* Ensure msg.Sender is current payee
-* Check previous pending payeeship transfer record and ensure previous payeeship transfer does not conflict
-* Set payeeship transfer record
+- Get feed config from `feedId` and ensure that feed config exists
+- Ensure msg.Sender is current payee
+- Check previous pending payeeship transfer record and ensure previous payeeship transfer does not conflict
+- Set payeeship transfer record
## Msg/AcceptPayeeship
@@ -223,7 +221,7 @@ message MsgAcceptPayeeship {
**Steps**
-* Get feed config from `feedId` and ensure that feed config exists
-* Get pending payeeship transfer record for `msg.Transmitter` and `feedId`
-* Reset payee for `feedId` and `transmitter`
-* Delete pending payeeship transfer for `transmitter` of `feedId`
+- Get feed config from `feedId` and ensure that feed config exists
+- Get pending payeeship transfer record for `msg.Transmitter` and `feedId`
+- Reset payee for `feedId` and `transmitter`
+- Delete pending payeeship transfer for `transmitter` of `feedId`
diff --git a/.gitbook/developers/modules/injective/ocr/05_begin_block.md b/.gitbook/developers/modules/injective/ocr/05_begin_block.md
index ea773810..6c2ed6a8 100644
--- a/.gitbook/developers/modules/injective/ocr/05_begin_block.md
+++ b/.gitbook/developers/modules/injective/ocr/05_begin_block.md
@@ -3,11 +3,11 @@ sidebar_position: 5
title: Begin-Block
---
-# BeginBlock
+# Begin-Block
-At each BeginBlock, it checks if it's time for payout interval and if it's time, it processes payout for all feeds.
+At each BeginBlock, it checks if it's time for payout interval and if it's time, it process payout for all feeds.
**Steps**
-* Ensure it's the begin block of payout interval
-* While iterating all feed configs, process reward payouts
+- Ensure it's the begin block of payout interval
+- While iterating all feed configs, process reward payouts
diff --git a/.gitbook/developers/modules/injective/ocr/06_hooks.md b/.gitbook/developers/modules/injective/ocr/06_hooks.md
index e4106648..c50e2acf 100644
--- a/.gitbook/developers/modules/injective/ocr/06_hooks.md
+++ b/.gitbook/developers/modules/injective/ocr/06_hooks.md
@@ -4,13 +4,14 @@ sidebar_position: 6
# Hooks
-Other modules may register operations to execute when a certain event has occurred within ocr module. The following hooks can be registered with ocr:
+Other modules may register operations to execute when a certain event has occurred within ocr module. The following hooks can registered with ocr:
-* `AfterSetFeedConfig(ctx sdk.Context, feedConfig *FeedConfig)`
- * called after feed config is created or updated
-* `AfterTransmit(ctx sdk.Context, feedId string, answer math.LegacyDec, timestamp int64)`
- * called when info is transmitted
-* `AfterFundFeedRewardPool(ctx sdk.Context, feedId string, newPoolAmount sdk.Coin)`
- * called when feed reward pool is updated
+- `AfterSetFeedConfig(ctx sdk.Context, feedConfig *FeedConfig)`
+ - called after feed config is created or updated
+- `AfterTransmit(ctx sdk.Context, feedId string, answer math.LegacyDec, timestamp int64)`
+ - called when info is transmitted
+- `AfterFundFeedRewardPool(ctx sdk.Context, feedId string, newPoolAmount sdk.Coin)`
+ - called when feed reward pool is updated
-Note: `oracle` module is accepting `AfterTransmit` hook to store cumulative price when transmission is made.
+Note:
+`oracle` module is accepting `AfterTransmit` hook to store cumulative price when transmission is made.
\ No newline at end of file
diff --git a/.gitbook/developers/modules/injective/ocr/README.md b/.gitbook/developers/modules/injective/ocr/README.md
index 9ea3d7ab..41e1e177 100644
--- a/.gitbook/developers/modules/injective/ocr/README.md
+++ b/.gitbook/developers/modules/injective/ocr/README.md
@@ -1,20 +1,21 @@
-# OCR
+# Ocr
## Abstract
-OCR module is to store Chainlink's OCR (Off-Chain Report) info into the chain storage.
+OCR module is to store chainlink's OCR(Off-Chain Report) info into the chain storage.
-Feed configuration is managed by module admin and report move to on-chain by transmitters and observers. Transmitters and observers are rewarded in LINK token on the chain configured by governance.
+Feed configuration is managed by module admin and report move to on-chain by transmitters and observers.
+Transmitters and observers are rewarded in LINK token on the chain configured by governance.
While storing feed information, module provide hooks where oracle module can use for the calculation of cumulative price for futures market.
## Contents
-1. [**Concepts**](01_concepts.md)
-2. [**State**](02_state.md)
-3. [**Messages**](03_messages.md)
-4. [**Proposals**](04_proposals.md)
-5. [**Begin-Block**](05_begin_block.md)
-6. [**Hooks**](06_hooks.md)
-7. [**Events**](07_events.md)
-8. [**Parameters**](08_params.md)
+1. **[Concepts](01_concepts.md)**
+2. **[State](02_state.md)**
+3. **[Messages](03_messages.md)**
+4. **[Proposals](04_proposals.md)**
+5. **[Begin-Block](05_begin_block.md)**
+6. **[Hooks](06_hooks.md)**
+7. **[Events](07_events.md)**
+8. **[Parameters](08_params.md)**
diff --git a/.gitbook/developers/modules/injective/ocr/events.md b/.gitbook/developers/modules/injective/ocr/events.md
deleted file mode 100644
index 2d7cfb97..00000000
--- a/.gitbook/developers/modules/injective/ocr/events.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# Events
-
diff --git a/.gitbook/developers/modules/injective/oracle/01_state.md b/.gitbook/developers/modules/injective/oracle/01_state.md
index 29dbcb1f..5a5ed19e 100644
--- a/.gitbook/developers/modules/injective/oracle/01_state.md
+++ b/.gitbook/developers/modules/injective/oracle/01_state.md
@@ -6,9 +6,7 @@ title: State
# State
## Params
-
-The oracle module parameters.
-
+The oracle module parameters.
```protobuf
message Params {
option (gogoproto.equal) = true;
@@ -17,6 +15,7 @@ message Params {
}
```
+
## PriceState
PriceState is common type to manage cumulative price and latest price along with timestamp for all oracle types.
@@ -31,21 +30,21 @@ message PriceState {
}
```
-where:
+where
-* `Price` represents the normalized decimal price
-* `CumulativePrice` represents the cumulative price for a given oracle price feed since the start of the oracle price feed's creation.
-* `Timestamp` represents the time at which the blocktime at which the price state was relayed.
+- `Price` represents the normalized decimal price
+- `CumulativePrice` represents the cumulative price for a given oracle price feed since the start of the oracle price feed's creation.
+- `Timestamp` represents the time at which the blocktime at which the price state was relayed.
-Note that the `CumulativePrice` value follows the convention set by the [Uniswap V2 Oracle](https://uniswap.org/docs/v2/core-concepts/oracles/) and is used to allow modules to calculate Time-Weighted Average Price (TWAP) between 2 arbitrary block time intervals (t1, t2).
+Note that the `CumulativePrice` value follows the convention set by the [Uniswap V2 Oracle](https://uniswap.org/docs/v2/core-concepts/oracles/) and is used to allows modules to calculate Time-Weighted Average Price (TWAP) between 2 arbitrary block time intervals (t1, t2).
-$\mathrm{TWAP = \frac{CumulativePrice_2 - CumulativePrice_1}{Timestamp_2 - Timestamp_1\}}$
+$\mathrm{TWAP = \frac{CumulativePrice_2 - CumulativePrice_1}{Timestamp_2 - Timestamp_1}}$
## Band
Band price data for a given symbol are represented and stored as follows:
-* BandPriceState: `0x01 | []byte(symbol) -> ProtocolBuffer(BandPriceState)`
+- BandPriceState: `0x01 | []byte(symbol) -> ProtocolBuffer(BandPriceState)`
```protobuf
message BandPriceState {
@@ -61,17 +60,22 @@ Note that the `Rate` is the raw USD rate for the `Symbol` obtained from the Band
Band relayers are stored by their address as follows.
-* BandRelayer: `0x02 | RelayerAddr -> []byte{}`
+- BandRelayer: `0x02 | RelayerAddr -> []byte{}`
## Band IBC
This section describes all the state management to maintain the price by connecting to Band chain via IBC.
-* LatestClientID is maintained to manage unique clientID for band IBC packets. It is increased by 1 when sending price request packet into bandchain.
+- LatestClientID is maintained to manage unique clientID for band IBC packets. It is increased by 1 when sending price request packet into bandchain.
+
* LatestClientID: `0x32 -> Formated(LatestClientID)`
-* LatestRequestID is maintained to manage unique `BandIBCOracleRequests`. Incremented by 1 when creating a new `BandIBCOracleRequest`.
+
+- LatestRequestID is maintained to manage unique `BandIBCOracleRequests`. Incremented by 1 when creating a new `BandIBCOracleRequest`.
+
* LatestRequestID: `0x36 -> Formated(LatestRequestID)`
-* Band IBC price data for a given symbol is stored as follows:
+
+- Band IBC price data for a given symbol is stored as follows:
+
* BandPriceState: `0x31 | []byte(symbol) -> ProtocolBuffer(BandPriceState)`
```protobuf
@@ -84,7 +88,8 @@ message BandPriceState {
}
```
-* BandIBCCallDataRecord is stored as follows when sending price request packet into bandchain:
+- BandIBCCallDataRecord is stored as follows when sending price request packet into bandchain:
+
* CalldataRecord: `0x33 | []byte(ClientId) -> ProtocolBuffer(CalldataRecord)`
```protobuf
@@ -94,7 +99,8 @@ message CalldataRecord {
}
```
-* BandIBCOracleRequest is stored as follows when the governance configure oracle requests to send:
+- BandIBCOracleRequest is stored as follows when the governance configure oracle requests to send:
+
* BandOracleRequest: `0x34 | []byte(RequestId) -> ProtocolBuffer(BandOracleRequest)`
```protobuf
@@ -127,7 +133,8 @@ message BandOracleRequest {
}
```
-* BandIBCParams is stored as follows and configured by governance:
+- BandIBCParams is stored as follows and configured by governance:
+
* BandIBCParams: `0x35 -> ProtocolBuffer(BandIBCParams)`
`BandIBCParams` contains the information for IBC connection with band chain.
@@ -157,7 +164,7 @@ Note:
Coinbase price data for a given symbol ("key") are represented and stored as follows:
-* CoinbasePriceState: `0x21 | []byte(key) -> CoinbasePriceState`
+- CoinbasePriceState: `0x21 | []byte(key) -> CoinbasePriceState`
```protobuf
message CoinbasePriceState {
@@ -182,7 +189,7 @@ Note that the `Value` is the raw USD price data obtained from Coinbase which has
Pricefeed price data for a given base quote pair are represented and stored as follows:
-* PriceFeedInfo: `0x11 + Keccak256Hash(base + quote) -> PriceFeedInfo`
+- PriceFeedInfo: `0x11 + Keccak256Hash(base + quote) -> PriceFeedInfo`
```protobuf
message PriceFeedInfo {
@@ -191,7 +198,7 @@ message PriceFeedInfo {
}
```
-* PriceFeedPriceState: `0x12 + Keccak256Hash(base + quote) -> PriceFeedPriceState`
+- PriceFeedPriceState: `0x12 + Keccak256Hash(base + quote) -> PriceFeedPriceState`
```protobuf
message PriceFeedState {
@@ -202,14 +209,12 @@ message PriceFeedState {
}
```
-* PriceFeedRelayer: `0x13 + Keccak256Hash(base + quote) + relayerAddr -> relayerAddr`
-
-## Provider
+- PriceFeedRelayer: `0x13 + Keccak256Hash(base + quote) + relayerAddr -> relayerAddr`
+## Provider
Provider price feeds are represented and stored as follows:
-* ProviderInfo: `0x61 + provider + @@@ -> ProviderInfo`
-
+- ProviderInfo: `0x61 + provider + @@@ -> ProviderInfo`
```protobuf
message ProviderInfo {
string provider = 1;
@@ -217,9 +222,9 @@ message ProviderInfo {
}
```
-* ProviderIndex: `0x62 + relayerAddress -> provider`
-* ProviderPrices: `0x63 + provider + @@@ + symbol -> ProviderPriceState`
+- ProviderIndex: `0x62 + relayerAddress -> provider`
+- ProviderPrices: `0x63 + provider + @@@ + symbol -> ProviderPriceState`
```protobuf
message ProviderPriceState {
string symbol = 1;
@@ -230,9 +235,7 @@ message ProviderPriceState {
## Pyth
Pyth prices are represented and stored as follows:
-
-* PythPriceState: `0x71 + priceID -> PythPriceState`
-
+- PythPriceState: `0x71 + priceID -> PythPriceState`
```protobuf
message PythPriceState {
bytes price_id = 1;
@@ -247,9 +250,7 @@ message PythPriceState {
## Stork
Stork prices are represented and stored as follows:
-
-* StorkPriceState: `0x81 + symbol -> PythPriceState`
-
+- StorkPriceState: `0x81 + symbol -> PythPriceState`
```protobuf
message StorkPriceState {
// timestamp of the when the price was signed by stork
@@ -267,9 +268,8 @@ message StorkPriceState {
```
Stork publishers are represented and stored as follows:
-
-* Publisher: `0x82 + stork_publisher -> publisher`
+- Publisher: `0x82 + stork_publisher -> publisher`
```protobuf
string stork_publisher
-```
+```
\ No newline at end of file
diff --git a/.gitbook/developers/modules/injective/oracle/03_messages.md b/.gitbook/developers/modules/injective/oracle/03_messages.md
index c965bc28..599e47a3 100644
--- a/.gitbook/developers/modules/injective/oracle/03_messages.md
+++ b/.gitbook/developers/modules/injective/oracle/03_messages.md
@@ -7,7 +7,9 @@ title: Messages
## MsgRelayBandRates
-Authorized Band relayers can relay price feed data for multiple symbols with the `MsgRelayBandRates` message. The registered handler iterates over all the symbols present in the `MsgRelayBandRates` and creates/updates the `BandPriceState` for each symbol.
+Authorized Band relayers can relay price feed data for multiple symbols with the `MsgRelayBandRates` message.
+The registered handler iterates over all the symbols present in the `MsgRelayBandRates` and creates/updates the
+`BandPriceState` for each symbol.
```protobuf
message MsgRelayBandRates {
@@ -80,11 +82,12 @@ message MsgRequestBandIBCRates {
}
```
-Anyone can broadcast this message, and no specific authorization is needed. The handler checks if `BandIbcEnabled` flag is true and go ahead sending a request.
+Anyone can broadcast this message and no specific authorization is needed.
+The handler checks if `BandIbcEnabled` flag is true and go ahead sending a request.
## MsgRelayPythPrices
-`MsgRelayPythPrices` is a message for the Pyth contract relay prices to the oracle module.
+`MsgRelayPythPrices` is a message for the Pyth contract relay prices to the oracle module.
```protobuf
// MsgRelayPythPrices defines a SDK message for updating Pyth prices
@@ -123,11 +126,12 @@ enum PythStatus {
}
```
-This message is expected to fail if the Relayer (`sender`) does not equal the Pyth contract address as defined in the oracle module Params.
+This message is expected to fail if the Relayer (`sender`) does not equal the Pyth contract address as defined in the
+oracle module Params.
## MsgRelayStorkPrices
-`MsgRelayStorkPrices` is a message for the Stork contract relay prices to the oracle module.
+`MsgRelayStorkPrices` is a message for the Stork contract relay prices to the oracle module.
```protobuf
// MsgRelayStorkPrices defines a SDK message for relaying price message from Stork API.
@@ -156,11 +160,10 @@ message SignedPriceOfAssetPair {
}
```
-This message is expected to fail if:
-
-* the Relayer (`sender`) is not an authorized oracle publisher or if `assetId` is not unique amongst the provided asset pairs
-* ECDSA signature verification fails for the `SignedPriceOfAssetPair`
-* The difference between timestamps exceeds the `MaxStorkTimestampIntervalNano` (500 milliseconds).
+This message is expected to fail if:
+- the Relayer (`sender`) is not an authorized oracle publisher or if `assetId` is not unique amongst the provided asset pairs
+- ECDSA signature verification fails for the `SignedPriceOfAssetPair`
+- the difference between timestamps exceeds the `MaxStorkTimestampIntervalNano` (500 milliseconds).
## MsgRelayProviderPrices
diff --git a/.gitbook/developers/modules/injective/oracle/04_proposals.md b/.gitbook/developers/modules/injective/oracle/04_proposals.md
index fe02087e..82488e8c 100644
--- a/.gitbook/developers/modules/injective/oracle/04_proposals.md
+++ b/.gitbook/developers/modules/injective/oracle/04_proposals.md
@@ -3,12 +3,13 @@ sidebar_position: 4
title: Governance Proposals
---
-# Proposals
+# Governance Proposals
## GrantProviderPrivilegeProposal
Oracle provider privileges can be granted to your account through a `GrantBandOraclePrivilegeProposal`. After the governance proposal is passed, you will be able to relay price feeds using your provider.
+
```protobuf
// Grant Privileges
message GrantProviderPrivilegeProposal {
@@ -25,7 +26,7 @@ message GrantProviderPrivilegeProposal {
}
```
-You can submit your proposal according to the example:
+You can submit your proposal according to the example:
```bash
injectived tx oracle grant-provider-privilege-proposal YOUR_PROVIDER \
@@ -40,11 +41,14 @@ injectived tx oracle grant-provider-privilege-proposal YOUR_PROVIDER \
--deposit="40000000000000000000inj"
```
-To successfully pass the proposal for **testnet**, `YOUR_DEPOSIT` should be slightly less than `min_deposit` value (for example, `40000000000000000000inj`). After that, you should contact the Injective dev team. Dev team will top up your deposit to `min_deposit` and vote for your proposal.
+
+To successfully pass the proposal for **testnet**, `YOUR_DEPOSIT` should be slightly less than `min_deposit`
+value (for example, `40000000000000000000inj`). After that you should contact the Injective dev team. Dev team will
+top up your deposit to `min_deposit` and vote for your proposal.
## RevokeProviderPrivilegeProposal
-Oracle provider privileges can be revoked from your account through a `RevokeProviderPrivilegeProposal`.
+Oracle provider privileges can be revoked from your account through a `RevokeProviderPrivilegeProposal`.
```protobuf
// Revoke Privileges
@@ -147,7 +151,9 @@ message AuthorizeBandOracleRequestProposal {
## UpdateBandOracleRequestProposal
-This proposal is used for deleting a request or updating the request. When `DeleteRequestId` is not zero, it deletes the request with the id and finish its execution. When `DeleteRequestId` is zero, it updates the request with id `UpdateOracleRequest.RequestId` to UpdateOracleRequest.
+This proposal is used for deleting a request or updating the request.
+When `DeleteRequestId` is not zero, it deletes the request with the id and finish its execution.
+When `DeleteRequestId` is zero, it update the request with id `UpdateOracleRequest.RequestId` to UpdateOracleRequest.
```protobuf
message UpdateBandOracleRequestProposal {
@@ -163,7 +169,8 @@ message UpdateBandOracleRequestProposal {
## EnableBandIBCProposal
-This proposal is to enable IBC connection between Band chain and Injective chain. When the proposal is approved, it updates the BandIBCParams into the newer one configured on the proposal.
+This proposal is to enable IBC connection between Band chain and Injective chain.
+When the proposal is approved, it updates the BandIBCParams into newer one configured on the proposal.
```protobuf
message EnableBandIBCProposal {
@@ -177,7 +184,7 @@ message EnableBandIBCProposal {
}
```
-The details of `BandIBCParams`, can be checked at [**State**](01_state.md)
+The details of `BandIBCParams`, can be checked at **[State](./01_state.md)**
## GrantStorkPublisherPrivilegeProposal
@@ -217,4 +224,4 @@ message RevokeStorkPublisherPrivilegeProposal {
repeated string stork_publishers = 3;
}
-```
+```
\ No newline at end of file
diff --git a/.gitbook/developers/modules/injective/oracle/README.md b/.gitbook/developers/modules/injective/oracle/README.md
index c9ffe7ff..f30bd028 100644
--- a/.gitbook/developers/modules/injective/oracle/README.md
+++ b/.gitbook/developers/modules/injective/oracle/README.md
@@ -1,4 +1,4 @@
-# Oracle
+# `Oracle`
## Abstract
@@ -6,30 +6,34 @@ This specification specifies the oracle module, which is primarily used by the `
## Workflow
-1. New price feed providers must first obtain oracle privileges through a governance proposal, which grants privileges to a list of relayers. The exception to this is for the Coinbase price oracle, as anyone can send Coinbase price updates since they are already exclusively signed by the Coinbase oracle private key.\
+1. New price feed providers must first obtain oracle privileges through a governance proposal which grants privileges to a list of relayers. The exception to this is for the Coinbase price oracle, as anyone can send Coinbase price updates since they are already exclusively signed by the Coinbase oracle private key.
**Example Grant Proposals**: `GrantBandOraclePrivilegeProposal`, `GrantPriceFeederPrivilegeProposal`
-2. Once the governance proposal is approved, the specified relayers can publish oracle data by sending relay messages specific to their oracle type.\
- **Example Relay Messages**:`MsgRelayBandRates`, `MsgRelayPriceFeedPrice`, `MsgRelayCoinbaseMessages` etc.
+2. Once the governance proposal is approved, the specified relayers can publish oracle data by sending relay messages specific to their oracle type.
+ **Example Relay Messages**:`MsgRelayBandRates`, `MsgRelayPriceFeedPrice`, `MsgRelayCoinbaseMessages` etc
3. Upon receiving the relay message, the oracle module checks if the relayer account has grant privileges and persists the latest price data in the state.
4. Other Cosmos-SDK modules can then fetch the latest price data for a specific provider by querying the oracle module.
-**Note**: In case of any discrepancy, the price feed privileges can be revoked through governance\
+**Note**: In case of any discrepancy, the price feed privileges can be revoked through governance
**Example Revoke Proposals**: `RevokeBandOraclePrivilegeProposal`, `RevokePriceFeederPrivilegeProposal` etc
## Band IBC integration flow
-Cosmos SDK blockchains are able to interact with each other using IBC and Injective support the feature to fetch price feed from BandChain via IBC.
+Cosmos SDK blockchains are able to interact with each other using IBC and Injective support the feature to fetch price feed from bandchain via IBC.
1. To communicate with BandChain's oracle using IBC, Injective Chain must first initialize a communication channel with the oracle module on the BandChain using relayers.
+
2. Once the connection has been established, a pair of channel identifiers is generated -- one for the Injective Chain and one for Band. The channel identifier is used by Injective Chain to route outgoing oracle request packets to Band. Similarly, Band's oracle module uses the channel identifier when sending back the oracle response.
+
3. To enable band IBC integration after setting up communication channel, the governance proposal for `EnableBandIBCProposal` should pass.
+
4. And then, the list of prices to be fetched via IBC should be determined by `AuthorizeBandOracleRequestProposal` and `UpdateBandOracleRequestProposal`.
-5. Once BandIBC is enabled, chain periodically sends price request IBC packets (`OracleRequestPacketData`) to bandchain and bandchain responds with the price via IBC packet (`OracleResponsePacketData`). Band chain is providing prices when there are threshold number of data providers confirm, and it takes time to get the price after sending requests. To request price before the configured interval, any user can broadcast a `MsgRequestBandIBCRates` message, which is instantly executed.
+
+5. Once BandIBC is enabled, chain periodically sends price request IBC packets (`OracleRequestPacketData`) to bandchain and bandchain responds with the price via IBC packet (`OracleResponsePacketData`). Band chain is providing prices when there are threshold number of data providers confirm and it takes time to get the price after sending requests. To request price before the configured interval, any user can broadcast `MsgRequestBandIBCRates` message which is instantly executed.
## Contents
-1. [**State**](01_state.md)
-2. [**Keeper**](02_keeper.md)
-3. [**Messages**](03_messages.md)
-4. [**Proposals**](04_proposals.md)
-5. [**Events**](05_events.md)
+1. **[State](./01_state.md)**
+2. **[Keeper](./02_keeper.md)**
+3. **[Messages](./03_messages.md)**
+4. **[Proposals](./04_proposals.md)**
+5. **[Events](./05_events.md)**
diff --git a/.gitbook/developers/modules/injective/peggy/01_definitions.md b/.gitbook/developers/modules/injective/peggy/01_definitions.md
index a4bd1d7e..037c1da0 100644
--- a/.gitbook/developers/modules/injective/peggy/01_definitions.md
+++ b/.gitbook/developers/modules/injective/peggy/01_definitions.md
@@ -3,28 +3,34 @@ sidebar_position: 1
title: Definitions
---
-# Definitions
+# Intro
-This doc aims to provide an overview of `Peggy` (Injective's Ethereum bridge) from a technical perspective and dive deep into its operational logic. Peggy is the name of the custom Cosmos SDK module built on Injective as well as the Ethereum contract (Peggy.sol) which make up both sides of the bridge. Connected via a middle-man process called `Peggo` users can securely move token assets between networks.
+This doc aims to provide an overview of `Peggy` (Injective's Ethereum bridge) from a technical perspective and dive deep into its operational logic.
+Peggy is the name of the custom Cosmos SDK module built on Injective as well as the Ethereum contract (Peggy.sol) which make up both sides of the bridge.
+Connected via a middle-man process called `Peggo` users can securely move token assets between networks.
To suggest improvements, please open a GitHub issue.
### Key definitions
-Words matter, and we seek clarity in the terminology so we can have clarity in our thinking and communication. To help better understand, some key definitions are:
-
-* `Operator` - this is a person (or people) who control and operate `Validator` and `Orchestrator` processes
-* `Validator` - this is an Injective Chain validating node (e.g., `injectived` process)
-* `Validator Set` - the (active) set of Injective Chain `Validators` (Valset) along with their respective voting power as determined by their stake weight. Each validator is associated with an Ethereum address to be represented on the Ethereum network.
-* `Orchestrator (Peggo)` - the off-chain process (`peggo`) that plays the middleman role between Injective and Ethereum. Orchestrators are responsible for keeping the bridge online and require active endpoints to fully synced Injective (Ethereum) nodes.
-* `Peggy module` - the counterparty Cosmos module for `Peggy contract`. Besides providing services to bridge token assets, it automatically reflects on the active `Validator Set` as it changes over time. The update is later applied on Ethereum via `Peggo`
-* `Peggy Contract` - The Ethereum contract that holds all the ERC-20 tokens. It also maintains a compressed checkpointed representation of the Injective Chain `Validator Set` using `Delegate Keys` and normalized powers.
-* `Delegate Keys` - when an `Operator` sets up their `Orchestrator` for the first time, they register (on Injective) their `Validator`'s address with an Ethereum address. The corresponding key is used to sign messages and represent that validator on Ethereum. Optionally, one delegate Injective Chain account key can be provided to sign Injective messages (e.g., `Claims`) on behalf of the `Validator`
-* `Peggy Tx pool (withdrawals)` - when a user wishes to move their asset from Injective to Ethereum, their individual tx gets pooled with others with the same asset
-* `Peggy Batch pool` - pooled withdrawals are batched together (by an `Orchestrator`) to be signed off and eventually relayed to Ethereum. These batches are kept within this pool.
-* `Claim` - a signed proof (by an `Orchestrator`) that an event occurred in the `Peggy contract`
-* `Attestation` - an aggregate of claims for a particular event nonce emitted from `Peggy contract`. After a majority of `Orchestrators` attests to a claim, the event is acknowledged and executed on Injective.
-* `Majority` - the majority of Injective network, 2/3 + 1 validators
-* `Deposit` - an asset transfer initiated from Ethereum to Injective
-* `Withdrawal` - an asset transfer initiated from Injective to Ethereum (present in `Peggy Tx pool`)
-* `Batch` - a batch of withdrawals with the same token type (present in `Peggy Batch pool`)
+Words matter and we seek clarity in the terminology so we can have clarity in our thinking and communication.
+To help better understand, some key definitions are:
+
+- `Operator` - this is a person (or people) who control and operate `Validator` and `Orchestrator` processes
+- `Validator` - this is an Injective Chain validating node (eg. `injectived` process)
+- `Validator Set` - the (active) set of Injective Chain `Validators` (Valset) along with their respective voting power as determined by their stake weight. Each validator is associated with an Ethereum address to be represented on the Ethereum network
+- `Orchestrator (Peggo)` - the off-chain process (`peggo`) that plays the middleman role between Injective and Ethereum. Orchestrators are responsible for keeping the bridge online and require active endpoints to fully synced Injective (Ethereum) nodes
+- `Peggy module` - the counterparty Cosmos module for `Peggy contract`. Besides providing services to bridge token assets, it automatically reflects on the active `Validator Set` as it changes over time. The update is later applied on Ethereum via `Peggo`
+- `Peggy Contract` - The Ethereum contract that holds all the ERC-20 tokens. It also maintains a compressed checkpointed representation of the Injective Chain `Validator Set` using `Delegate Keys` and normalized powers
+- `Delegate Keys` - when an `Operator` sets up their `Orchestrator` for the first time they register (on Injective) their `Validator`'s address with an Ethereum address. The corresponding key is used to sign messages and represent that validator on Ethereum.
+ Optionally, one delegate Injective Chain account key can be provided to sign Injective messages (eg `Claims`) on behalf of the `Validator`
+- `Peggy Tx pool (withdrawals)` - when a user wishes to move their asset from Injective to Ethereum their individual tx gets pooled with others with the same asset
+- `Peggy Batch pool` - pooled withdrawals are batched together (by an `Orchestrator`) to be signed off and eventually relayed to Ethereum. These batches are kept within this pool
+- `Claim` - a signed proof (by an `Orchestrator`) that an event occurred in the `Peggy contract`
+- `Attestation` - an aggregate of claims for a particular event nonce emitted from `Peggy contract`. After a majority of `Orchestrators` attests to a claim, the event is acknowledged and executed on Injective
+- `Majority` - the majority of Injective network, 2/3 + 1 validators
+- `Deposit` - an asset transfer initiated from Ethereum to Injective
+- `Withdrawal` - an asset transfer initiated from Injective to Ethereum (present in `Peggy Tx pool`)
+- `Batch` - a batch of withdrawals with the same token type (present in `Peggy Batch pool`)
+
+
diff --git a/.gitbook/developers/modules/injective/peggy/02_workflow.md b/.gitbook/developers/modules/injective/peggy/02_workflow.md
index d8b26873..2a7b4742 100644
--- a/.gitbook/developers/modules/injective/peggy/02_workflow.md
+++ b/.gitbook/developers/modules/injective/peggy/02_workflow.md
@@ -13,71 +13,72 @@ To recap, each `Operator` is responsible for maintaining 2 secure processes:
2. The `Orchestrator` service (`peggo orchestrator` process) which interacts with both networks. Implicitly, an RPC endpoint to a fully synced Ethereum node is required as well (see peggo .env example)
Combined, these 2 entities accomplish 3 things:
+- Move token assets from Ethereum to Injective
+- Move token assets from Injective to Ethereum
+- Keep the `Peggy.sol` contract in sync with the active `Validator Set` on Injective
-* Move token assets from Ethereum to Injective
-* Move token assets from Injective to Ethereum
-* Keep the `Peggy.sol` contract in sync with the active `Validator Set` on Injective
-
-It is possible to run `peggo` without ever being a `Validator`. Peggo automatically runs in "relayer mode" when configured to run with an address **not associated** with a `Validator`. In this mode, only 2 things can happen:
-
-* New token batches can be created on Injective
-* Confirmed valsets/batches can be relayed to Ethereum
+It is possible to run `peggo` without ever being a `Validator`. Peggo automatically runs in "relayer mode" when configured to run with an address **not associated** with a `Validator`.
+In this mode, only 2 things can happen:
+* new token batches can be created on Injective
+* confirmed valsets/batches can be relayed to Ethereum
## Types of Assets
### Native Ethereum assets
-Any asset originating from Ethereum which implements the ERC-20 standard can be transferred from Ethereum to Injective by calling the `sendToInjective` function on the [Peggy.sol](https://github.com/InjectiveLabs/peggo/blob/master/solidity/contracts/Peggy.sol) contract, which transfers tokens from the sender's balance to the Peggy contract.
+Any asset originating from Ethereum which implements the ERC-20 standard can be transferred from Ethereum to Injective by calling the `sendToInjective` function on the [Peggy.sol](https://github.com/InjectiveLabs/peggo/blob/master/solidity/contracts/Peggy.sol) contract which transfers tokens from the sender's balance to the Peggy contract.
-The `Operators` all run their `peggo` processes, which submit `MsgDepositClaim` messages describing the deposit they have observed. Once more than 66% of all voting power has submitted a claim for this specific deposit, representative tokens are minted and issued to the Injective Chain address that the sender requested.
+The `Operators` all run their `peggo` processes which submit `MsgDepositClaim` messages describing the deposit they have observed. Once more than 66% of all voting power has submitted a claim for this specific deposit representative tokens are minted and issued to the Injective Chain address that the sender requested.
-These representative tokens have a denomination prefix of `peggy` concatenated with the ERC-20 token hex address, e.g., `peggy0xdac17f958d2ee523a2206206994597c13d831ec7`.
+These representative tokens have a denomination prefix of `peggy` concatenated with the ERC-20 token hex address, e.g. `peggy0xdac17f958d2ee523a2206206994597c13d831ec7`.
### Native Cosmos SDK assets
-An asset native to a Cosmos SDK chain (e.g. `ATOM`) first must be represented on Ethereum before it's possible to bridge it. To do so, the [Peggy contract](https://github.com/InjectiveLabs/peggo/blob/master/solidity/contracts/Peggy.sol) allows anyone to create a new ERC-20 token representing a Cosmos asset by calling the `deployERC20` function.
+An asset native to a Cosmos SDK chain (e.g. `ATOM`) first must be represented on Ethereum before it's possible to bridge it. To do so, the [Peggy contract](https://github.com/InjectiveLabs/peggo/blob/master/solidity/contracts/Peggy.sol) allows anyone to create a new ERC-20 token representing a Cosmos asset by calling the `deployERC20` function.
This endpoint is not permissioned, so it is up to the validators and the users of the Peggy bridge to declare any given ERC-20 token as the representation of a given asset.
-When a user on Ethereum calls `deployERC20`, they pass arguments describing the desired asset. [Peggy.sol](https://github.com/InjectiveLabs/peggo/blob/master/solidity/contracts/Peggy.sol) uses an ERC-20 factory to deploy the actual ERC-20 contract and assigns ownership of the entire balance of the new token to the Peggy contract itself before emitting an `ERC20DeployedEvent`.
+When a user on Ethereum calls `deployERC20` they pass arguments describing the desired asset. [Peggy.sol](https://github.com/InjectiveLabs/peggo/blob/master/solidity/contracts/Peggy.sol) uses an ERC-20 factory to deploy the actual ERC-20 contract and assigns ownership of the entire balance of the new token to the Peggy contract itself before emitting an `ERC20DeployedEvent`.
The peggo orchestrators observe this event and decide if a Cosmos asset has been accurately represented (correct decimals, correct name, no pre-existing representation). If this is the case, the ERC-20 contract address is adopted and stored as the definitive representation of that Cosmos asset on Ethereum.
## `Orchestrator` (Peggo) subprocesses
-The `peggo orchestrator` process consists of 4 subprocesses running concurrently at exact intervals (loops). These are:
-
-* `Signer`, which signs new `Validator Set` updates and `Token Batches` with the `Operator`'s Ethereum keys and submits using [messages](04_messages.md#Ethereum-Signer-messages).
-* `Oracle`, which observes Ethereum events and sends them as [claims](04_messages.md#Oracle-messages) to Injective.
-* `Relayer`, which submits confirmed `Validator Set` updates and `Token Batches` to the `Peggy Contract` on Ethereum.
-* `Batch Creator`, which observes (new) withdrawals on Injective and decides which of these to batch according to their type and the configured `PEGGO_MIN_BATCH_FEE_USD` value.
+The `peggo orchestrator` process consists of 4 subprocesses running concurrently at exact intervals (loops). These are:
+* `Signer` which signs new `Validator Set` updates and `Token Batches` with the `Operator`'s Ethereum keys and submits using [messages](./04_messages.md#Ethereum-Signer-messages).
+* `Oracle` which observes Ethereum events and sends them as [claims](./04_messages.md#Oracle-messages) to Injective.
+* `Relayer` which submits confirmed `Validator Set` updates and `Token Batches` to the `Peggy Contract` on Ethereum
+* `Batch Creator` which observes (new) withdrawals on Injective and decides which of these to batch according to their type and the configured `PEGGO_MIN_BATCH_FEE_USD` value
### Batch Creator
-The purpose of the `Batch Creator` is only in creating token batches on the Injective side. The relevant `Peggy module` RPC is not permissioned, so anyone can create a batch.
+The purpose of the `Batch Creator` is only in creating token batches on the Injective side. The relevant `Peggy module` RPC is not permissioned so anyone can create a batch.
-When a user wants to withdraw assets from Injective to Ethereum, they send a special message to Injective (`MsgSendToEth`), which adds their withdrawal to `Peggy Tx Pool`. `Batch Creator` continually queries the pool for withdrawals (by token type) and issues a `MsgRequestBatch` to Injective when a potential batch satisfies the configured `PEGGO_MIN_BATCH_FEE_USD` value (see .env example).
+When a user wants to withdraw assets from Injective to Ethereum they send a special message to Injective (`MsgSendToEth`) which adds their withdrawal to `Peggy Tx Pool`.
+`Batch Creator` continually queries the pool for withdrawals (by token type) and issues a `MsgRequestBatch` to Injective when a potential batch satisfies the configured `PEGGO_MIN_BATCH_FEE_USD` value (see .env example).
On the receiving end, all pooled withdrawals matching the token type in the request are moved from the `Outgoing Tx Pool` as a single batch and placed in the `Outgoing Batch Pool`.
### Signer
-The responsibility of Signer is to provide confirmations that an `Operator (Orchestrator)` is partaking in bridge activity. Failure to provide these confirmations results in slashing penalties for the orchestrator's `Validator`. In other words, this process **must be running at all times** for a `Validator` node.
+The responsibility of Signer is to provide confirmations that an `Operator (Orchestrator)` is partaking in bridge activity. Failure to provide these confirmations results in slashing penalties for the orchestrator's `Validator`.
+In other words, this process **must be running at all times** for a `Validator` node.
-Any payload moving in the Injective->Ethereum pipeline (`Validator Set` updates/`Token Batches`) requires `Validator` signatures to be successfully relayed to Ethereum. Certain calls on `Peggy Contract` accept an array of signatures to be checked against the `Validator Set` in the contract itself. `Orchestrators` make these signatures with their `Delegate Ethereum address`: this is an Ethereum address decided by the `Operator` upon initial setup ([SetOrchestratorAddress](04_messages.md#setorchestratoraddresses)). This address then represents that validator on the Ethereum blockchain, and will be added as a signing member of the multisig with a weighted voting power as close as possible to the Injective Chain voting power.
+Any payload moving in the Injective->Ethereum pipeline (`Validator Set` updates/`Token Batches`) requires `Validator` signatures to be successfully relayed to Ethereum. Certain calls on `Peggy Contract` accept an array of signatures to be checked against the `Validator Set` in the contract itself.
+`Orchestrators` make these signatures with their `Delegate Ethereum address`: this is an Ethereum address decided by the `Operator` upon initial setup ([SetOrchestratorAddress](./04_messages.md#setorchestratoraddresses)). This address then represents that validator on the Ethereum blockchain and will be added as a signing member of the multisig with a weighted voting power as close as possible to the Injective Chain voting power.
-Whenever `Signer` finds that there is a unconfirmed valset update (token batch) present within the `Peggy Module`, it issues a `MsgConfirmValset` (`MsgConfirmBatch`) as proof that the operating `Validator` is active in bridge activity.
+Whenever `Signer` finds that there is a unconfirmed valset update (token batch) present within the `Peggy Module` it issues a `MsgConfirmValset` (`MsgConfirmBatch`) as proof that the operating `Validator` is active in bridge activity.
### Oracle
-Monitors the Ethereum network for new events involving the `Peggy Contract`.
+Monitors the Ethereum network for new events involving the `Peggy Contract`.
-Every event emitted by the contract has a unique event nonce. This nonce value is crucial in coordinating `Orchestrators` to properly observe contract activity and make sure Injective acknowledges them via `Claims`. Multiple claims of the same nonce make up an `Attestation` and when the majority (2/3) of orchestrators have observed an event its particular logic gets executed on Injective.
+Every event emitted by the contract has a unique event nonce. This nonce value is crucial in coordinating `Orchestrators` to properly observe contract activity and make sure Injective acknowledges them via `Claims`.
+Multiple claims of the same nonce make up an `Attestation` and when the majority (2/3) of orchestrators have observed an event its particular logic gets executed on Injective.
-If 2/3 of the validators can not agree on a single `Attestation`, the oracle is halted. This means no new events will be relayed from Ethereum until some of the validators change their votes. There is no slashing condition for this, with reasoning outlined in the [slashing spec](05_slashing.md)
+If 2/3 of the validators can not agree on a single `Attestation`, the oracle is halted. This means no new events will be relayed from Ethereum until some of the validators change their votes. There is no slashing condition for this, with reasoning outlined in the [slashing spec](./05_slashing.md)
There are 4 types of events emitted from Peggy.sol:
-
1. `TransactionBatchExecutedEvent` - event indicating that a token batch (withdrawals) has been successfully relayed to Ethereum
2. `ValsetUpdatedEvent` - event indicating that a `Validator Set` update has been successfully relayed to Ethereum
3. `SendToInjectiveEvent` - event indicating that a new deposit to Injective has been initiated
@@ -89,76 +90,75 @@ Injective's `Oracle` implementation ignores the last 12 blocks on Ethereum to en
`Relayer` bundles valset updates (or token batches) along with their confirmations into an Ethereum transaction and sends it to the `Peggy contract`.
-Keep in mind that these messages cost a variable amount of money based on wildly changing Ethereum gas prices, so it's not unreasonable for a single batch to cost over a million gas. A major design decision for our relayer rewards was to always issue them on the Ethereum chain. This has downsides, namely some strange behavior in the case of validator set update rewards.
+Keep in mind that these messages cost a variable amount of money based on wildly changing Ethereum gas prices, so it's not unreasonable for a single batch to cost over a million gas.
+A major design decision for our relayer rewards was to always issue them on the Ethereum chain. This has downsides, namely some strange behavior in the case of validator set update rewards.
But the upsides are undeniable, because the Ethereum messages pay `msg.sender` any existing bot in the Ethereum ecosystem will pick them up and try to submit them. This makes the relaying market much more competitive and less prone to cabal like behavior.
-## End-to-end Lifecycle
+## End-to-end Lifecycle
-This document describes the end to end lifecycle of the Peggy bridge.
+This document describes the end to end lifecycle of the Peggy bridge.
### Peggy Smart Contract Deployment
-In order to deploy the Peggy contract, the validator set of the native chain (Injective Chain) must be known. Upon deploying the Peggy contract suite (Peggy Implementation, Proxy contract, and ProxyAdmin contracts), the Peggy contract (the Proxy contract) must be initialized with the validator set. Upon initialization a `ValsetUpdatedEvent` is emitted from the contract.
+In order to deploy the Peggy contract, the validator set of the native chain (Injective Chain) must be known. Upon deploying the Peggy contract suite (Peggy Implementation, Proxy contract, and ProxyAdmin contracts), the Peggy contract (the Proxy contract) must be initialized with the validator set.
+Upon initialization a `ValsetUpdatedEvent` is emitted from the contract.
-The proxy contract is used to upgrade Peggy Implementation contract, which is needed for bug fixing and potential improvements during initial phase. It is a simple wrapper or "proxy" which users interact with directly and is in charge of forwarding transactions to the Peggy implementation contract, which contains the logic. The key concept to understand is that the implementation contract can be replaced, but the proxy (the access point) is never changed.
+The proxy contract is used to upgrade Peggy Implementation contract which is needed for bug fixing and potential improvements during initial phase. It is a simple wrapper or "proxy" which users interact with directly and is in charge of forwarding transactions to the Peggy implementation contract, which contains the logic. The key concept to understand is that the implementation contract can be replaced but the proxy (the access point) is never changed.
-The ProxyAdmin is a central admin for the Peggy proxy, which simplifies management. It controls upgradability and ownership transfers. The ProxyAdmin contract itself has a built-in expiration time which, once expired, prevents the Peggy implementation contract from being upgraded in the future.
+The ProxyAdmin is a central admin for the Peggy proxy, which simplifies management. It controls upgradability and ownership transfers. The ProxyAdmin contract itself has a built-in expiration time which, once expired, prevents the Peggy implementation contract from being upgraded in the future.
Then the following peggy genesis params should be updated:
-
-1. `bridge_ethereum_address` with Peggy proxy contract address
+1. `bridge_ethereum_address` with Peggy proxy contract address
2. `bridge_contract_start_height` with the height at which the Peggy proxy contract was deployed
-This completes the bootstrap of the Peggy bridge and the chain can be started. Afterward, `Operators` should start their `peggo` processes and eventually observe that the initial `ValsetUpdatedEvent` is attested on Injective.
+This completes the bootstrap of the Peggy bridge and the chain can be started. Afterward, `Operators` should start their `peggo` processes and eventually observe that the initial `ValsetUpdatedEvent` is attested on Injective.
### **Updating Injective Chain validator set on Ethereum**
-![img.png](images/valsetupdate.png)
-
-A validator set is a series of Ethereum addresses with attached normalized powers used to represent the Injective validator set (Valset) in the Peggy contract on Ethereum. The Peggy contract stays in sync with the Injective Chain validator set through the following mechanism:
+![img.png](./images/valsetupdate.png)
+A validator set is a series of Ethereum addresses with attached normalized powers used to represent the Injective validator set (Valset) in the Peggy contract on Ethereum. The Peggy contract stays in sync with the Injective Chain validator set through the following mechanism:
1. **Creating a new Valset on Injective:** A new Valset is automatically created on the Injective Chain when either:
- * The cumulative difference of the current validator set powers compared to the last recorded Valset exceeds 5%
- * A validator begins unbonding from the set
+ * the cumulative difference of the current validator set powers compared to the last recorded Valset exceeds 5%
+ * a validator begins unbonding from the set
2. **Confirming a Valset on Injective:** Each `Operator` is responsible for confirming Valset updates that are created on Injective. The `Signer` process sends these confirmations via `MsgConfirmValset` by having the validator's delegated Ethereum key sign over a compressed representation of the Valset data. The `Peggy module` verifies the validity of the signature and persists it to its state.
-3. **Updating the Valset on the Peggy contract:** After a 2/3+ 1 majority of validators have submitted their confirmations for a given Valset, `Relayer` submits the new Valset data to the Peggy contract by calling `updateValset`. The Peggy contract then validates the data, updates the valset checkpoint, transfers valset rewards to sender, and emits a `ValsetUpdatedEvent`.
-4. **Acknowledging the `ValsetUpdatedEvent` on Injective:** `Oracle` witnesses the `ValsetUpdatedEvent` on Ethereum, and sends a `MsgValsetUpdatedClaim`, which informs the `Peggy module` that the Valset has been updated on Ethereum.
-5. **Pruning Valsets on Injective:** Once a 2/3 majority of validators send their claim for a given `ValsetUpdateEvent`, all the previous valsets are pruned from the `Peggy module` state.
-6. **Validator Slashing:** Validators are subject to slashing after a configured window of time (`SignedValsetsWindow`) for not providing confirmations. Read more [valset slashing](05_slashing.md)
+3. **Updating the Valset on the Peggy contract:** After a 2/3+ 1 majority of validators have submitted their confirmations for a given Valset, `Relayer` submits the new Valset data to the Peggy contract by calling `updateValset`.
+The Peggy contract then validates the data, updates the valset checkpoint, transfers valset rewards to sender and emits a `ValsetUpdatedEvent`.
+4. **Acknowledging the `ValsetUpdatedEvent` on Injective:** `Oracle` witnesses the `ValsetUpdatedEvent` on Ethereum, and sends a `MsgValsetUpdatedClaim` which informs the `Peggy module` that the Valset has been updated on Ethereum.
+5. **Pruning Valsets on Injective:** Once a 2/3 majority of validators send their claim for a given `ValsetUpdateEvent`, all the previous valsets are pruned from the `Peggy module` state.
+6. **Validator Slashing:** Validators are subject to slashing after a configured window of time (`SignedValsetsWindow`) for not providing confirmations. Read more [valset slashing](./05_slashing.md)
-***
+----
### **Transferring ERC-20 tokens from Ethereum to Injective**
-![img.png](images/SendToCosmos.png)
+![img.png](./images/SendToCosmos.png)
ERC-20 tokens are transferred from Ethereum to Injective through the following mechanism:
+ 1. **Depositing ERC-20 tokens on the Peggy Contract:** A user initiates a transfer of ERC-20 tokens from Ethereum to Injective by calling the `sendToInjective` function on the Peggy contract which deposits tokens on the Peggy contract and emits a `SendToInjectiveEvent`.
+ The deposited tokens will remain locked until withdrawn at some undetermined point in the future. This event contains the amount and type of tokens, as well as a destination address on the Injective Chain to receive the funds.
-1. **Depositing ERC-20 tokens on the Peggy Contract:** A user initiates a transfer of ERC-20 tokens from Ethereum to Injective by calling the `sendToInjective` function on the Peggy contract, which deposits tokens on the Peggy contract and emits a `SendToInjectiveEvent`. The deposited tokens will remain locked until withdrawn at some undetermined point in the future. This event contains the amount and type of tokens, as well as a destination address on the Injective Chain to receive the funds.
-2. **Confirming the deposit:** Each `Oracle` witnesses the `SendToInjectiveEvent` and sends a `MsgDepositClaim`, which contains the deposit information to the Peggy module.
-3. **Minting tokens on the Injective:** Once a majority of validators confirm the deposit claim, the deposit is processed.
-
-* If the asset is Ethereum originated, the tokens are minted and transferred to the intended recipient's address on the Injective Chain.
-* If the asset is Cosmos-SDK originated, the coins are unlocked and transferred to the intended recipient's address on the Injective Chain.
+ 2. **Confirming the deposit:** Each `Oracle` witnesses the `SendToInjectiveEvent` and sends a `MsgDepositClaim` which contains the deposit information to the Peggy module.
-***
+ 3. **Minting tokens on the Injective:** Once a majority of validators confirm the deposit claim, the deposit is processed.
+ - If the asset is Ethereum originated, the tokens are minted and transferred to the intended recipient's address on the Injective Chain.
+ - If the asset is Cosmos-SDK originated, the coins are unlocked and transferred to the intended recipient's address on the Injective Chain.
+-----
### **Withdrawing tokens from Injective to Ethereum**
-![img.png](images/SendToEth.png)
+![img.png](./images/SendToEth.png)
1. **Request Withdrawal from Injective:** A user can initiate the transfer of assets from the Injective Chain to Ethereum by sending a `MsgSendToEth` transaction to the peggy module.
- * If the asset is Ethereum native, the represented tokens are burnt.
- * If the asset is Cosmos SDK native, coins are locked in the module. The withdrawal is then added to `Outgoing Tx Pool`.
+ * If the asset is Ethereum native, the represented tokens are burnt.
+ * If the asset is Cosmos SDK native, coins are locked in the module. The withdrawal is then added to `Outgoing Tx Pool`.
2. **Batch Creation:** A `Batch Creator` observes the pool of pending withdrawals. The batch creator (or any external third party) then requests a batch of to be created for given token by sending `MsgRequestBatch` to the Injective Chain. The `Peggy module` collects withdrawals matching the token type into a batch and puts it in `Outgoing Batch Pool`.
-3. **Batch Confirmation:** Upon detecting the existence of an Outgoing Batch, the `Signer` signs over the batch with its Ethereum key and submits a `MsgConfirmBatch` tx to the Peggy module.
-4. **Submit Batch to Peggy Contract:** Once a majority of validators confirm the batch, the `Relayer` calls `submitBatch` on the Peggy contract with the batch and its confirmations. The Peggy contract validates the signatures, updates the batch checkpoint, processes the batch ERC-20 withdrawals, transfers the batch fee to the tx sender, and emits a `TransactionBatchExecutedEvent`.
+3. **Batch Confirmation:** Upon detecting the existence of an Outgoing Batch, the `Signer` signs over the batch with its Ethereum key and submits a `MsgConfirmBatch` tx to the Peggy module.
+4. **Submit Batch to Peggy Contract:** Once a majority of validators confirm the batch, the `Relayer` calls `submitBatch` on the Peggy contract with the batch and its confirmations. The Peggy contract validates the signatures, updates the batch checkpoint, processes the batch ERC-20 withdrawals, transfers the batch fee to the tx sender and emits a `TransactionBatchExecutedEvent`.
5. **Send Withdrawal Claim to Injective:** `Oracles` witness the `TransactionBatchExecutedEvent` and send a `MsgWithdrawClaim` containing the withdrawal information to the Peggy module.
-6. **Prune Batches** Once a majority of validators submit their `MsgWithdrawClaim` , the batch is deleted along and all previous batches are cancelled on the Peggy module. Withdrawals in cancelled batches get moved back into `Outgoing Tx Pool`.
-7. **Batch Slashing:** Validators are responsible for confirming batches and are subject to slashing if they fail to do so. Read more on [batch slashing](05_slashing.md).
+6. **Prune Batches** Once a majority of validators submit their `MsgWithdrawClaim` , the batch is deleted along and all previous batches are cancelled on the Peggy module. Withdrawals in cancelled batches get moved back into `Outgoing Tx Pool`.
+7. **Batch Slashing:** Validators are responsible for confirming batches and are subject to slashing if they fail to do so. Read more on [batch slashing](./05_slashing.md).
-{% hint style="info" %}
-**Note:** While batching reduces individual withdrawal costs dramatically, this comes at the cost of latency and implementation complexity. If a user wishes to withdraw quickly, they will have to pay a much higher fee. However, this fee will be about the same as the fee every withdrawal from the bridge would require in a non-batching system.
-{% endhint %}
+Note while that batching reduces individual withdrawal costs dramatically, this comes at the cost of latency and implementation complexity. If a user wishes to withdraw quickly they will have to pay a much higher fee. However this fee will be about the same as the fee every withdrawal from the bridge would require in a non-batching system.
diff --git a/.gitbook/developers/modules/injective/peggy/03_state.md b/.gitbook/developers/modules/injective/peggy/03_state.md
index 5150b773..e589efe6 100644
--- a/.gitbook/developers/modules/injective/peggy/03_state.md
+++ b/.gitbook/developers/modules/injective/peggy/03_state.md
@@ -9,20 +9,21 @@ This doc lists all the data Peggy module reads/writes to its state as KV pairs
### Module Params
-Params is a module-wide configuration structure that stores parameters and defines overall functioning of the peggy module. Detailed specification for each parameter can be found in the [Parameters section](08_params.md).
+Params is a module-wide configuration structure that stores parameters and defines overall functioning of the peggy module. Detailed specification for each parameter can be found in the [Parameters section](08_params.md).
| key | Value | Type | Encoding |
-| ------------- | ------------- | -------------- | ---------------- |
+|---------------|---------------|----------------|------------------|
| `[]byte{0x4}` | Module params | `types.Params` | Protobuf encoded |
+
### Validator Info
-#### Ethereum Address by Validator
+#### Ethereum Address by Validator
-Stores `Delegate Ethereum address` indexed by the `Validator`'s account address
+Stores `Delegate Ethereum address` indexed by the `Validator`'s account address
| key | Value | Type | Encoding |
-| ------------------------------------- | ---------------- | ---------------- | ---------------- |
+|---------------------------------------|------------------|------------------|------------------|
| `[]byte{0x1} + []byte(validatorAddr)` | Ethereum address | `common.Address` | Protobuf encoded |
#### Validator by Ethereum Address
@@ -30,17 +31,19 @@ Stores `Delegate Ethereum address` indexed by the `Validator`'s account address
Stores `Validator` account address indexed by the `Delegate Ethereum address`
| key | Value | Type | Encoding |
-| ----------------------------------- | ----------------- | ---------------- | ---------------- |
+|-------------------------------------|-------------------|------------------|------------------|
| `[]byte{0xfb} + []byte(ethAddress)` | Validator address | `sdk.ValAddress` | Protobuf encoded |
+
#### OrchestratorValidator
-When a validator would like to delegate their voting power to another key. The value is stored using the orchestrator address as the key.
+When a validator would like to delegate their voting power to another key. The value is stored using the orchestrator address as the key
| Key | Value | Type | Encoding |
-| ----------------------------------- | -------------------------------------------- | -------- | ---------------- |
+|-------------------------------------|----------------------------------------------|----------|------------------|
| `[]byte{0xe8} + []byte(AccAddress)` | Orchestrator address assigned by a validator | `[]byte` | Protobuf encoded |
+
### Valset
This is the validator set of the bridge. Created automatically by `Peggy module` during EndBlocker.
@@ -59,7 +62,7 @@ type Valset struct {
```
| key | Value | Type | Encoding |
-| ------------------------------------------ | ------------- | -------------- | ---------------- |
+|--------------------------------------------|---------------|----------------|------------------|
| `[]byte{0x2} + nonce (big endian encoded)` | Validator set | `types.Valset` | Protobuf encoded |
### SlashedValsetNonce
@@ -67,33 +70,35 @@ type Valset struct {
The latest validator set slash nonce. This is used to track which validator set needs to be slashed and which already has been.
| Key | Value | Type | Encoding |
-| -------------- | ----- | ------ | ---------------------- |
+|----------------|-------|--------|------------------------|
| `[]byte{0xf5}` | Nonce | uint64 | encoded via big endian |
### ValsetNonce
-Nonce of the latest validator set. Updated on each new validator set.
+Nonce of the latest validator set. Updated on each new validator set.
| key | Value | Type | Encoding |
-| -------------- | ----- | -------- | ---------------------- |
+|----------------|-------|----------|------------------------|
| `[]byte{0xf6}` | Nonce | `uint64` | encoded via big endian |
+
### Valset Confirmation
-`Singer` confirmation for a particular validator set. See [oracle messages](04_messages.md#ValsetConfirm).
+`Singer` confirmation for a particular validator set. See [oracle messages](./04_messages.md#ValsetConfirm)
| Key | Value | Type | Encoding |
-| ------------------------------------------- | ---------------------- | ------------------------ | ---------------- |
+|---------------------------------------------|------------------------|--------------------------|------------------|
| `[]byte{0x3} + (nonce + []byte(AccAddress)` | Validator Confirmation | `types.MsgValsetConfirm` | Protobuf encoded |
### Batch Confirmation
-`Singer` confirmation for a particular token batch. See [oracle messages](04_messages.md#ConfirmBatch).
+`Singer` confirmation for a particular token batch. See [oracle messages](./04_messages.md#ConfirmBatch)
| Key | Value | Type | Encoding |
-| ------------------------------------------------------------------- | ---------------------------- | ----------------------- | ---------------- |
+|---------------------------------------------------------------------|------------------------------|-------------------------|------------------|
| `[]byte{0xe1} + []byte(tokenContract) + nonce + []byte(AccAddress)` | Validator Batch Confirmation | `types.MsgConfirmBatch` | Protobuf encoded |
+
### OutgoingTransferTx
User withdrawals are pooled together in `Peggy Tx Pool` ready to be batched later by a `Batch Creator`.
@@ -111,22 +116,25 @@ type OutgoingTransferTx struct {
```
| Key | Value | Type | Encoding |
-| -------------------------------------- | ---------------------------- | -------- | ------------------ |
+|----------------------------------------|------------------------------|----------|--------------------|
| `[]byte{0x7} + []byte("lastTxPoolId")` | nonce of outgoing withdrawal | `uint64` | Big endian encoded |
+
### LastTXPoolID
Monotonically increasing value for each withdrawal received by Injective
| Key | Value | Type | Encoding |
-| -------------------------------------- | ----------------------- | -------- | ------------------ |
+|----------------------------------------|-------------------------|----------|--------------------|
| `[]byte{0x6} + []byte("lastTxPoolId")` | Last used withdrawal ID | `uint64` | Big endian encoded |
+
### OutgoingTxBatch
`OutgoingTxBatch` represents a collection of withdrawals of the same token type. Created on every successful `MsgRequestBatch`.
-Stored in two possible ways, first with a height and second without (unsafe). Unsafe is used for testing and export and import of state. Currently [Peggy.sol](https://github.com/InjectiveLabs/peggo/blob/master/solidity/contracts/Peggy.sol) is hardcoded to only accept batches with a single token type and only pay rewards in that same token type.
+Stored in two possible ways, first with a height and second without (unsafe). Unsafe is used for testing and export and import of state.
+Currently [Peggy.sol](https://github.com/InjectiveLabs/peggo/blob/master/solidity/contracts/Peggy.sol) is hardcoded to only accept batches with a single token type and only pay rewards in that same token type.
```go
type OutgoingTxBatch struct {
@@ -139,24 +147,25 @@ type OutgoingTxBatch struct {
```
| key | Value | Type | Encoding |
-| ------------------------------------------------------------------ | -------------------------------- | ----------------------- | ---------------- |
+|--------------------------------------------------------------------|----------------------------------|-------------------------|------------------|
| `[]byte{0xa} + []byte(tokenContract) + nonce (big endian encoded)` | A batch of outgoing transactions | `types.OutgoingTxBatch` | Protobuf encoded |
| `[]byte{0xb} + block (big endian encoded)` | A batch of outgoing transactions | `types.OutgoingTxBatch` | Protobuf encoded |
+
### LastOutgoingBatchID
Monotonically increasing value for each batch created on Injective by some `Batch Creator`
| Key | Value | Type | Encoding |
-| ------------------------------------- | ------------------ | -------- | ------------------ |
+|---------------------------------------|--------------------|----------|--------------------|
| `[]byte{0x7} + []byte("lastBatchId")` | Last used batch ID | `uint64` | Big endian encoded |
### SlashedBlockHeight
-Represents the latest slashed block height. There is always only a singe value stored.
+Represents the latest slashed block height. There is always only a singe value stored.
| Key | Value | Type | Encoding |
-| -------------- | --------------------------------------- | -------- | ------------------ |
+|----------------|-----------------------------------------|----------|--------------------|
| `[]byte{0xf7}` | Latest height a batch slashing occurred | `uint64` | Big endian encoded |
### LastUnbondingBlockHeight
@@ -164,15 +173,15 @@ Represents the latest slashed block height. There is always only a singe value s
Represents the latest bloch height at which a `Validator` started unbonding from the `Validator Set`. Used to determine slashing conditions.
| Key | Value | Type | Encoding |
-| -------------- | ---------------------------------------------------- | -------- | ------------------ |
+|----------------|------------------------------------------------------|----------|--------------------|
| `[]byte{0xf8}` | Latest height at which a Validator started unbonding | `uint64` | Big endian encoded |
### TokenContract & Denom
-A denom that is originally from a counter chain will be from a contract. The token contract and denom are stored in two ways. First, the denom is used as the key and the value is the token contract. Second, the contract is used as the key, the value is the denom the token contract represents.
+A denom that is originally from a counter chain will be from a contract. The token contract and denom are stored in two ways. First, the denom is used as the key and the value is the token contract. Second, the contract is used as the key, the value is the denom the token contract represents.
| Key | Value | Type | Encoding |
-| -------------------------------------- | ---------------------- | -------- | --------------------- |
+|----------------------------------------|------------------------|----------|-----------------------|
| `[]byte{0xf3} + []byte(denom)` | Token contract address | `[]byte` | stored in byte format |
| `[]byte{0xf4} + []byte(tokenContract)` | Token denom | `[]byte` | stored in byte format |
@@ -181,15 +190,16 @@ A denom that is originally from a counter chain will be from a contract. The tok
This entry represents the last observed Valset that was successfully relayed to Ethereum. Updates after an attestation of `ValsetUpdatedEvent` has been processed on Injective.
| Key | Value | Type | Encoding |
-| -------------- | -------------------------------- | -------------- | ---------------- |
+|----------------|----------------------------------|----------------|------------------|
| `[]byte{0xfa}` | Last observed Valset on Ethereum | `types.Valset` | Protobuf encoded |
+
### LastEventNonce
The nonce of the last observed event on Ethereum. This is set when `TryAttestation()` is called. There is always only a single value held in this store.
| Key | Value | Type | Encoding |
-| -------------- | ------------------------- | -------- | ------------------ |
+|----------------|---------------------------|----------|--------------------|
| `[]byte{0xf2}` | Last observed event nonce | `uint64` | Big endian encoded |
### LastObservedEthereumHeight
@@ -197,9 +207,10 @@ The nonce of the last observed event on Ethereum. This is set when `TryAttestati
This block height of the last observed event on Ethereum. There will always only be a single value stored in this store.
| Key | Value | Type | Encoding |
-| -------------- | ----------------------------- | -------- | ---------------- |
+|----------------|-------------------------------|----------|------------------|
| `[]byte{0xf9}` | Last observed Ethereum Height | `uint64` | Protobuf encoded |
+
### LastEventByValidator
This is the last observed event on Ethereum from a particular `Validator`. Updated every time the asssociated `Orchestrator` sends an event claim.
@@ -212,12 +223,13 @@ type LastClaimEvent struct {
```
| Key | Value | Type | Encoding |
-| ------------------------------------------ | ------------------------------------- | ---------------------- | ---------------- |
+|--------------------------------------------|---------------------------------------|------------------------|------------------|
| `[]byte{0xf1} + []byte(validator address)` | Last observed event by some Validator | `types.LastClaimEvent` | Protobuf encoded |
+
### Attestation
-Attestation is an aggregate of claims that eventually becomes observed by all orchestrators as more votes (claims) are coming in. Once observed, the claim's particular logic gets executed.
+Attestation is an aggregate of claims that eventually becomes observed by all orchestrators as more votes (claims) are coming in. Once observed the claim's particular logic gets executed.
Each attestation is bound to a unique event nonce (generated by `Peggy contract`) and they must be processed in order. This is a correctness issue, if relaying out of order transaction replay attacks become possible.
@@ -229,23 +241,25 @@ type Attestation struct {
Claim *types.Any
}
```
-
| Key | Value | Type | Encoding |
-| -------------------------------------------------------------------- | ------------------------------------- | ------------------- | ---------------- |
+|----------------------------------------------------------------------|---------------------------------------|---------------------|------------------|
| `[]byte{0x5} + event nonce (big endian encoded) + []byte(claimHash)` | Attestation of occurred events/claims | `types.Attestation` | Protobuf encoded |
### PastEthSignatureCheckpoint
-A computed hash indicating that a validator set/token batch in fact existed on Injective. This checkpoint also exists in `Peggy contract`. Updated on each new valset update and token batch creation.
+A computed hash indicating that a validator set/token batch in fact existed on Injective. This checkpoint also exists in `Peggy contract`.
+Updated on each new valset update and token batch creation.
+
| Key | Value | Type | Encoding |
-| -------------- | ----------------------------------------- | ----------------- | -------------------- |
+|----------------|-------------------------------------------|-------------------|----------------------|
| `[]byte{0x1b}` | Last created checkpoint hash on Injective | `gethcommon.Hash` | store in byte format |
### EthereumBlacklist
A list of known malicious Ethereum addresses that are prevented from using the bridge.
-| Key | Value | Type | Encoding |
-| ----------------------------------------- | ------------------- | ----------------- | ---------------------- |
-| `[]byte{0x1c} + []byte(ethereum address)` | Empty \[]byte slice | `gethcommon.Hash` | stored in byte format] |
+| Key | Value | Type | Encoding |
+|-------------------------------------------|--------------------|-------------------|------------------------|
+| `[]byte{0x1c} + []byte(ethereum address)` | Empty []byte slice | `gethcommon.Hash` | stored in byte format] |
+
diff --git a/.gitbook/developers/modules/injective/peggy/04_messages.md b/.gitbook/developers/modules/injective/peggy/04_messages.md
index a278daee..d2f14516 100644
--- a/.gitbook/developers/modules/injective/peggy/04_messages.md
+++ b/.gitbook/developers/modules/injective/peggy/04_messages.md
@@ -5,15 +5,16 @@ title: Messages
# Messages
-This is a reference document for Peggy message types. For code reference and exact arguments, see the [proto definitions](https://github.com/InjectiveLabs/injective-core/blob/master/proto/injective/peggy/v1/msgs.proto).
+This is a reference document for Peggy message types. For code reference and exact arguments see the [proto definitions](https://github.com/InjectiveLabs/injective-core/blob/master/proto/injective/peggy/v1/msgs.proto).
## User messages
-These are messages sent on the Injective Chain peggy module by the end user. See [workflow](02_workflow.md) for a more detailed summary of the entire deposit and withdraw process.
+These are messages sent on the Injective Chain peggy module by the end user. See [workflow](./02_workflow.md) for a more detailed summary of the entire deposit and withdraw process.
### SendToEth
-Sent to Injective whenever a user wishes to make a withdrawal back to Ethereum. The submitted amount is removed from the user's balance immediately. The withdrawal is added to the outgoing tx pool as a `types.OutgoingTransferTx` where it will remain until it is included in a batch.
+Sent to Injective whenever a user wishes to make a withdrawal back to Ethereum. Submitted amount is removed from the user's balance immediately.
+The withdrawal is added to the outgoing tx pool as a `types.OutgoingTransferTx` where it will remain until it is included in a batch.
```go
type MsgSendToEth struct {
@@ -35,7 +36,7 @@ type MsgCancelSendToEth struct {
Sender string // original sender of the withdrawal
}
-```
+```
### SubmitBadSignatureEvidence
@@ -55,7 +56,10 @@ These messages are sent by the `Batch Creator` subprocess of `peggo`
### RequestBatch
-This message is sent whenever some `Batch Creator` finds pooled withdrawals that when batched would satisfy their minimum batch fee (`PEGGO_MIN_BATCH_FEE_USD`). After receiving this message, the `Peggy module` collects all withdrawals of the requested token denom, creates a unique token batch (`types.OutgoingTxBatch`) and places it in the `Outgoing Batch pool`. Withdrawals that are batched cannot be cancelled with `MsgCancelSendToEth`.
+This message is sent whenever some `Batch Creator` finds pooled withdrawals that when batched would satisfy their minimum batch fee (`PEGGO_MIN_BATCH_FEE_USD`).
+After receiving this message the `Peggy module` collects all withdrawals of the requested token denom, creates a unique token batch (`types.OutgoingTxBatch`) and places it in the `Outgoing Batch pool`.
+Withdrawals that are batched cannot be cancelled with `MsgCancelSendToEth`.
+
```go
type MsgRequestBatch struct {
@@ -64,13 +68,15 @@ type MsgRequestBatch struct {
}
```
+
## Oracle Messages
These messages are sent by the `Oracle` subprocess of `peggo`
### DepositClaim
-Sent to Injective when a `SendToInjectiveEvent` is emitted from the `Peggy contract`. This occurs whenever a user is making an individual deposit from Ethereum to Injective.
+Sent to Injective when a `SendToInjectiveEvent` is emitted from the `Peggy contract`.
+This occurs whenever a user is making an individual deposit from Ethereum to Injective.
```go
type MsgDepositClaim struct {
@@ -86,7 +92,8 @@ type MsgDepositClaim struct {
### WithdrawClaim
-Sent to Injective when a `TransactionBatchExecutedEvent` is emitted from the `Peggy contract`. This occurs when a `Relayer` has successfully called `submitBatch` on the contract to complete a batch of withdrawals.
+Sent to Injective when a `TransactionBatchExecutedEvent` is emitted from the `Peggy contract`.
+This occurs when a `Relayer` has successfully called `submitBatch` on the contract to complete a batch of withdrawals.
```go
type MsgWithdrawClaim struct {
@@ -100,7 +107,8 @@ type MsgWithdrawClaim struct {
### ValsetUpdatedClaim
-Sent to Injective when a `ValsetUpdatedEvent` is emitted from the `Peggy contract`. This occurs when a `Relayer` has successfully called `updateValset` on the contract to update the `Validator Set` on Ethereum.
+Sent to Injective when a `ValsetUpdatedEvent` is emitted from the `Peggy contract`.
+This occurs when a `Relayer` has successfully called `updateValset` on the contract to update the `Validator Set` on Ethereum.
```go
@@ -117,7 +125,8 @@ type MsgValsetUpdatedClaim struct {
### ERC20DeployedClaim
-Sent to Injective when a `ERC20DeployedEvent` is emitted from the `Peggy contract`. This occurs whenever the `deployERC20` method is called on the contract to issue a new token asset eligible for bridging.
+Sent to Injective when a `ERC20DeployedEvent` is emitted from the `Peggy contract`.
+This occurs whenever the `deployERC20` method is called on the contract to issue a new token asset eligible for bridging.
```go
type MsgERC20DeployedClaim struct {
@@ -132,13 +141,15 @@ type MsgERC20DeployedClaim struct {
}
```
+
## Signer Messages
These messages are sent by the `Signer` subprocess of `peggo`
### ConfirmBatch
-When `Signer` finds a batch that the `Orchestrator` (`Validator`) has not signed off, it constructs a signature with its `Delegated Ethereum Key` and sends the confirmation to Injective. It's crucial that a `Validator` eventually provides their confirmation for a created batch, as they will be slashed otherwise.
+When `Signer` finds a batch that the `Orchestrator` (`Validator`) has not signed off, it constructs a signature with its `Delegated Ethereum Key` and sends the confirmation to Injective.
+It's crucial that a `Validator` eventually provides their confirmation for a created batch as they will be slashed otherwise.
```go
type MsgConfirmBatch struct {
@@ -152,7 +163,8 @@ type MsgConfirmBatch struct {
### ValsetConfirm
-When `Signer` finds a valset update that the `Orchestrator` (`Validator`) has not signed off, it constructs a signature with its `Delegated Ethereum Key` and sends the confirmation to Injective. It's crucial that a `Validator` eventually provides their confirmation for a created valset update, as they will be slashed otherwise.
+When `Signer` finds a valset update that the `Orchestrator` (`Validator`) has not signed off, it constructs a signature with its `Delegated Ethereum Key` and sends the confirmation to Injective.
+It's crucial that a `Validator` eventually provides their confirmation for a created valset update as they will be slashed otherwise.
```go
type MsgValsetConfirm struct {
@@ -173,7 +185,8 @@ These are messages sent directly using the validator's message key.
### SetOrchestratorAddresses
-Sent to Injective by an `Operator` managing a `Validator` node. Before being able to start their `Orchestrator` (`peggo`) process, they must register a chosen Ethereum address to represent their `Validator` on Ethereum. Optionally, an additional Injective address can be provided (`Orchestrator` field) to represent that `Validator` in the bridging process (`peggo`). Defaults to `Validator`'s own address if omitted.
+Sent to Injective by an `Operator` managing a `Validator` node. Before being able to start their `Orchestrator` (`peggo`) process, they must register a chosen Ethereum address to represent their `Validator` on Ethereum.
+Optionally, an additional Injective address can be provided (`Orchestrator` field) to represent that `Validator` in the bridging process (`peggo`). Defaults to `Validator`'s own address if omitted.
```go
type MsgSetOrchestratorAddresses struct {
@@ -182,5 +195,5 @@ type MsgSetOrchestratorAddresses struct {
EthAddress string // the Sender's (Validator) delegated Ethereum address
}
```
+This message sets the Orchestrator's delegate keys.
-This message sets the Orchestrator's delegate keys.
diff --git a/.gitbook/developers/modules/injective/peggy/05_slashing.md b/.gitbook/developers/modules/injective/peggy/05_slashing.md
index ffa4a651..41d2fa40 100644
--- a/.gitbook/developers/modules/injective/peggy/05_slashing.md
+++ b/.gitbook/developers/modules/injective/peggy/05_slashing.md
@@ -4,10 +4,11 @@ title: Slashing
---
# Slashing
-
### Security Concerns
-The **Validator Set** is the actual set of keys with stake behind them, which are slashed for double-signs or other misbehavior. We typically consider the security of a chain to be the security of a _Validator Set_. This varies on each chain, but is our gold standard. Even IBC offers no more security than the minimum of both involved Validator Sets.
+The **Validator Set** is the actual set of keys with stake behind them, which are slashed for double-signs or other
+misbehavior. We typically consider the security of a chain to be the security of a _Validator Set_. This varies on
+each chain, but is our gold standard. Even IBC offers no more security than the minimum of both involved Validator Sets.
The **Eth bridge relayer** is a binary run alongside the main `injectived` daemon by the validator set. It exists purely as a matter of code organization and is in charge of signing Ethereum transactions, as well as observing events on Ethereum and bringing them into the Injective Chain state. It signs transactions bound for Ethereum with an Ethereum key, and signs over events coming from Ethereum with an Injective Chain account key. We can add slashing conditions to any mis-signed message by any _Eth Signer_ run by the _Validator Set_ and be able to provide the same security as the _Validator Set_, just a different module detecting evidence of malice and deciding how much to slash. If we can prove a transaction signed by any _Eth Signer_ of the _Validator Set_ was illegal or malicious, then we can slash on the Injective Chain side and potentially provide 100% of the security of the _Validator Set_. Note that this also has access to the 3 week unbonding period to allow evidence to slash even if they immediately unbond.
@@ -16,7 +17,6 @@ Below are various slashing conditions we use in Peggy.
## PEGGYSLASH-01: Signing fake validator set or tx batch evidence
This slashing condition is intended to stop validators from signing over a validator set and nonce that has never existed on the Injective Chain. It works via an evidence mechanism, where anyone can submit a message containing the signature of a validator over a fake validator set. This is intended to produce the effect that if a cartel of validators is formed with the intention of submitting a fake validator set, one defector can cause them all to be slashed.
-
```go
// This call allows anyone to submit evidence that a
// validator has signed a valset, batch, or logic call that never
@@ -27,36 +27,35 @@ type MsgSubmitBadSignatureEvidence struct {
Sender string
}
```
-
**Implementation considerations:**
The trickiest part of this slashing condition is determining that a validator set has never existed on Injective. To save space, we will need to clean up old validator sets. We could keep a mapping of validator set hash to true in the KV store, and use that to check if a validator set has ever existed. This is more efficient than storing the whole validator set, but its growth is still unbounded. It might be possible to use other cryptographic methods to cut down on the size of this mapping. It might be OK to prune very old entries from this mapping, but any pruning reduces the deterrence of this slashing condition.
-The implemented version of this slashing condition stores a map of hashes for all past events, this is smaller than storing entire batches or validator sets and doesn't have to be accessed as frequently. A possible, but not currently implemented efficiency optimization, would be to remove hashes from this list after a given period. However, this would require storing more metadata about each hash.
+The implemented version of this slashing condition stores a map of hashes for all past events, this is smaller than storing entire batches or validator sets and doesn't have to be accessed as frequently. A possible but not currently implemented efficiency optimization would be to remove hashes from this list after a given period. But this would require storing more metadata about each hash.
-Currently, automatic evidence submission is not implemented in the relayer. By the time a signature is visible on Ethereum, it's already too late for slashing to prevent bridge highjacking or theft of funds. Furthermore, since 66% of the validator set is required to perform this action anyway, that same controlling majority could simply refuse the evidence. The most common case envisioned for this slashing condition is to break up a cabal of validators trying to take over the bridge by making it more difficult for them to trust one another and actually coordinate such a theft.
+Currently automatic evidence submission is not implemented in the relayer. By the time a signature is visible on Ethereum it's already too late for slashing to prevent bridge highjacking or theft of funds. Furthermore since 66% of the validator set is required to perform this action anyways that same controlling majority could simply refuse the evidence. The most common case envisioned for this slashing condition is to break up a cabal of validators trying to take over the bridge by making it more difficult for them to trust one another and actually coordinate such a theft.
The theft would involve exchanging of slashable Ethereum signatures and open up the possibility of a manual submission of this message by any defector in the group.
-Currently, this is implemented as an ever growing array of hashes in state.
+Currently this is implemented as an ever growing array of hashes in state.
## PEGGYSLASH-02: Failure to sign tx batch
-This slashing condition is triggered when a validator does not sign a transaction batch within `SignedBatchesWindow` upon it's creation by the Peggy module. This prevents two bad scenarios:
+This slashing condition is triggered when a validator does not sign a transaction batch within `SignedBatchesWindow` upon it's creation by the Peggy module. This prevents two bad scenarios-
1. A validator simply does not bother to keep the correct binaries running on their system,
2. A cartel of >1/3 validators unbond and then refuse to sign updates, preventing any batches from getting enough signatures to be submitted to the Peggy Ethereum contract.
## PEGGYSLASH-03: Failure to sign validator set update
-This slashing condition is triggered when a validator does not sign a validator set update which is produced by the Peggy module. This prevents two bad scenarios:
+This slashing condition is triggered when a validator does not sign a validator set update which is produced by the Peggy module. This prevents two bad scenarios-
1. A validator simply does not bother to keep the correct binaries running on their system,
2. A cartel of >1/3 validators unbond and then refuse to sign updates, preventing any validator set updates from getting enough signatures to be submitted to the Peggy Ethereum contract. If they prevent validator set updates for longer than the Injective Chain unbonding period, they can no longer be punished for submitting fake validator set updates and tx batches (PEGGYSLASH-01 and PEGGYSLASH-03).
To deal with scenario 2, PEGGYSLASH-03 will also need to slash validators who are no longer validating, but are still in the unbonding period for up to `UnbondSlashingValsetsWindow` blocks. This means that when a validator leaves the validator set, they will need to keep running their equipment for at least `UnbondSlashingValsetsWindow` blocks. This is unusual for the Injective Chain, and may not be accepted by the validators.
-The current value of `UnbondSlashingValsetsWindow` is 25,000 blocks, or about 12-14 hours. We have determined this to be a safe value based on the following logic. So long as every validator leaving the validator set signs at least one validator set update that they are not contained in, then it is guaranteed to be possible for a relayer to produce a chain of validator set updates to transform the current state on the chain into the present state.
+The current value of `UnbondSlashingValsetsWindow` is 25,000 blocks, or about 12-14 hours. We have determined this to be a safe value based on the following logic. So long as every validator leaving the validator set signs at least one validator set update that they are not contained in then it is guaranteed to be possible for a relayer to produce a chain of validator set updates to transform the current state on the chain into the present state.
It should be noted that both PEGGYSLASH-02 and PEGGYSLASH-03 could be eliminated with no loss of security if it where possible to perform the Ethereum signatures inside the consensus code. This is a pretty limited feature addition to Tendermint that would make Peggy far less prone to slashing.
@@ -84,8 +83,9 @@ This is similar to PEGGYSLASH-04, but it is triggered against validators who do
**Implementation considerations**
-Unfortunately, PEGGYSLASH-05 has the same downsides as PEGGYSLASH-04 in that it ties the correct operation of the Injective Chain to the Ethereum chain. Also, it likely does not incentivize much in the way of correct behavior. To avoid triggering PEGGYSLASH-05, a validator simply needs to copy claims which are close to becoming observed. This copying of claims could be prevented by a commit-reveal scheme, but it would still be easy for a "lazy validator" to simply use a public Ethereum full node or block explorer, with similar effects on security. Therefore, the real usefulness of PEGGYSLASH-05 is likely minimal.
+Unfortunately, PEGGYSLASH-05 has the same downsides as PEGGYSLASH-04 in that it ties the correct operation of the Injective Chain to the Ethereum chain. Also, it likely does not incentivize much in the way of correct behavior. To avoid triggering PEGGYSLASH-05, a validator simply needs to copy claims which are close to becoming observed. This copying of claims could be prevented by a commit-reveal scheme, but it would still be easy for a "lazy validator" to simply use a public Ethereum full node or block explorer, with similar effects on security. Therefore, the real usefulness of PEGGYSLASH-05 is likely minimal
+
+PEGGYSLASH-05 also introduces significant risks. Mostly around forks on the Ethereum chain. For example recently OpenEthereum failed to properly handle the Berlin hardfork, the resulting node 'failure' was totally undetectable to automated tools. It didn't crash so there was no restart to perform, blocks where still being produced although extremely slowly. If this had occurred while Peggy was running with PEGGYSLASH-05 active it would have caused those validators to be removed from the set. Possibly resulting in a very chaotic moment for the chain as dozens of validators where removed for little to no fault of their own.
-PEGGYSLASH-05 also introduces significant risks, mostly around forks on the Ethereum chain. For example, recently OpenEthereum failed to properly handle the Berlin hardfork; the resulting node 'failure' was totally undetectable to automated tools. It didn't crash, so there was no restart to perform. Blocks were still being produced, although extremely slowly. If this had occurred while Peggy was running with PEGGYSLASH-05 active, it would have caused those validators to be removed from the set, possibly resulting in a very chaotic moment for the chain as dozens of validators where removed for little to no fault of their own.
+Without PEGGYSLASH-04 and PEGGYSLASH-05, the Ethereum event oracle only continues to function if >2/3 of the validators voluntarily submit correct claims. Although the arguments against PEGGYSLASH-04 and PEGGYSLASH-05 are convincing, we must decide whether we are comfortable with this fact. Alternatively we must be comfortable with the Injective Chain potentially halting entirely due to Ethereum generated factors.
-Without PEGGYSLASH-04 and PEGGYSLASH-05, the Ethereum event oracle only continues to function if >2/3 of the validators voluntarily submit correct claims. Although the arguments against PEGGYSLASH-04 and PEGGYSLASH-05 are convincing, we must decide whether we are comfortable with this fact. Alternatively, we must be comfortable with the Injective Chain potentially halting entirely due to Ethereum generated factors.
diff --git a/.gitbook/developers/modules/injective/peggy/06_end_block.md b/.gitbook/developers/modules/injective/peggy/06_end_block.md
index 87eb2390..40bcae02 100644
--- a/.gitbook/developers/modules/injective/peggy/06_end_block.md
+++ b/.gitbook/developers/modules/injective/peggy/06_end_block.md
@@ -3,28 +3,29 @@ sidebar_position: 5
title: End-Block
---
-# EndBlock
+# EndBlocker
-Upon the end of each block, the following operations are performed to the state of the module
+Upon the end of each block the following operations are performed to the state of the module
## 1. Slashing
### Validator slashing
-A validator is slashed for not signing over a valset update which passed the `SignedValsetsWindow`. In other words, if a validator fails to provide the confirmation for a valset update within a preconfigured amount of time, they will be slashed for `SlashFractionValset` portion of their stake and get jailed immediately.
+A validator is slashed for not signing over a valset update which passed the `SignedValsetsWindow`.
+In other words, if a validator fails to provide the confirmation for a valset update within a preconfigured amount of time, they will be slashed for `SlashFractionValset` portion of their stake and get jailed immediately.
### Batch Slashing
-A validator is slashed for not signing over a batch which passed the `SignedBatchesWindow`. In other words, if a validator fails to provide the confirmation for a batch within a preconfigured amount of time, they will be slashed for `SlashFractionBatch` portion of their stake and get jailed immediately.
+A validator is slashed for not signing over a batch which passed the `SignedBatchesWindow`.
+In other words, if a validator fails to provide the confirmation for a batch within a preconfigured amount of time, they will be slashed for `SlashFractionBatch` portion of their stake and get jailed immediately.
## 2. Cancelling timed out batches
-Any batch still present in the `Outgoing Batch pool` whose `BatchTimeout` (a designated Ethereum height by which the batch should have executed) is exceeded gets removed from the pool and the withdrawals are reinserted back into the `Outgoing Tx pool`.
+Any batch still present in the `Outgoing Batch pool` whose `BatchTimeout` (a designated Ethereum height by which the batch should have executed) is exceeded gets removed from the pool and the withdrawals are reinserted back into the `Outgoing Tx pool`.
## 3. Creating new Valset updates
A new `Validator Set` update will be created automatically when:
-
* there is a power diff greater than 5% between the latest and current validator set
* a validator begins unbonding
@@ -36,10 +37,10 @@ Previously observed valsets that passed the `SignedValsetsWindow` are removed fr
## 5. Attestation processing
-Processes all attestations (an aggregate of claims for a particular event) currently being voted on. Each attestation is processed one by one to ensure each `Peggy contract` event is processed. After each processed attestation, the module's `lastObservedEventNonce` and `lastObservedEthereumBlockHeight` are updated.
+Processes all attestations (an aggregate of claims for a particular event) currently being voted on. Each attestation is processed one by one to ensure each `Peggy contract` event is processed.
+After each processed attestation the module's `lastObservedEventNonce` and `lastObservedEthereumBlockHeight` are updated.
Depending on the type of claim in the attestation, the following is executed:
-
* `MsgDepositClaim`: deposited tokens are minted/unlocked for the receiver address
* `MsgWithdrawClaim`: corresponding batch is removed from the outgoing pool and any previous batch is cancelled
* `MsgValsetUpdatedClaim`: the module's `LastObservedValset` is updated
diff --git a/.gitbook/developers/modules/injective/peggy/08_params.md b/.gitbook/developers/modules/injective/peggy/08_params.md
index 55226067..d76128cc 100644
--- a/.gitbook/developers/modules/injective/peggy/08_params.md
+++ b/.gitbook/developers/modules/injective/peggy/08_params.md
@@ -35,21 +35,33 @@ type Params struct {
## `peggy_id`
-A random 32 byte value to prevent signature reuse, for example if the Injective Chain validators decided to use the same Ethereum keys for another chain also running Peggy we would not want it to be possible to play a deposit from chain A back on chain B's Peggy. This value IS USED ON ETHEREUM so it must be set in your genesis.json before launch and not changed after deploying Peggy. Changing this value after deploying Peggy will result in the bridge being non-functional. To recover just set it back to the original value the contract was deployed with.
+A random 32 byte value to prevent signature reuse, for example if the
+Injective Chain validators decided to use the same Ethereum keys for another chain
+also running Peggy we would not want it to be possible to play a deposit
+from chain A back on chain B's Peggy. This value IS USED ON ETHEREUM so
+it must be set in your genesis.json before launch and not changed after
+deploying Peggy. Changing this value after deploying Peggy will result
+in the bridge being non-functional. To recover just set it back to the original
+value the contract was deployed with.
## `contract_source_hash`
-The code hash of a known good version of the Peggy contract solidity code. This can be used to verify the correct version of the contract has been deployed. This is a reference value for governance action only, it is never read by any Peggy code.
+The code hash of a known good version of the Peggy contract
+solidity code. This can be used to verify the correct version
+of the contract has been deployed. This is a reference value for
+governance action only it is never read by any Peggy code
## `bridge_ethereum_address`
-The address of the bridge contract on the Ethereum side, this is a reference value for governance only and is not actually used by any Peggy module code.
+is address of the bridge contract on the Ethereum side, this is a
+reference value for governance only and is not actually used by any
+Peggy module code.
The Ethereum bridge relayer use this value to interact with Peggy contract for querying events and submitting valset/batches to Peggy contract.
## `bridge_chain_id`
-The bridge chain ID is the unique identifier of the Ethereum chain. This is a reference value only and is not actually used by any Peggy code.
+The bridge chain ID is the unique identifier of the Ethereum chain. This is a reference value only and is not actually used by any Peggy code
These reference values may be used by future Peggy client implementations to allow for consistency checks.
@@ -59,20 +71,29 @@ These reference values may be used by future Peggy client implementations to all
* `signed_batches_window`
* `signed_claims_window`
-These values represent the time in blocks that a validator has to submit a signature for a batch or valset, or to submit a claim for a particular attestation nonce.
+These values represent the time in blocks that a validator has to submit
+a signature for a batch or valset, or to submit a claim for a particular
+attestation nonce.
-In the case of attestations, this clock starts when the attestation is created, but only allows for slashing once the event has passed. Note that that claims slashing is not currently enabled, see [slashing spec](05_slashing.md).
+In the case of attestations this clock starts when the
+attestation is created, but only allows for slashing once the event has passed.
+Note that that claims slashing is not currently enabled see [slashing spec](./05_slashing.md)
## `target_batch_timeout`
-This is the 'target' value for when batches time out, this is a target because Ethereum is a probabilistic chain, and you can't say for sure what the block frequency is ahead of time.
+This is the 'target' value for when batches time out, this is a target because
+Ethereum is a probabilistic chain and you can't say for sure what the block
+frequency is ahead of time.
## Ethereum timing
* `average_block_time`
* `average_ethereum_block_time`
-These values are the average Injective Chain block time and Ethereum block time, respectively, and are used to compute what the target batch timeout is. It is important that governance updates these in case of any major, prolonged change in the time it takes to produce a block.
+These values are the average Injective Chain block time and Ethereum block time respectively
+and they are used to compute what the target batch timeout is. It is important that
+governance updates these in case of any major, prolonged change in the time it takes
+to produce a block
## Slash fractions
@@ -81,10 +102,11 @@ These values are the average Injective Chain block time and Ethereum block time,
* `slash_fraction_claim`
* `slash_fraction_conflicting_claim`
-The slashing fractions for the various peggy-related slashing conditions. The first three refer to not submitting a particular message, the third for failing to submit a claim, and the last for submitting a different claim than other validators.
+The slashing fractions for the various peggy related slashing conditions. The first three
+refer to not submitting a particular message, the third for failing to submit a claim and the last for submitting a different claim than other validators.
-Note that claim slashing is currently disabled as outlined in the [slashing spec](05_slashing.md)
+Note that claim slashing is currently disabled as outlined in the [slashing spec](./05_slashing.md)
## `valset_reward`
-Valset reward is the reward amount paid to a relayer when they relay a valset to the Peggy contract on Ethereum.
+Valset reward is the reward amount paid to a relayer when they relay a valset to the Peggy contract on Ethereum.
\ No newline at end of file
diff --git a/.gitbook/developers/modules/injective/peggy/09_relay_semantics.md b/.gitbook/developers/modules/injective/peggy/09_relay_semantics.md
index 84762b6d..8dbcad36 100644
--- a/.gitbook/developers/modules/injective/peggy/09_relay_semantics.md
+++ b/.gitbook/developers/modules/injective/peggy/09_relay_semantics.md
@@ -5,7 +5,7 @@ title: Relay Semantics
# Relay Semantics
-This document is designed to assist developers in implementing alternate Peggy relayers. The two major components of the Orchestrator, which interact with Ethereum. The Peggy bridge has been designed for increased efficiency, not for ease of use. This means there are many implicit requirements of these external binaries, which this document does its best to make explicit.
+This document is designed to assist developers in implementing alternate Peggy relayers. The two major components of the Orchestrator which interact with Ethereum. The Peggy bridge has been designed for increased efficiency, not for ease of use. This means there are many implicit requirements of these external binaries which this document does it's best to make explicit.
The Peggy `orchestrator` combines three distinct roles that need to be performed by external binaries in the Peggy bridge. This document highlights the requirements of the `relayer` which is one of those roles included in the `orchestrator`.
@@ -13,41 +13,41 @@ The Peggy `orchestrator` combines three distinct roles that need to be performed
### Sorting and Ordering of the Validator set and signatures
-When updating the validator set in the Peggy contract, you must provide a copy of the old validator set. This _MUST_ only be taken from the last ValsetUpdated event on the Ethereum chain.
+When updating the validator set in the Peggy contract you must provide a copy of the old validator set. This _MUST_ only be taken from the last ValsetUpdated event on the Ethereum chain.
Providing the old validator set is part of a storage optimization, instead of storing the entire validator set in Ethereum storage it is instead provided by each caller and stored in the much cheaper Ethereum event queue. No sorting of any kind is performed in the Peggy contract, meaning the list of validators and their new signatures must be submitted in exactly the same order as the last call.
-For the purpose of normal operation, this requirement can be shortened to 'sort the validators by descending power, and by Eth address bytes where power is equal'. Since the peggy module produces the validator sets, they should always come in order. It is not possible for the relayer to change this order, since it is part of the signature. But a change in this sorting method on the Peggy module side would halt valset updates and essentially decouple the bridge, unless your implementation is smart enough to take a look at the last submitted order rather than blindly following sorting.
+For the purpose of normal operation this requirement can be shortened to 'sort the validators by descending power, and by Eth address bytes where power is equal'. Since the peggy module produces the validator sets they should always come in order. It is not possible for the relayer to change this order since it is part of the signature. But a change in this sorting method on the Peggy module side would halt valset updates and essentially decouple the bridge unless your implementation is smart enough to take a look at the last submitted order rather than blindly following sorting.
### Deciding what Validator set to relay
The Injective Chain simply produces a stream of validator sets, it does not make any judgement on how they are relayed. It's up to the relayer implementation to determine how to optimize the gas costs of this relaying operation.
-For example, let's say we had validator sets `A, B, C, and D` each is created when there is a 5% power difference between the last Peggy validator set snapshot in the store and the currently active validator set.
+For example lets say we had validator sets `A, B, C, and D` each is created when there is a 5% power difference between the last Peggy validator set snapshot in the store and the currently active validator set.
-5% is an arbitrary constant. The specific value chosen here is a tradeoff made by the chain between how up to date the Ethereum validator set is and the cost to keep it updated. The higher this value is, the lower the portion of the voting validator set is needed to highjack the bridge in the worst case. If we made a new validator set update every block 66% would need to collude, the 5% change threshold means 61% of the total voting power colluding in a given validator set may be able to steal the funds in the bridge.
+5% is an arbitrary constant. The specific value chosen here is a tradeoff made by the chain between how up to date the Ethereum validator set is and the cost to keep it updated. The higher this value is the lower the portion of the voting validator set is needed to highjack the bridge in the worst case. If we made a new validator set update every block 66% would need to collude, the 5% change threshold means 61% of the total voting power colluding in a given validator set may be able to steal the funds in the bridge.
```
A -> B -> C -> D
5% 10% 15%
```
-The relayer should iterate over the event history for the Peggy Ethereum contract, it will determine that validator set A is currently in the Peggy bridge. It can choose to either relay validator sets B, C and then D or simply submit validator set D. Provided all validators have signed D it has more than 66% voting power and can pass on its own. Without paying potentially several hundred dollars more in Ethereum to relay the intermediate sets.
+The relayer should iterate over the event history for the Peggy Ethereum contract, it will determine that validator set A is currently in the Peggy bridge. It can choose to either relay validator sets B, C and then D or simply submit validator set D. Provided all validators have signed D it has more than 66% voting power and can pass on it's own. Without paying potentially several hundred dollars more in Ethereum to relay the intermediate sets.
-Performing this check locally somehow, before submitting transactions, is essential to a cost-effective relayer implementation. You can either use a local Ethereum signing implementation and sum the powers and signatures yourself, or you can simply use the `eth_call()` Ethereum RPC to simulate the call on your Ethereum node.
+Performing this check locally somehow, before submitting transactions, is essential to a cost effective relayer implementation. You can either use a local Ethereum signing implementation and sum the powers and signatures yourself, or you can simply use the `eth_call()` Ethereum RPC to simulate the call on your Ethereum node.
Note that `eth_call()` often has funny gotchas. All calls fail on Geth based implementations if you don't have any Ethereum to pay for gas, while on Parity based implementations your gas inputs are mostly ignored and an accurate gas usage is returned.
## Semantics for transaction batch relaying
-In order to submit a transaction batch, you also need to submit the last set of validators and their staking powers. This is to facilitate the same storage optimization mentioned there.
+In order to submit a transaction batch you also need to submit the last set of validators and their staking powers. This is to facilitate the same storage optimization mentioned there.
### Deciding what batch to relay
Making a decision about which batch to relay is very different from deciding which validator set to relay. Batch relaying is primarily motivated by fees, not by a desire to maintain the integrity of the bridge. So the decision mostly comes down to fee computation, this is further complicated by the concept of 'batch requests'. Which is an unpermissioned transaction that requests the Peggy module generate a new batch for a specific token type.
-Batch requests are designed to allow the user to withdraw their tokens from the send to Ethereum tx pool at any time, up until a relayer shows interest in actually relaying them. While transactions are in the pool, there's no risk of a double spend if the user is allowed to withdraw them by sending a MsgCancelSendToEth. Once the transaction enters a batch due to a 'request batch' that is no longer the case and the users funds must remain locked until the Oracle informs the Peggy module that the batch containing the users tokens has become somehow invalid to submit or has been executed on Ethereum.
+Batch requests are designed to allow the user to withdraw their tokens from the send to Ethereum tx pool at any time up until a relayer shows interest in actually relaying them. While transactions are in the pool there's no risk of a double spend if the user is allowed to withdraw them by sending a MsgCancelSendToEth. Once the transaction enters a batch due to a 'request batch' that is no longer the case and the users funds must remain locked until the Oracle informs the Peggy module that the batch containing the users tokens has become somehow invalid to submit or has been executed on Ethereum.
-A relayer uses the query endpoint `BatchFees` to iterate over the send to Eth tx pool for each token type, the relayer can then observe the price for the ERC-20 tokens being relayed on a dex and compute the gas cost of executing the batch (via `eth_call()`) as well as the gas cost of liquidating the earnings on a dex if desired. Once a relayer determines that a batch is good and profitable, it can send a `MsgRequestBatch` and the batch will be created for the relayer to relay.
+A relayer uses the query endpoint `BatchFees` to iterate over the send to Eth tx pool for each token type, the relayer can then observe the price for the ERC-20 tokens being relayed on a dex and compute the gas cost of executing the batch (via `eth_call()`) as well as the gas cost of liquidating the earnings on a dex if desired. Once a relayer determines that a batch is good and profitable it can send a `MsgRequestBatch` and the batch will be created for the relayer to relay.
There are also existing batches, which the relayer should also judge for profitability and make an attempt at relaying using much the same method.
diff --git a/.gitbook/developers/modules/injective/peggy/10_future_improvements.md b/.gitbook/developers/modules/injective/peggy/10_future_improvements.md
index 14e4d6ac..76771318 100644
--- a/.gitbook/developers/modules/injective/peggy/10_future_improvements.md
+++ b/.gitbook/developers/modules/injective/peggy/10_future_improvements.md
@@ -3,20 +3,20 @@ sidebar_position: 10
title: Future Improvements
---
-# Improvements
+# Future Improvements
### Native Ethereum Signing
Validators run a required `Eth Signer` in the peggo orchestrator because we can not yet insert this sort of simple signature logic into Cosmos SDK based chains without significant modification to Tendermint. This may be possible in the future with [modifications to Tendermint](https://github.com/tendermint/tendermint/issues/6066).
-It should be noted that both [PEGGYSLASH-02](05_slashing.md) and [PEGGYSLASH-03](05_slashing.md) could be eliminated with no loss of security if it were possible to perform the Ethereum signatures inside the consensus code. This is a pretty limited feature addition to Tendermint that would make Peggy far less prone to slashing.
+It should be noted that both [PEGGYSLASH-02](./05_slashing.md) and [PEGGYSLASH-03](./05_slashing.md) could be eliminated with no loss of security if it where possible to perform the Ethereum signatures inside the consensus code. This is a pretty limited feature addition to Tendermint that would make Peggy far less prone to slashing.
### Improved Validator Incentives
-Currently, validators in Peggy have only one carrot - the extra activity brought to the chain by a functioning bridge.
+Currently validators in Peggy have only one carrot - the extra activity brought to the chain by a functioning bridge.
-There are, on the other hand, a lot of negative incentives (sticks) that the validators must watch out for. These are outlined in the [slashing spec](05_slashing.md).
+There are on the other hand a lot of negative incentives (sticks) that the validators must watch out for. These are outlined in the [slashing spec](./05_slashing.md).
-One negative incentive that is not covered under slashing is the cost of submitting oracle submissions and signatures. Currently, these operations are not incentivized, but still cost the validators fees to submit. This isn't a severe issue considering the relatively cheap transaction fees on the Injective Chain currently, but of course is an important factor to consider as transaction fees rise.
+One negative incentive that is not covered under slashing is the cost of submitting oracle submissions and signatures. Currently these operations are not incentivized, but still cost the validators fees to submit. This isn't a severe issue considering the relatively cheap transaction fees on the Injective Chain currently, but of course is an important factor to consider as transaction fees rise.
-Some positive incentives for correctly participating in the operation of the bridge should be under consideration. In addition to eliminating the fees for mandatory submissions.
+Some positive incentives for correctly participating in the operation of the bridge should be under consideration. In addition to eliminating the fees for mandatory submissions.
\ No newline at end of file
diff --git a/.gitbook/developers/modules/injective/peggy/README.md b/.gitbook/developers/modules/injective/peggy/README.md
index 6596179e..87c78767 100644
--- a/.gitbook/developers/modules/injective/peggy/README.md
+++ b/.gitbook/developers/modules/injective/peggy/README.md
@@ -1,32 +1,34 @@
-# Peggy
+# `Peggy`
## Abstract
-The peggy module enables the Injective Chain to support a trustless, on-chain bidirectional ERC-20 token bridge to Ethereum. In this system, holders of ERC-20 tokens on Ethereum can convert their ERC-20 tokens to Cosmos-native coins on the Injective Chain and vice versa.
+The peggy module enables the Injective Chain to support a trustless, on-chain bidirectional ERC-20 token bridge to Ethereum. In this system,
+holders of ERC-20 tokens on Ethereum can convert their ERC-20 tokens to Cosmos-native coins on
+the Injective Chain and vice-versa.
This decentralized bridge is secured and operated by the validators of the Injective Chain.
## Contents
-1. [**Definitions**](01_definitions.md)
-2. [**Workflow**](02_workflow.md)
-3. [**State**](03_state.md)
-4. [**Messages**](04_messages.md)
-5. [**Slashing**](05_slashing.md)
-6. [**End-Block**](06_end_block.md)
-7. [**Events**](07_events.md)
-8. [**Parameters**](08_params.md)
+1. **[Definitions](./01_definitions.md)**
+2. **[Workflow](./02_workflow.md)**
+3. **[State](./03_state.md)**
+4. **[Messages](./04_messages.md)**
+5. **[Slashing](./05_slashing.md)**
+6. **[End-Block](./06_end_block.md)**
+7. **[Events](./07_events.md)**
+8. **[Parameters](./08_params.md)**
### Components
-1. [**Peggy**](https://etherscan.io/address/0xF955C57f9EA9Dc8781965FEaE0b6A2acE2BAD6f3) **smart contract on Ethereum**
+1. **[Peggy](https://etherscan.io/address/0xF955C57f9EA9Dc8781965FEaE0b6A2acE2BAD6f3) smart contract on Ethereum**
2. **Peggy module on the Injective Chain**
-3. [**Peggo**](https://github.com/InjectiveLabs/peggo) **(off-chain relayer aka orchestrator)**
- * **Oracle** (Observes events of Peggy contract and send claims to the Peggy module)
- * **EthSigner** (Signs Valset and Batch confirmations to the Peggy module)
- * **Batch Requester** (Sends batch token withdrawal requests to the Peggy module)
- * **Valset Relayer** (Submits Validator set updates to the Peggy contract)
- * **Batch Relayer** (Submits batches of token withdrawals to the Peggy contract)
+3. **[Peggo](https://github.com/InjectiveLabs/peggo) (off-chain relayer aka orchestrator)**
+ - **Oracle** (Observes events of Peggy contract and send claims to the Peggy module)
+ - **EthSigner** (Signs Valset and Batch confirmations to the Peggy module)
+ - **Batch Requester** (Sends batch token withdrawal requests to the Peggy module)
+ - **Valset Relayer** (Submits Validator set updates to the Peggy contract)
+ - **Batch Relayer** (Submits batches of token withdrawals to the Peggy contract)
In addition to running an `injectived` node to sign blocks, Injective Chain validators must also run the `peggo` orchestrator to relay data from the Peggy smart contract on Ethereum and the Peggy module on the Injective Chain.
diff --git a/scripts/setup.sh b/scripts/setup.sh
index a503bdca..4fff77f0 100755
--- a/scripts/setup.sh
+++ b/scripts/setup.sh
@@ -3,8 +3,8 @@ injective_core_branch=dev
cosmos_sdk_branch=v0.50.x-inj
BUILD_DIR=./temp
STUB_DIR=./scripts/stub
-CORE_DIR=./docs/develop/modules/core
-INJECTIVE_DIR=./docs/develop/modules/injective
+CORE_DIR=./.gitbook/developers/modules/core
+INJECTIVE_DIR=./.gitbook/developers/modules/injective
mkdir -p $BUILD_DIR
rm -rf $CORE_DIR
@@ -32,10 +32,8 @@ for D in ./$BUILD_DIR/injective-core/injective-chain/modules/*; do
fi
done
-cp $STUB_DIR/core_category.json.stub $CORE_DIR/_category_.json
-cp $STUB_DIR/core_index.mdx.stub $CORE_DIR/index.mdx
-cp $STUB_DIR/injective_category.json.stub $INJECTIVE_DIR/_category_.json
-cp $STUB_DIR/injective_index.mdx.stub $INJECTIVE_DIR/index.mdx
+cp $STUB_DIR/core.modules.md.stub $CORE_DIR/README.md
+cp $STUB_DIR/injective.modules.md.stub $INJECTIVE_DIR/README.md
## 1. Manually replace wrong import paths
## authz
diff --git a/scripts/stub/core.modules.md.stub b/scripts/stub/core.modules.md.stub
new file mode 100644
index 00000000..dc0a11b3
--- /dev/null
+++ b/scripts/stub/core.modules.md.stub
@@ -0,0 +1,3 @@
+# Core
+
+## Core Modules
diff --git a/.gitbook/developers/modules/injective/README.md b/scripts/stub/injective.modules.md.stub
similarity index 100%
rename from .gitbook/developers/modules/injective/README.md
rename to scripts/stub/injective.modules.md.stub