Skip to content

Conversation

@aarmoa
Copy link
Collaborator

@aarmoa aarmoa commented Oct 17, 2025

  • Updated proto definitions to injective-core v1.17.0-beta.3 and indexer v1.17.0-beta

Solves CP-651

Summary by CodeRabbit

Release Notes

  • New Features

    • Added position offsetting capability to manage perpetual and derivatives positions.
    • Added instant market launch for perpetual and expiry futures markets.
    • Introduced open notional cap feature to control maximum notional exposure per market.
    • Added open interest querying for derivative and binary options markets.
    • Enabled streaming of order failure events with conditional order trigger failures.
    • Introduced rate limiting for cross-chain token transfers.
  • Improvements

    • Renamed denom queries to clarify auction exchange transfer context.
    • Enhanced batch order updates with market order support.

@aarmoa aarmoa requested a review from Copilot October 17, 2025 02:58
@coderabbitai
Copy link

coderabbitai bot commented Oct 17, 2025

Walkthrough

Introduces market offset positions, open notional caps for derivative/binary options markets, Peggy rate limiting, instant perpetual/expiry futures market launches, OpenInterest queries, and Hyperlane integration. Renames denom decimals queries to auction exchange transfer variants. Updates proto definitions, Go implementations, client interfaces, and examples across exchange, peggy, permissions, and stream modules.

Changes

Cohort / File(s) Summary
Protocol Buffer Exchange v1beta1 & v2 Definitions
proto/injective/exchange/v1beta1/exchange.proto, proto/injective/exchange/v1beta1/tx.proto, proto/injective/exchange/v1beta1/query.proto, proto/injective/exchange/v2/exchange.proto, proto/injective/exchange/v2/market.proto, proto/injective/exchange/v2/proposal.proto, proto/injective/exchange/v2/query.proto, proto/injective/exchange/v2/tx.proto
Added OpenNotionalCap messages; introduced MsgInstantPerpetualMarketLaunch, MsgInstantExpiryFuturesMarketLaunch, MsgOffsetPosition; added OffsettingPosition execution type; extended Params with post_only_mode_blocks_amount_after_downtime and open_notional_cap fields; renamed DenomDecimals queries to AuctionExchangeTransferDenomDecimals; added OpenInterest RPC and seq fields to orderbook responses; replaced UpdateParams RPC.
Protocol Buffer Peggy v1 Definitions
proto/injective/peggy/v1/msgs.proto, proto/injective/peggy/v1/rate_limit.proto, proto/injective/peggy/v1/events.proto, proto/injective/peggy/v1/genesis.proto
Added rate limiting messages (MsgCreateRateLimit, MsgUpdateRateLimit, MsgRemoveRateLimit); introduced RateLimit and BridgeTransfer messages; added JailReason enum and EventValidatorJailed; extended genesis with rate_limits field.
Protocol Buffer Permissions & Stream
proto/injective/permissions/v1beta1/genesis.proto, proto/injective/permissions/v1beta1/params.proto, proto/injective/permissions/v1beta1/permissions.proto, proto/injective/permissions/v1beta1/query.proto, proto/injective/permissions/v1beta1/tx.proto, proto/injective/stream/v2/query.proto
Added documentation comments to permissions proto files; introduced OrderFailureUpdate, ConditionalOrderTriggerFailureUpdate, and corresponding filters to stream query.
Protocol Buffer Token Factory & Txfees
proto/injective/tokenfactory/v1beta1/genesis.proto, proto/injective/tokenfactory/v1beta1/params.proto, proto/injective/tokenfactory/v1beta1/query.proto, proto/injective/tokenfactory/v1beta1/tx.proto, proto/injective/txfees/v1beta1/query.proto, proto/osmosis/txfees/v1beta1/query.proto
Added documentation comments and new fields to tokenfactory (name, symbol in MsgCreateDenom; receiver in MsgMint; burnFromAddress in MsgBurn; denom, new_admin in MsgChangeAdmin); added sub_denom to QueryDenomAuthorityMetadataRequest; added denoms to QueryDenomsFromCreatorResponse; added base_fee to QueryEipBaseFeeResponse.
Exchange Types Core
chain/exchange/types/codec.go, chain/exchange/types/errors.go, chain/exchange/types/expected_keepers.go, chain/exchange/types/key.go, chain/exchange/types/market.go, chain/exchange/types/market_admin.go, chain/exchange/types/msgs.go, chain/exchange/types/params.go
Added codec registrations for new market launch messages; extended error definitions and added new errors (ErrPositionNotOffsettable, ErrOffsettingSubaccountIDsEmpty, ErrInvalidOpenNotionalCap); removed SetDelegationTransferReceiver from StakingKeeper; added DerivativeMarketOpenInterestPrefix; introduced market ID prefixes (SPOT, PERPETUAL, EXPIRY_FUTURES, BINARY_OPTIONS); added OpenNotionalCapPerm; implemented new instant market launch message validations; updated tick size validation logic; removed MinDerivativeOrderPrice.
Exchange Types V2 Core
chain/exchange/types/v2/codec.go, chain/exchange/types/v2/msgs.go, chain/exchange/types/v2/market.go, chain/exchange/types/v2/events.go, chain/exchange/types/v2/params.go, chain/exchange/types/v2/position.go, chain/exchange/types/v2/proposal.go
Registered MsgOffsetPosition and replaced UpdateDenomDecimalsProposal with UpdateAuctionExchangeTransferDenomDecimalsProposal; added GetMarkPrice() methods to conditional order failure events; added GetOpenNotionalCap() getters to market types; implemented MsgOffsetPosition with full validation; added post_only_mode_blocks_amount_after_downtime and open_notional_cap parameters; updated proposal types with OpenNotionalCap fields; changed GetLiquidationMarketOrderWorstPrice to return pointer; added GetOffsettingMarketOrderWorstPrice.
EVM Precompiles
chain/evm/precompiles/bank/fixed_supply_bank_erc20.abigen.go, chain/evm/precompiles/bank/i_bank_module.abigen.go, chain/evm/precompiles/bank/mint_burn_bank_erc20.abigen.go, chain/evm/precompiles/staking/i_staking_module.abigen.go
Restructured ABI JSON strings with updated field ordering, internalType fields, and bytecode alignment across FixedSupplyBankERC20, BankModule, MintBurnBankERC20, and StakingModule metadata.
EVM Types
chain/evm/types/errors.go
Added RevertSelector and RevertReasonBytes() for ABI-encoded revert reasons.
Chain Client Interface & Implementation
client/chain/chain_v2.go, client/chain/chain_test_support.go, client/chain/context.go
Renamed FetchDenomDecimal/FetchDenomDecimals to FetchAuctionExchangeTransferDenomDecimal/FetchAuctionExchangeTransferDenomDecimals; added FetchOpenInterest; added Hyperlane module imports.
Client Utilities
client/chain/markets_assistant.go, client/chain/markets_assistant_test.go, client/chain/markets_assistant_test_support.go
Removed exchange client dependency from NewMarketsAssistantWithAllTokens and NewHumanReadableMarketsAssistantWithAllTokens; updated market initializations with OpenNotionalCap Uncapped.
Exchange Client Tests
client/exchange/exchange_test_support.go
Removed entire MockExchangeClient implementation.
Examples - Market Operations
examples/chain/exchange/4_MsgInstantPerpetualMarketLaunch/example.go, examples/chain/exchange/5_MsgInstantExpiryFuturesMarketLaunch/example.go, examples/chain/exchange/9_MsgBatchUpdateOrders/example.go, examples/chain/exchange/13_MsgInstantBinaryOptionsMarketLaunch/example.go, examples/chain/exchange/25_MsgUpdateDerivativeMarket/example.go, examples/chain/exchange/30_MsgOffsetPosition/example.go
Updated market launch messages with OpenNotionalCap; added spot/derivative market order creation in batch updates; introduced MsgOffsetPosition example with gas price handling.
Examples - Query Operations
examples/chain/exchange/query/8_AuctionExchangeTransferDenomDecimal/example.go, examples/chain/exchange/query/9_AuctionExchangeTransferDenomDecimals/example.go, examples/chain/exchange/query/66_OpenInterest/example.go
Renamed denom decimal queries to auction exchange transfer variants; added OpenInterest query example.
Examples - Stream & Explorer
examples/chain/12_ChainStream/example.go, examples/explorer/1_GetTxByHash/example.go
Added OrderFailuresFilter and ConditionalOrderTriggerFailuresFilter to ChainStreamV2; changed network loader from "sentry" to "lb".
Build & Configuration
Makefile, go.mod, injective_data/chain_messages_list.json
Updated git clone tags for Injective indexer and core; enhanced message extraction for pb.go files; bumped dependencies (cosmos-sdk v0.50.12, cometbft v1.0.1-inj.4, go-ethereum v1.16.3-inj); added hyperlane-cosmos v1.0.1-inj; updated message list with new market launch and offset messages; removed MsgSetDelegationTransferReceivers; expanded Peggy messages.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Client as Chain Client V2
    participant Msg as MsgOffsetPosition
    participant Validator as Validator

    User->>Client: AsyncBroadcastMsg(MsgOffsetPosition)
    Client->>Msg: Route() / Type()
    Msg-->>Client: RouterKey / TypeMsgOffsetPosition
    Client->>Msg: ValidateBasic()
    Note over Msg: Validate sender, market ID,<br/>subaccount, nonces,<br/>offsetting subaccounts
    Msg-->>Client: Validation result
    Client->>Msg: GetSignBytes()
    Msg-->>Client: Canonical signing data
    Client->>Msg: GetSigners()
    Msg-->>Client: [sender address]
    Client->>Validator: Broadcast transaction
    Validator-->>Client: Tx response
    Client-->>User: Pretty JSON response
Loading
sequenceDiagram
    participant User
    participant Client as Chain Client V2
    participant Msg as MsgInstant*MarketLaunch
    participant Validator as Validator

    User->>Client: Create market launch message
    Client->>Msg: ValidateBasic()
    Note over Msg: Validate sender, ticker, denoms,<br/>oracle params, fees, margins
    alt Has OpenNotionalCap
        Msg->>Msg: ValidateOpenNotionalCap()
        Note over Msg: Check mutual exclusivity,<br/>non-nil cap, non-negative
        Msg-->>Msg: OpenNotionalCap valid
    end
    Note over Msg: Validate tick size, notional
    Msg-->>Client: Validation result
    Client->>Validator: Broadcast transaction
    Validator-->>Client: Market launched with cap
    Client-->>User: Success response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Rationale: This PR introduces multiple interdependent features across heterogeneous areas: (1) new MsgOffsetPosition with complex validation logic spanning multiple files; (2) OpenNotionalCap structure threaded through market launch messages, proposals, and query responses; (3) extensive proto schema changes affecting serialization and client interfaces; (4) exchange client removal impacting test infrastructure; (5) systematic renaming of denom decimal queries affecting client methods and examples. While individual changes are well-structured, the scope spans ~80+ files with logic-dense additions (market ID prefixes, open notional validation, duplicate order detection), requiring careful verification of interactions across types/v2, examples, and client layers.

Poem

🐰 Offsets dance with notional caps,
Peggy's rate limits close the gaps,
Markets launch with prefixed IDs,
Hyperlane carries what speed needs,
A hop toward commerce unbounded!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "CP-651 update protos for v1.17.0 upgrade" clearly and specifically communicates the primary purpose of the changeset: updating protocol buffer definitions for the v1.17.0 version upgrade. The title includes a ticket reference (CP-651), identifies the main artifact being updated (protos), and specifies the version target (v1.17.0). While the changeset encompasses substantial supporting changes such as generated Go code updates, codec registrations, examples, and client implementations, these are all direct artifacts of the proto definition changes, making the title's focus on proto updates the accurate summary of the main change. The title is concise, specific, and avoids vague language.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cp-651/update_protos_for_v1_17_0_upgrade

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR updates the Injective protocol buffer definitions to support version 1.17.0, transitioning from v1.17.0-beta.3 of injective-core and v1.17.0-beta of the indexer. The changes enhance documentation, add new features for rate limiting and position offsetting, and improve API naming consistency.

Key changes include:

  • Added comprehensive documentation comments throughout proto files
  • Introduced new peggy rate limiting functionality with price feeds integration
  • Added position offsetting capability for derivative markets
  • Enhanced chain streaming with order failure tracking
  • Improved API naming for auction/exchange transfer operations

Reviewed Changes

Copilot reviewed 93 out of 98 changed files in this pull request and generated no comments.

Show a summary per file
File Description
proto/osmosis/txfees/v1beta1/query.proto Added documentation comment for base fee field
proto/injective/txfees/v1beta1/query.proto Added documentation comment for gas price field
proto/injective/tokenfactory/v1beta1/*.proto Added comprehensive field documentation across tx, query, params, and genesis files
proto/injective/stream/v2/query.proto Enhanced streaming with order failure filters and conditional order trigger failures
proto/injective/permissions/v1beta1/*.proto Added detailed field documentation for permissions module
proto/injective/peggy/v1/rate_limit.proto New file defining rate limiting structures for peggy bridge
proto/injective/peggy/v1/msgs.proto Added rate limiting management messages and validator jailing events
proto/injective/exchange/v2/*.proto Added position offsetting, open notional caps, and updated API naming
injective_data/chain_messages_list.json Updated with new message types for peggy and exchange modules
client/chain/*.go Updated method names for auction exchange transfer operations
examples/ Updated examples to use new API methods and demonstrate new features

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
chain/exchange/types/params.go (1)

391-426: <!-- [scratchpad]
[task review_comment_validation/1 complete]

[observations]

  • MaxTickSizeDecimalPlaces = 15 (line 51)
  • Comment at line 49-51 states: "MaxTickSizeDecimalPlaces defines the maximum number of decimal places allowed for tick size"
  • Current code enforces power-of-10 via repeated division (lines 398-424)
  • "errors" import used only at lines 400, 416 (both in ValidateTickSize function)
  • MaxOrderPrice = 10^32 (line 59)
  • ValidateTickSize called for MinPriceTickSize and MinQuantityTickSize in msgs, proposals (many locations)
  • No tests found for ValidateTickSize
  • Comment at lines 391-393 claims intent is "enforce decimal places limit" but implementation enforces "power of 10"

[analysis]
DISCREPANCY FOUND:

  • Comment says: "Use 10^MaxTickSizeDecimalPlaces as scaleFactor to naturally enforce decimal places limit"
  • But code actually enforces: "power of 10 using repeated division"

These are fundamentally different requirements:

  • Decimal places limit: allows ANY positive value with ≤15 decimals (0.5, 0.25, 0.123, etc.)
  • Power of 10: allows ONLY 1, 10, 100, 0.1, 0.01, 0.001, etc.

The comment's stated intent matches the review comment's proposed fix, NOT the current implementation.

Current code accepts: 0.00001, 0.0001, 0.001, 0.01, 0.1, 1, 10, 100, etc.
Current code REJECTS: 0.5, 0.25, 2, 3, 4, 5, 0.15, 0.123, etc.

Review comment's claim is FACTUALLY CORRECT: implementation is overly restrictive.

[done]
Review comment accurately identifies:

  1. Power-of-10 check too restrictive (VERIFIED)
  2. Proposed fix correct (integer check after scaling)
  3. "errors" import becomes unused (VERIFIED)
  4. Intent appears to be decimal place limiting, not power-of-10 enforcement
    [/scratchpad]

Current ValidateTickSize implementation enforces power-of-10 constraint that contradicts documented intent.

The code comment (lines 391-393) states the goal is "naturally enforce decimal places limit," yet the implementation uses repeated division to verify the value is a power of 10. These are fundamentally different:

  • Stated intent (per comment): Allow any positive tick with ≤15 decimal places
  • Actual behavior: Allow only powers of 10 (e.g., 0.01, 0.1, 1, 10) while rejecting 0.5, 0.25, 2, etc.

MaxTickSizeDecimalPlaces documentation (line 49-51) confirms the intent is to limit decimal places, not enforce powers of 10.

The "errors" import (lines 400, 416) is used only in this function and becomes unused with the proposed fix.

The proposed fix correctly implements the stated intent: scaling by 10^15 and checking for integer result.

Without test coverage for ValidateTickSize behavior, ensure the proposed change aligns with market tick size requirements before deployment.

chain/exchange/types/v2/position.go (1)

6-8: Duplicate import of the same package; unify alias

The same path is imported twice as types and v1; this won’t compile. Keep one alias (types) and update references.

 import (
     "cosmossdk.io/math"
 
-    "github.com/InjectiveLabs/sdk-go/chain/exchange/types"
-    v1 "github.com/InjectiveLabs/sdk-go/chain/exchange/types"
+    "github.com/InjectiveLabs/sdk-go/chain/exchange/types"
 )
@@
-func (p *Position) CheckValidPositionToReduce(
-    marketType v1.MarketType,
+func (p *Position) CheckValidPositionToReduce(
+    marketType types.MarketType,
@@
-func (p *Position) GetPayoutIfFullyClosing(closingPrice, closingFeeRate math.LegacyDec) *v1.PositionPayout {
+func (p *Position) GetPayoutIfFullyClosing(closingPrice, closingFeeRate math.LegacyDec) *types.PositionPayout {
@@
-    return &v1.PositionPayout{
+    return &types.PositionPayout{

Also applies to: 149-150, 303-314

examples/chain/exchange/9_MsgBatchUpdateOrders/example.go (1)

27-35: Avoid committing private keys; use env/keyring.

Replace the literal PK with an environment variable or empty string to use keyring.

Apply:

-    "inj-user",
-    "12345678",
-    "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
+    "inj-user",
+    "12345678",
+    os.Getenv("INJ_PK"), // leave empty to use keyring
🧹 Nitpick comments (22)
proto/injective/tokenfactory/v1beta1/params.proto (1)

13-21: Consider documenting other fields for consistency.

The Params message now has a comment for denom_creation_fee. If this message grows or if other similar messages in the proto package document their fields, consider adding documentation comments for consistency across the codebase.

proto/injective/stream/v2/query.proto (2)

272-299: Consider error reporting consistency between the two failure types.

OrderFailureUpdate uses error_code (uint32) while ConditionalOrderTriggerFailureUpdate uses error_description (string). While both approaches work, this inconsistency makes the API less uniform. Consider standardizing on one approach—either numeric error codes with a separate error registry, or string descriptions throughout.


342-352: Consider expanding OrderFailuresFilter filtering options.

OrderFailuresFilter only supports filtering by accounts, whereas ConditionalOrderTriggerFailuresFilter supports both subaccount_ids and market_ids. Since OrderFailureUpdate includes context like order_hash and cid that could be associated with markets and subaccounts, consider whether OrderFailuresFilter would benefit from similar granular filtering options for consistency and flexibility.

chain/evm/types/errors.go (1)

115-118: Consider clarifying the comment.

The comment states "selector of ErrExecutionReverted", but RevertSelector is actually the ABI function selector for the standard Solidity Error(string) function (0x08c379a0). The implementation is correct—this selector is used to encode/decode revert reasons according to Ethereum ABI standards.

Consider updating the comment for precision:

 var (
-	// RevertSelector is selector of ErrExecutionReverted
+	// RevertSelector is the ABI function selector for Error(string), used to encode revert reasons
 	RevertSelector = crypto.Keccak256([]byte("Error(string)"))[:4]
 )
client/chain/context.go (1)

189-192: LGTM! Registration implementation is correct.

The hyperlane type registrations follow the established pattern and are correctly placed. The implementation properly wires the new types into the codec's interface registry.

For consistency, consider aligning the registration order with the import order (lines 11-14):

-hyperlanecoretypes.RegisterInterfaces(interfaceRegistry)
-hyperlanewarptypes.RegisterInterfaces(interfaceRegistry)
-hyperlanepostdispatchtypes.RegisterInterfaces(interfaceRegistry)
-hyperlaneinterchainsecuritytypes.RegisterInterfaces(interfaceRegistry)
+hyperlaneinterchainsecuritytypes.RegisterInterfaces(interfaceRegistry)
+hyperlanepostdispatchtypes.RegisterInterfaces(interfaceRegistry)
+hyperlanecoretypes.RegisterInterfaces(interfaceRegistry)
+hyperlanewarptypes.RegisterInterfaces(interfaceRegistry)
go.mod (1)

238-276: Consistent InjectiveLabs fork strategy across replace directives.

All replace directives uniformly redirect cosmossdk.io paths and upstream modules (cosmos-sdk, cometbft, ibc-go, ibc-apps, wasmd, ethereum, block-sdk, etc.) to InjectiveLabs forks with -inj or -inj.N suffixes. This is architecturally consistent. However, confirm that all InjectiveLabs fork versions are synchronized, tested together, and compatible with the proto updates for v1.17.0.

proto/injective/peggy/v1/msgs.proto (1)

7-13: Remove the unused rate_limit.proto import.

The import at line 13 (injective/peggy/v1/rate_limit.proto) is not used in msgs.proto. The three new messages (MsgCreateRateLimit, MsgUpdateRateLimit, MsgRemoveRateLimit) use only primitive types and gogoproto custom types, never referencing RateLimit or BridgeTransfer. Removing this import will keep the proto surface clean.

examples/chain/exchange/25_MsgUpdateDerivativeMarket/example.go (1)

81-87: OpenNotionalCap oneof usage looks correct.

Cap -> Capped -> OpenNotionalCapCapped nesting matches the generated oneof types. Optionally, consider a constructor helper (e.g., NewCappedOpenNotionalCap(value)) to reduce boilerplate across examples.

proto/injective/exchange/v2/exchange.proto (1)

207-210: Comment name mismatch with field

Comment refers to post_only_mode_blocks_amount, but the field is post_only_mode_blocks_amount_after_downtime. Align to avoid confusion.

-  // post_only_mode_blocks_amount defines the amount of blocks the post only
-  // mode will be enabled after the downtime-detector module detects a chain
-  // downtime
+  // post_only_mode_blocks_amount_after_downtime defines the amount of blocks
+  // the post only mode will be enabled after the downtime-detector module
+  // detects a chain downtime
examples/chain/exchange/30_MsgOffsetPosition/example.go (1)

24-32: Avoid hard-coding private keys in examples

Use an env var (or keep empty to use keyring). Prevent accidental secret leakage.

-    "inj-user",
-    "12345678",
-    "5d386fbdbf11f1141010f81a46b40f94887367562bd33b452bbaa6ce1cd1381e", // keyring will be used if pk not provided
+    "inj-user",
+    "12345678",
+    os.Getenv("INJ_PRIV_KEY"), // leave empty to use keyring; or provide via env
chain/exchange/types/v2/params.go (2)

132-136: DRY up duplicate validators for post-only blocks amount

Reuse ValidatePostOnlyModeBlocksAmount for the “after downtime” param to avoid duplication.

 func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
@@
-        paramtypes.NewParamSetPair(
-            KeyPostOnlyModeBlocksAmountAfterDowntime,
-            &p.PostOnlyModeBlocksAmountAfterDowntime,
-            ValidatePostOnlyModeBlocksAmountAfterDowntime,
-        ),
+        paramtypes.NewParamSetPair(
+            KeyPostOnlyModeBlocksAmountAfterDowntime,
+            &p.PostOnlyModeBlocksAmountAfterDowntime,
+            ValidatePostOnlyModeBlocksAmount,
+        ),
 }
@@
-func ValidatePostOnlyModeBlocksAmountAfterDowntime(blocksAmount any) error {
-    v, ok := blocksAmount.(uint64)
-    if !ok {
-        return fmt.Errorf("invalid parameter type: %T", blocksAmount)
-    }
-    if v == 0 {
-        return fmt.Errorf("PostOnlyModeBlocksAmountAfterDowntime must be greater than zero: %d", v)
-    }
-    return nil
-}
+func ValidatePostOnlyModeBlocksAmountAfterDowntime(blocksAmount any) error {
+    // Reuse the same validation rules
+    return ValidatePostOnlyModeBlocksAmount(blocksAmount)
+}

Also applies to: 315-326


344-350: Use %v instead of %s in error formatting

Avoid using %s for a struct; use %v.

-        if v.GetCapped().Value.IsNegative() {
-            return fmt.Errorf("cap value cannot be negative: %s", v)
-        }
+        if v.GetCapped().Value.IsNegative() {
+            return fmt.Errorf("cap value cannot be negative: %v", v)
+        }
chain/exchange/types/v2/position.go (1)

194-202: Pointer return is fine; consider documenting nil semantics

Returning pointers to locals is safe in Go (heap escape). If nil may ever be meaningful, document when nil can be returned; otherwise value return could suffice.

Also applies to: 204-207

chain/exchange/types/v2/market.go (1)

188-190: Getters look correct; align with proto non-nullable fields.

LGTM. Optional: add nil receiver guards if these might be invoked on nil instances (pattern used elsewhere).

Also applies to: 293-295

chain/peggy/types/key.go (2)

120-121: Document new store prefixes and confirm migration.

Add brief comments for RateLimitsKey and MintAmountsERC20Key, and ensure any state migration notes cover these new keyspaces.


306-312: Prefer typed address over raw bytes for key builder.

Accepting []byte risks misuse. Take common.Address to enforce 20-byte ERC‑20 address length, mirroring other helpers.

Apply:

-func GetMintAmountERC20Key(erc20 []byte) []byte {
-	k := make([]byte, 0, len(MintAmountsERC20Key)+len(erc20))
-	k = append(k, MintAmountsERC20Key...)
-	k = append(k, erc20...)
-	return k
-}
+func GetMintAmountERC20Key(erc20 common.Address) []byte {
+	k := make([]byte, 0, len(MintAmountsERC20Key)+common.AddressLength)
+	k = append(k, MintAmountsERC20Key...)
+	k = append(k, erc20.Bytes()...)
+	return k
+}
client/chain/markets_assistant.go (1)

58-64: Avoid panic on token initialization; propagate or recover errors in constructors

initializeTokensFromChainDenoms panics on failure. Since these constructors are public entry points, consider:

  • Refactor initializeTokensFromChainDenoms to return error and handle it here, or
  • Add a local recovery wrapper to convert panics into errors for resilience.

This prevents process-wide crashes originating from a metadata RPC failure.

Also applies to: 66-72

client/chain/markets_assistant_test.go (1)

193-194: Constructor updates in tests look good; optional cleanup

LGTM on the new signatures. In the “WithAllTokens” tests you set up httpServer/network but don’t assign mockChain.Network; since LoadTokens errors are ignored, this setup is unnecessary. Consider removing it to speed tests and reduce noise.

Also applies to: 377-378

proto/injective/exchange/v2/proposal.proto (1)

501-503: New UpdateAuctionExchangeTransferDenomDecimalsProposal message (amino name).

Looks correct. Ensure legacy clients have a clear deprecation path from UpdateDenomDecimalsProposal.

chain/exchange/types/v2/msgs.go (1)

2707-2725: ensureNoDuplicateMarketOrders — LGTM; consider minor generalization.

Optional: accept interface for both derivatives/binary (same struct) to avoid two calls; not urgent.

chain/exchange/types/v2/proposal.go (2)

20-37: New/updated proposal type strings — LGTM.

Note minor naming inconsistency: ProposalUpdateAuctionExchangeTransferDenomDecimals (no “Type” prefix) vs others. Cosmetic.


689-699: Constructor still named NewUpdateDenomDecimalsProposal but returns new type.

Consider adding a new alias constructor NewUpdateAuctionExchangeTransferDenomDecimalsProposal and deprecate the old name for clarity.

Example addition outside this hunk:

// NewUpdateAuctionExchangeTransferDenomDecimalsProposal is the preferred constructor.
// Deprecated: use NewUpdateAuctionExchangeTransferDenomDecimalsProposal.
func NewUpdateAuctionExchangeTransferDenomDecimalsProposal(title, description string, denomDecimals []*DenomDecimals) *UpdateAuctionExchangeTransferDenomDecimalsProposal {
    return NewUpdateDenomDecimalsProposal(title, description, denomDecimals)
}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 56d001c and d55c55a.

⛔ Files ignored due to path filters (28)
  • chain/exchange/types/exchange.pb.go is excluded by !**/*.pb.go
  • chain/exchange/types/query.pb.go is excluded by !**/*.pb.go
  • chain/exchange/types/tx.pb.go is excluded by !**/*.pb.go
  • chain/exchange/types/v2/events.pb.go is excluded by !**/*.pb.go
  • chain/exchange/types/v2/exchange.pb.go is excluded by !**/*.pb.go
  • chain/exchange/types/v2/genesis.pb.go is excluded by !**/*.pb.go
  • chain/exchange/types/v2/market.pb.go is excluded by !**/*.pb.go
  • chain/exchange/types/v2/proposal.pb.go is excluded by !**/*.pb.go
  • chain/exchange/types/v2/query.pb.go is excluded by !**/*.pb.go
  • chain/exchange/types/v2/tx.pb.go is excluded by !**/*.pb.go
  • chain/peggy/types/events.pb.go is excluded by !**/*.pb.go
  • chain/peggy/types/genesis.pb.go is excluded by !**/*.pb.go
  • chain/peggy/types/msgs.pb.go is excluded by !**/*.pb.go
  • chain/peggy/types/rate_limit.pb.go is excluded by !**/*.pb.go
  • chain/permissions/types/genesis.pb.go is excluded by !**/*.pb.go
  • chain/permissions/types/params.pb.go is excluded by !**/*.pb.go
  • chain/permissions/types/permissions.pb.go is excluded by !**/*.pb.go
  • chain/permissions/types/query.pb.go is excluded by !**/*.pb.go
  • chain/permissions/types/tx.pb.go is excluded by !**/*.pb.go
  • chain/stream/types/v2/query.pb.go is excluded by !**/*.pb.go
  • chain/tokenfactory/types/genesis.pb.go is excluded by !**/*.pb.go
  • chain/tokenfactory/types/params.pb.go is excluded by !**/*.pb.go
  • chain/tokenfactory/types/query.pb.go is excluded by !**/*.pb.go
  • chain/tokenfactory/types/tx.pb.go is excluded by !**/*.pb.go
  • chain/txfees/osmosis/types/query.pb.go is excluded by !**/*.pb.go
  • chain/txfees/types/query.pb.go is excluded by !**/*.pb.go
  • exchange/auction_rpc/pb/goadesign_goagen_injective_auction_rpc.pb.go is excluded by !**/*.pb.go
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (70)
  • Makefile (2 hunks)
  • chain/evm/precompiles/bank/fixed_supply_bank_erc20.abigen.go (1 hunks)
  • chain/evm/precompiles/bank/i_bank_module.abigen.go (1 hunks)
  • chain/evm/precompiles/bank/mint_burn_bank_erc20.abigen.go (1 hunks)
  • chain/evm/precompiles/staking/i_staking_module.abigen.go (1 hunks)
  • chain/evm/types/errors.go (3 hunks)
  • chain/exchange/types/codec.go (2 hunks)
  • chain/exchange/types/errors.go (3 hunks)
  • chain/exchange/types/expected_keepers.go (0 hunks)
  • chain/exchange/types/key.go (1 hunks)
  • chain/exchange/types/market.go (4 hunks)
  • chain/exchange/types/market_admin.go (1 hunks)
  • chain/exchange/types/msgs.go (4 hunks)
  • chain/exchange/types/params.go (3 hunks)
  • chain/exchange/types/v2/codec.go (4 hunks)
  • chain/exchange/types/v2/events.go (2 hunks)
  • chain/exchange/types/v2/market.go (2 hunks)
  • chain/exchange/types/v2/msgs.go (14 hunks)
  • chain/exchange/types/v2/params.go (5 hunks)
  • chain/exchange/types/v2/position.go (1 hunks)
  • chain/exchange/types/v2/proposal.go (19 hunks)
  • chain/peggy/types/codec.go (2 hunks)
  • chain/peggy/types/key.go (2 hunks)
  • client/chain/chain_test_support.go (2 hunks)
  • client/chain/chain_v2.go (4 hunks)
  • client/chain/context.go (2 hunks)
  • client/chain/markets_assistant.go (1 hunks)
  • client/chain/markets_assistant_test.go (2 hunks)
  • client/chain/markets_assistant_test_support.go (2 hunks)
  • client/exchange/exchange_test_support.go (0 hunks)
  • examples/chain/12_ChainStream/example.go (1 hunks)
  • examples/chain/exchange/13_MsgInstantBinaryOptionsMarketLaunch/example.go (1 hunks)
  • examples/chain/exchange/25_MsgUpdateDerivativeMarket/example.go (1 hunks)
  • examples/chain/exchange/30_MsgOffsetPosition/example.go (1 hunks)
  • examples/chain/exchange/4_MsgInstantPerpetualMarketLaunch/example.go (1 hunks)
  • examples/chain/exchange/5_MsgInstantExpiryFuturesMarketLaunch/example.go (1 hunks)
  • examples/chain/exchange/9_MsgBatchUpdateOrders/example.go (2 hunks)
  • examples/chain/exchange/query/66_OpenInterest/example.go (1 hunks)
  • examples/chain/exchange/query/8_AuctionExchangeTransferDenomDecimal/example.go (1 hunks)
  • examples/chain/exchange/query/9_AuctionExchangeTransferDenomDecimals/example.go (1 hunks)
  • examples/explorer/1_GetTxByHash/example.go (1 hunks)
  • examples/explorer/2_AccountTxs/example.go (1 hunks)
  • go.mod (6 hunks)
  • injective_data/chain_messages_list.json (3 hunks)
  • proto/injective/exchange/v1beta1/exchange.proto (2 hunks)
  • proto/injective/exchange/v1beta1/query.proto (1 hunks)
  • proto/injective/exchange/v1beta1/tx.proto (2 hunks)
  • proto/injective/exchange/v2/events.proto (2 hunks)
  • proto/injective/exchange/v2/exchange.proto (2 hunks)
  • proto/injective/exchange/v2/genesis.proto (1 hunks)
  • proto/injective/exchange/v2/market.proto (3 hunks)
  • proto/injective/exchange/v2/proposal.proto (7 hunks)
  • proto/injective/exchange/v2/query.proto (9 hunks)
  • proto/injective/exchange/v2/tx.proto (9 hunks)
  • proto/injective/peggy/v1/events.proto (1 hunks)
  • proto/injective/peggy/v1/genesis.proto (2 hunks)
  • proto/injective/peggy/v1/msgs.proto (5 hunks)
  • proto/injective/peggy/v1/rate_limit.proto (1 hunks)
  • proto/injective/permissions/v1beta1/genesis.proto (1 hunks)
  • proto/injective/permissions/v1beta1/params.proto (1 hunks)
  • proto/injective/permissions/v1beta1/permissions.proto (3 hunks)
  • proto/injective/permissions/v1beta1/query.proto (2 hunks)
  • proto/injective/permissions/v1beta1/tx.proto (2 hunks)
  • proto/injective/stream/v2/query.proto (4 hunks)
  • proto/injective/tokenfactory/v1beta1/genesis.proto (1 hunks)
  • proto/injective/tokenfactory/v1beta1/params.proto (1 hunks)
  • proto/injective/tokenfactory/v1beta1/query.proto (3 hunks)
  • proto/injective/tokenfactory/v1beta1/tx.proto (5 hunks)
  • proto/injective/txfees/v1beta1/query.proto (1 hunks)
  • proto/osmosis/txfees/v1beta1/query.proto (1 hunks)
💤 Files with no reviewable changes (2)
  • chain/exchange/types/expected_keepers.go
  • client/exchange/exchange_test_support.go
🧰 Additional context used
🧬 Code graph analysis (27)
chain/exchange/types/v2/market.go (1)
chain/exchange/types/v2/market.pb.go (10)
  • DerivativeMarket (478-530)
  • DerivativeMarket (534-534)
  • DerivativeMarket (535-537)
  • OpenNotionalCap (62-67)
  • OpenNotionalCap (71-71)
  • OpenNotionalCap (72-74)
  • OpenNotionalCap (140-145)
  • BinaryOptionsMarket (394-442)
  • BinaryOptionsMarket (446-446)
  • BinaryOptionsMarket (447-449)
examples/chain/12_ChainStream/example.go (1)
chain/stream/types/v2/query.pb.go (6)
  • OrderFailuresFilter (1778-1781)
  • OrderFailuresFilter (1785-1785)
  • OrderFailuresFilter (1786-1788)
  • ConditionalOrderTriggerFailuresFilter (1823-1828)
  • ConditionalOrderTriggerFailuresFilter (1832-1832)
  • ConditionalOrderTriggerFailuresFilter (1833-1835)
examples/chain/exchange/25_MsgUpdateDerivativeMarket/example.go (1)
chain/exchange/types/v2/market.pb.go (9)
  • OpenNotionalCap (62-67)
  • OpenNotionalCap (71-71)
  • OpenNotionalCap (72-74)
  • OpenNotionalCap (140-145)
  • OpenNotionalCap_Capped (111-113)
  • OpenNotionalCap_Capped (116-116)
  • OpenNotionalCapCapped (183-185)
  • OpenNotionalCapCapped (189-189)
  • OpenNotionalCapCapped (190-192)
examples/chain/exchange/9_MsgBatchUpdateOrders/example.go (3)
client/chain/chain.go (2)
  • SpotOrderData (1637-1645)
  • DerivativeOrderData (1625-1635)
chain/exchange/types/exchange.pb.go (9)
  • OrderType (97-97)
  • OrderType (145-147)
  • OrderType_BUY (101-101)
  • SpotOrder (1413-1422)
  • SpotOrder (1426-1426)
  • SpotOrder (1427-1429)
  • DerivativeOrder (1611-1622)
  • DerivativeOrder (1626-1626)
  • DerivativeOrder (1627-1629)
chain/exchange/types/v2/tx.pb.go (3)
  • MsgBatchUpdateOrders (1722-1752)
  • MsgBatchUpdateOrders (1756-1756)
  • MsgBatchUpdateOrders (1757-1759)
examples/explorer/1_GetTxByHash/example.go (2)
client/common/network.go (1)
  • LoadNetwork (53-202)
client/explorer/explorer.go (1)
  • NewExplorerClient (48-96)
client/chain/markets_assistant.go (2)
client/chain/chain.go (1)
  • ChainClient (74-332)
client/chain/chain_v2.go (1)
  • ChainClientV2 (54-311)
chain/exchange/types/codec.go (3)
chain/exchange/types/msgs.go (4)
  • MsgInstantPerpetualMarketLaunch (593-593)
  • MsgInstantPerpetualMarketLaunch (596-596)
  • MsgInstantExpiryFuturesMarketLaunch (739-739)
  • MsgInstantExpiryFuturesMarketLaunch (742-744)
chain/exchange/types/tx.pb.go (6)
  • MsgInstantPerpetualMarketLaunch (755-790)
  • MsgInstantPerpetualMarketLaunch (794-794)
  • MsgInstantPerpetualMarketLaunch (795-797)
  • MsgInstantExpiryFuturesMarketLaunch (982-1019)
  • MsgInstantExpiryFuturesMarketLaunch (1023-1023)
  • MsgInstantExpiryFuturesMarketLaunch (1024-1026)
chain/exchange/types/v2/tx.pb.go (6)
  • MsgInstantPerpetualMarketLaunch (753-793)
  • MsgInstantPerpetualMarketLaunch (797-797)
  • MsgInstantPerpetualMarketLaunch (798-800)
  • MsgInstantExpiryFuturesMarketLaunch (986-1027)
  • MsgInstantExpiryFuturesMarketLaunch (1031-1031)
  • MsgInstantExpiryFuturesMarketLaunch (1032-1034)
chain/peggy/types/codec.go (2)
chain/peggy/types/msgs.pb.go (9)
  • MsgCreateRateLimit (1587-1603)
  • MsgCreateRateLimit (1607-1607)
  • MsgCreateRateLimit (1608-1610)
  • MsgUpdateRateLimit (1709-1720)
  • MsgUpdateRateLimit (1724-1724)
  • MsgUpdateRateLimit (1725-1727)
  • MsgRemoveRateLimit (1819-1824)
  • MsgRemoveRateLimit (1828-1828)
  • MsgRemoveRateLimit (1829-1831)
chain/peggy/types/rate_limit.pb.go (3)
  • RateLimit (27-43)
  • RateLimit (47-47)
  • RateLimit (48-50)
chain/exchange/types/errors.go (1)
chain/exchange/types/key.go (1)
  • ModuleName (17-17)
examples/chain/exchange/4_MsgInstantPerpetualMarketLaunch/example.go (2)
chain/exchange/types/exchange.pb.go (6)
  • OpenNotionalCap (232-237)
  • OpenNotionalCap (241-241)
  • OpenNotionalCap (242-244)
  • OpenNotionalCap (310-315)
  • OpenNotionalCap_Uncapped (278-280)
  • OpenNotionalCap_Uncapped (285-285)
chain/exchange/types/v2/market.pb.go (6)
  • OpenNotionalCap (62-67)
  • OpenNotionalCap (71-71)
  • OpenNotionalCap (72-74)
  • OpenNotionalCap (140-145)
  • OpenNotionalCap_Uncapped (108-110)
  • OpenNotionalCap_Uncapped (115-115)
client/chain/markets_assistant_test_support.go (2)
chain/exchange/types/exchange.pb.go (6)
  • OpenNotionalCap (232-237)
  • OpenNotionalCap (241-241)
  • OpenNotionalCap (242-244)
  • OpenNotionalCap (310-315)
  • OpenNotionalCap_Uncapped (278-280)
  • OpenNotionalCap_Uncapped (285-285)
chain/exchange/types/v2/market.pb.go (6)
  • OpenNotionalCap (62-67)
  • OpenNotionalCap (71-71)
  • OpenNotionalCap (72-74)
  • OpenNotionalCap (140-145)
  • OpenNotionalCap_Uncapped (108-110)
  • OpenNotionalCap_Uncapped (115-115)
examples/chain/exchange/5_MsgInstantExpiryFuturesMarketLaunch/example.go (2)
chain/exchange/types/exchange.pb.go (6)
  • OpenNotionalCap (232-237)
  • OpenNotionalCap (241-241)
  • OpenNotionalCap (242-244)
  • OpenNotionalCap (310-315)
  • OpenNotionalCap_Uncapped (278-280)
  • OpenNotionalCap_Uncapped (285-285)
chain/exchange/types/v2/market.pb.go (6)
  • OpenNotionalCap (62-67)
  • OpenNotionalCap (71-71)
  • OpenNotionalCap (72-74)
  • OpenNotionalCap (140-145)
  • OpenNotionalCap_Uncapped (108-110)
  • OpenNotionalCap_Uncapped (115-115)
chain/exchange/types/v2/events.go (1)
chain/exchange/types/v2/events.pb.go (6)
  • EventTriggerConditionalMarketOrderFailed (2393-2400)
  • EventTriggerConditionalMarketOrderFailed (2406-2406)
  • EventTriggerConditionalMarketOrderFailed (2407-2409)
  • EventTriggerConditionalLimitOrderFailed (2472-2479)
  • EventTriggerConditionalLimitOrderFailed (2485-2485)
  • EventTriggerConditionalLimitOrderFailed (2486-2488)
client/chain/markets_assistant_test.go (1)
client/chain/markets_assistant.go (2)
  • NewMarketsAssistantWithAllTokens (58-64)
  • NewHumanReadableMarketsAssistantWithAllTokens (66-72)
client/chain/chain_test_support.go (1)
chain/exchange/types/v2/query.pb.go (9)
  • QueryAuctionExchangeTransferDenomDecimalResponse (937-939)
  • QueryAuctionExchangeTransferDenomDecimalResponse (947-947)
  • QueryAuctionExchangeTransferDenomDecimalResponse (948-950)
  • QueryAuctionExchangeTransferDenomDecimalsResponse (1038-1040)
  • QueryAuctionExchangeTransferDenomDecimalsResponse (1048-1048)
  • QueryAuctionExchangeTransferDenomDecimalsResponse (1049-1051)
  • QueryOpenInterestResponse (7567-7569)
  • QueryOpenInterestResponse (7573-7573)
  • QueryOpenInterestResponse (7574-7576)
examples/explorer/2_AccountTxs/example.go (2)
client/common/network.go (1)
  • LoadNetwork (53-202)
client/explorer/explorer.go (1)
  • NewExplorerClient (48-96)
chain/exchange/types/v2/position.go (2)
chain/exchange/types/v2/exchange.pb.go (3)
  • Position (607-618)
  • Position (622-622)
  • Position (623-625)
chain/exchange/types/v2/market.pb.go (3)
  • PerpetualMarketFunding (951-960)
  • PerpetualMarketFunding (964-964)
  • PerpetualMarketFunding (965-967)
examples/chain/exchange/13_MsgInstantBinaryOptionsMarketLaunch/example.go (2)
chain/exchange/types/exchange.pb.go (6)
  • OpenNotionalCap (232-237)
  • OpenNotionalCap (241-241)
  • OpenNotionalCap (242-244)
  • OpenNotionalCap (310-315)
  • OpenNotionalCap_Uncapped (278-280)
  • OpenNotionalCap_Uncapped (285-285)
chain/exchange/types/v2/market.pb.go (6)
  • OpenNotionalCap (62-67)
  • OpenNotionalCap (71-71)
  • OpenNotionalCap (72-74)
  • OpenNotionalCap (140-145)
  • OpenNotionalCap_Uncapped (108-110)
  • OpenNotionalCap_Uncapped (115-115)
chain/exchange/types/v2/params.go (2)
chain/exchange/types/exchange.pb.go (4)
  • OpenNotionalCap (232-237)
  • OpenNotionalCap (241-241)
  • OpenNotionalCap (242-244)
  • OpenNotionalCap (310-315)
chain/exchange/types/v2/market.pb.go (4)
  • OpenNotionalCap (62-67)
  • OpenNotionalCap (71-71)
  • OpenNotionalCap (72-74)
  • OpenNotionalCap (140-145)
examples/chain/exchange/30_MsgOffsetPosition/example.go (6)
client/common/network.go (1)
  • LoadNetwork (53-202)
client/chain/keys.go (1)
  • InitCosmosKeyring (28-164)
client/chain/context.go (1)
  • NewClientContext (95-140)
client/chain/chain_v2.go (1)
  • NewChainClientV2 (362-506)
chain/exchange/types/v2/msgs.go (2)
  • MsgOffsetPosition (1861-1863)
  • MsgOffsetPosition (1865-1867)
chain/exchange/types/v2/tx.pb.go (3)
  • MsgOffsetPosition (2727-2732)
  • MsgOffsetPosition (2736-2736)
  • MsgOffsetPosition (2737-2739)
chain/exchange/types/msgs.go (8)
chain/exchange/types/tx.pb.go (6)
  • MsgInstantPerpetualMarketLaunch (755-790)
  • MsgInstantPerpetualMarketLaunch (794-794)
  • MsgInstantPerpetualMarketLaunch (795-797)
  • MsgInstantExpiryFuturesMarketLaunch (982-1019)
  • MsgInstantExpiryFuturesMarketLaunch (1023-1023)
  • MsgInstantExpiryFuturesMarketLaunch (1024-1026)
chain/exchange/types/v2/tx.pb.go (6)
  • MsgInstantPerpetualMarketLaunch (753-793)
  • MsgInstantPerpetualMarketLaunch (797-797)
  • MsgInstantPerpetualMarketLaunch (798-800)
  • MsgInstantExpiryFuturesMarketLaunch (986-1027)
  • MsgInstantExpiryFuturesMarketLaunch (1031-1031)
  • MsgInstantExpiryFuturesMarketLaunch (1032-1034)
chain/exchange/types/v2/msgs.go (3)
  • RouterKey (18-18)
  • TypeMsgInstantPerpetualMarketLaunch (95-95)
  • TypeMsgInstantExpiryFuturesMarketLaunch (96-96)
chain/exchange/types/errors.go (9)
  • ErrInvalidAddress (91-91)
  • ErrInvalidTicker (19-19)
  • ErrInvalidQuoteDenom (21-21)
  • ErrFeeRatesRelation (52-52)
  • ErrMarginsRelation (53-53)
  • ErrInvalidPriceTickSize (42-42)
  • ErrInvalidQuantityTickSize (43-43)
  • ErrInvalidNotional (108-108)
  • ErrInvalidExpiry (23-23)
chain/exchange/types/params.go (5)
  • MaxTickerLength (38-38)
  • ValidateMakerFee (300-319)
  • ValidateFee (280-298)
  • ValidateTickSize (369-427)
  • ValidateMinNotional (429-444)
chain/exchange/types/v2/proposal.go (1)
  • NewOracleParams (743-755)
chain/exchange/types/proposal.go (1)
  • NewOracleParams (659-671)
chain/exchange/types/codec.go (1)
  • ModuleCdc (187-187)
chain/exchange/types/v2/codec.go (4)
chain/exchange/types/v2/msgs.go (2)
  • MsgOffsetPosition (1861-1863)
  • MsgOffsetPosition (1865-1867)
chain/exchange/types/v2/tx.pb.go (3)
  • MsgOffsetPosition (2727-2732)
  • MsgOffsetPosition (2736-2736)
  • MsgOffsetPosition (2737-2739)
chain/exchange/types/v2/proposal.go (2)
  • UpdateAuctionExchangeTransferDenomDecimalsProposal (715-715)
  • UpdateAuctionExchangeTransferDenomDecimalsProposal (718-720)
chain/exchange/types/v2/proposal.pb.go (3)
  • UpdateAuctionExchangeTransferDenomDecimalsProposal (672-676)
  • UpdateAuctionExchangeTransferDenomDecimalsProposal (684-684)
  • UpdateAuctionExchangeTransferDenomDecimalsProposal (685-687)
examples/chain/exchange/query/66_OpenInterest/example.go (6)
client/common/network.go (1)
  • LoadNetwork (53-202)
client/chain/keys.go (1)
  • InitCosmosKeyring (28-164)
client/chain/context.go (1)
  • NewClientContext (95-140)
client/chain/chain_v2.go (1)
  • NewChainClientV2 (362-506)
client/common/options.go (1)
  • OptionGasPrices (36-47)
client/constants.go (1)
  • DefaultGasPriceWithDenom (6-6)
chain/exchange/types/market.go (2)
chain/oracle/types/oracle.pb.go (2)
  • OracleType (32-32)
  • OracleType (86-88)
chain/peggy/types/ethereum.go (1)
  • NewPeggyDenomFromString (113-127)
client/chain/chain_v2.go (2)
chain/exchange/types/v2/query.pb.go (21)
  • QueryAuctionExchangeTransferDenomDecimalResponse (937-939)
  • QueryAuctionExchangeTransferDenomDecimalResponse (947-947)
  • QueryAuctionExchangeTransferDenomDecimalResponse (948-950)
  • QueryAuctionExchangeTransferDenomDecimalsResponse (1038-1040)
  • QueryAuctionExchangeTransferDenomDecimalsResponse (1048-1048)
  • QueryAuctionExchangeTransferDenomDecimalsResponse (1049-1051)
  • QueryOpenInterestResponse (7567-7569)
  • QueryOpenInterestResponse (7573-7573)
  • QueryOpenInterestResponse (7574-7576)
  • QueryAuctionExchangeTransferDenomDecimalRequest (887-889)
  • QueryAuctionExchangeTransferDenomDecimalRequest (897-897)
  • QueryAuctionExchangeTransferDenomDecimalRequest (898-900)
  • QueryAuctionExchangeTransferDenomDecimalsRequest (987-990)
  • QueryAuctionExchangeTransferDenomDecimalsRequest (998-998)
  • QueryAuctionExchangeTransferDenomDecimalsRequest (999-1001)
  • QueryOpenInterestRequest (7522-7525)
  • QueryOpenInterestRequest (7529-7529)
  • QueryOpenInterestRequest (7530-7532)
  • OpenInterest (7475-7480)
  • OpenInterest (7484-7484)
  • OpenInterest (7485-7487)
client/common/api_request_assistant.go (1)
  • ExecuteCall (13-37)
chain/exchange/types/v2/msgs.go (4)
chain/exchange/types/v2/tx.pb.go (6)
  • MsgOffsetPosition (2727-2732)
  • MsgOffsetPosition (2736-2736)
  • MsgOffsetPosition (2737-2739)
  • MsgUpdateDerivativeMarket (144-165)
  • MsgUpdateDerivativeMarket (169-169)
  • MsgUpdateDerivativeMarket (170-172)
chain/exchange/types/errors.go (6)
  • ErrInvalidOpenNotionalCap (119-119)
  • ErrInvalidAddress (91-91)
  • ErrMarketInvalid (13-13)
  • ErrBadSubaccountID (18-18)
  • ErrOffsettingSubaccountIDsEmpty (118-118)
  • ErrInvalidBatchMsgUpdate (66-66)
chain/exchange/types/exchange.pb.go (10)
  • OpenNotionalCap (232-237)
  • OpenNotionalCap (241-241)
  • OpenNotionalCap (242-244)
  • OpenNotionalCap (310-315)
  • DerivativeOrder (1611-1622)
  • DerivativeOrder (1626-1626)
  • DerivativeOrder (1627-1629)
  • OrderInfo (1347-1357)
  • OrderInfo (1361-1361)
  • OrderInfo (1362-1364)
chain/exchange/types/common_utils.go (4)
  • IsHexHash (110-120)
  • IsValidSubaccountID (90-98)
  • HasDuplicates (311-320)
  • GetSubaccountIDOrDeriveFromNonce (203-213)
chain/exchange/types/v2/proposal.go (7)
chain/exchange/types/exchange.pb.go (7)
  • OpenNotionalCap (232-237)
  • OpenNotionalCap (241-241)
  • OpenNotionalCap (242-244)
  • OpenNotionalCap (310-315)
  • DenomDecimals (3302-3305)
  • DenomDecimals (3309-3309)
  • DenomDecimals (3310-3312)
chain/exchange/types/v2/market.pb.go (4)
  • OpenNotionalCap (62-67)
  • OpenNotionalCap (71-71)
  • OpenNotionalCap (72-74)
  • OpenNotionalCap (140-145)
chain/exchange/types/v2/params.go (1)
  • ValidateOpenNotionalCap (328-353)
chain/exchange/types/errors.go (1)
  • ErrInvalidOpenNotionalCap (119-119)
chain/exchange/types/v2/proposal.pb.go (3)
  • UpdateAuctionExchangeTransferDenomDecimalsProposal (672-676)
  • UpdateAuctionExchangeTransferDenomDecimalsProposal (684-684)
  • UpdateAuctionExchangeTransferDenomDecimalsProposal (685-687)
chain/exchange/types/v2/exchange.pb.go (3)
  • DenomDecimals (1910-1915)
  • DenomDecimals (1919-1919)
  • DenomDecimals (1920-1922)
chain/exchange/types/v2/msgs.go (1)
  • RouterKey (18-18)
🪛 Buf (1.58.0)
proto/injective/peggy/v1/rate_limit.proto

6-6: import "gogoproto/gogo.proto": file does not exist

(COMPILE)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Socket Security: Pull Request Alerts
  • GitHub Check: lint
  • GitHub Check: run-tests

ErrInsufficientMarketBalance = errors.Register(ModuleName, 106, "insufficient market balance")
ErrInvalidExpirationBlock = errors.Register(ModuleName, 107, "invalid expiration block")
ErrV1DerivativeMarketLaunch = errors.Register(ModuleName, 108, "v1 perpetual and expiry market launch proposal is not supported")
ErrPositionNotOffsettable = errors.Register(ModuleName, 109, "position not offsettable")
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix typo in error message.

The error message contains a typo: "offsettable" should be "offsetable".

Apply this diff to correct the typo:

-	ErrPositionNotOffsettable                   = errors.Register(ModuleName, 109, "position not offsettable")
+	ErrPositionNotOffsettable                   = errors.Register(ModuleName, 109, "position not offsetable")
📝 Committable suggestion

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

Suggested change
ErrPositionNotOffsettable = errors.Register(ModuleName, 109, "position not offsettable")
ErrPositionNotOffsettable = errors.Register(ModuleName, 109, "position not offsetable")
🤖 Prompt for AI Agents
In chain/exchange/types/errors.go around line 117, the error message string
"position not offsettable" contains a typo; update the registered error to use
the corrected wording "position not offsetable" by changing the message passed
to errors.Register accordingly.

Comment on lines +71 to 78
return crypto.Keccak256Hash([]byte((EXPIRY_FUTURES_MARKET_ID_PREFIX +
oracleType.String() +
ticker +
quoteDenom +
oracleBase +
oracleQuote +
strconv.Itoa(int(expiry)))))
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Integer truncation risk: use FormatInt for expiry

Casting int64 expiry to int before formatting can overflow on 32‑bit platforms, producing inconsistent IDs across architectures. Use strconv.FormatInt.

Apply this diff:

- return crypto.Keccak256Hash([]byte((EXPIRY_FUTURES_MARKET_ID_PREFIX +
-   oracleType.String() +
-   ticker +
-   quoteDenom +
-   oracleBase +
-   oracleQuote +
-   strconv.Itoa(int(expiry)))))
+ return crypto.Keccak256Hash([]byte((EXPIRY_FUTURES_MARKET_ID_PREFIX +
+   oracleType.String() +
+   ticker +
+   quoteDenom +
+   oracleBase +
+   oracleQuote +
+   strconv.FormatInt(expiry, 10)))))
📝 Committable suggestion

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

Suggested change
return crypto.Keccak256Hash([]byte((EXPIRY_FUTURES_MARKET_ID_PREFIX +
oracleType.String() +
ticker +
quoteDenom +
oracleBase +
oracleQuote +
strconv.Itoa(int(expiry)))))
}
return crypto.Keccak256Hash([]byte((EXPIRY_FUTURES_MARKET_ID_PREFIX +
oracleType.String() +
ticker +
quoteDenom +
oracleBase +
oracleQuote +
strconv.FormatInt(expiry, 10)))))
}
🤖 Prompt for AI Agents
In chain/exchange/types/market.go around lines 71 to 78, the code casts the
int64 expiry to int and calls strconv.Itoa which can overflow on 32-bit
platforms; replace the cast and strconv.Itoa with strconv.FormatInt(expiry, 10)
(or fmt.Sprintf with %d for an int64) so the expiry is converted from int64
safely to a decimal string, and update the concatenation to use that formatted
string.

Comment on lines +1861 to +1916
func (*MsgOffsetPosition) Route() string {
return RouterKey
}

func (*MsgOffsetPosition) Type() string {
return TypeMsgOffsetPosition
}

func (msg *MsgOffsetPosition) ValidateBasic() error {
_, err := sdk.AccAddressFromBech32(msg.Sender)

if err != nil {
return errors.Wrap(sdkerrors.ErrInvalidAddress, msg.Sender)
}

if !types.IsHexHash(msg.MarketId) {
return errors.Wrap(types.ErrMarketInvalid, msg.MarketId)
}

_, ok := types.IsValidSubaccountID(msg.SubaccountId)
if !ok {
return errors.Wrap(types.ErrBadSubaccountID, msg.SubaccountId)
}

if len(msg.OffsettingSubaccountIds) == 0 {
return errors.Wrap(types.ErrOffsettingSubaccountIDsEmpty, "at least one offsetting subaccount ID must be provided")
}

for _, subaccountID := range msg.OffsettingSubaccountIds {
if _, ok := types.IsValidSubaccountID(subaccountID); !ok {
return errors.Wrap(types.ErrBadSubaccountID, subaccountID)
}

if subaccountID == msg.SubaccountId {
return errors.Wrap(types.ErrBadSubaccountID, "offsetting subaccount ID cannot be the same as the original subaccount ID")
}
}

if types.HasDuplicates(msg.OffsettingSubaccountIds) {
return errors.Wrap(types.ErrBadSubaccountID, "message contains duplicate offsetting subaccount IDs")
}

return nil
}

func (msg *MsgOffsetPosition) GetSignBytes() []byte {
return sdk.MustSortJSON(types.ModuleCdc.MustMarshalJSON(msg))
}

func (msg *MsgOffsetPosition) GetSigners() []sdk.AccAddress {
sender, err := sdk.AccAddressFromBech32(msg.Sender)
if err != nil {
panic(err)
}
return []sdk.AccAddress{sender}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

MsgOffsetPosition validation: normalize subaccount IDs for equality/dup checks.

Today duplicates and self-check use raw strings; hex case or 0x/no-0x variants could slip through. Normalize via common.HexToHash().Hex() before comparisons.

Apply this diff to robustly normalize:

@@
-  for _, subaccountID := range msg.OffsettingSubaccountIds {
-    if _, ok := types.IsValidSubaccountID(subaccountID); !ok {
-      return errors.Wrap(types.ErrBadSubaccountID, subaccountID)
-    }
-
-    if subaccountID == msg.SubaccountId {
-      return errors.Wrap(types.ErrBadSubaccountID, "offsetting subaccount ID cannot be the same as the original subaccount ID")
-    }
-  }
-
-  if types.HasDuplicates(msg.OffsettingSubaccountIds) {
-    return errors.Wrap(types.ErrBadSubaccountID, "message contains duplicate offsetting subaccount IDs")
-  }
+  // normalize all IDs to canonical hex
+  orig := common.HexToHash(msg.SubaccountId).Hex()
+  normalized := make([]string, 0, len(msg.OffsettingSubaccountIds))
+  for _, subaccountID := range msg.OffsettingSubaccountIds {
+    if _, ok := types.IsValidSubaccountID(subaccountID); !ok {
+      return errors.Wrap(types.ErrBadSubaccountID, subaccountID)
+    }
+    norm := common.HexToHash(subaccountID).Hex()
+    if norm == orig {
+      return errors.Wrap(types.ErrBadSubaccountID, "offsetting subaccount ID cannot be the same as the original subaccount ID")
+    }
+    normalized = append(normalized, norm)
+  }
+  if types.HasDuplicates(normalized) {
+    return errors.Wrap(types.ErrBadSubaccountID, "message contains duplicate offsetting subaccount IDs")
+  }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In chain/exchange/types/v2/msgs.go around lines 1861-1916, the MsgOffsetPosition
ValidateBasic currently compares raw subaccount ID strings (for self-check and
duplicate detection) which can miss equivalents with different hex casing or 0x
prefixes; normalize all subaccount IDs before equality and duplicate checks by
converting each ID to a canonical form (e.g., use common.HexToHash(id).Hex() or
a shared helper that strips 0x and lowercases/normalizes) and then perform the
comparisons: normalize msg.SubaccountId and each entry in
msg.OffsettingSubaccountIds before checking equality, before adding to any seen
set for duplicate detection, and when calling types.IsValidSubaccountID if that
function expects normalized input. Ensure the normalized values are only used
for validation (do not mutate original fields unless intended) and update the
HasDuplicates check to operate on the normalized slice.

Comment on lines +1656 to +1658
if err := ValidateOpenNotionalCap(p.OpenNotionalCap); err != nil {
return errors.Wrap(types.ErrInvalidOpenNotionalCap, err.Error())
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

BinaryOptionsMarketLaunchProposal now requires OpenNotionalCap in ValidateBasic but constructor doesn’t set it.

This will cause validation failures. Add an openNotionalCap parameter to the constructor and assign it, or default to an explicit Uncapped value.

Apply this diff to the constructor (signature + assignment):

@@
-func NewBinaryOptionsMarketLaunchProposal(
+func NewBinaryOptionsMarketLaunchProposal(
     title, description, ticker, oracleSymbol, oracleProvider string,
     oracleType oracletypes.OracleType, oracleScaleFactor uint32,
     expirationTimestamp, settlementTimestamp int64,
     admin, quoteDenom string,
-    makerFeeRate, takerFeeRate, minPriceTickSize, minQuantityTickSize, minNotional math.LegacyDec,
+    makerFeeRate, takerFeeRate, minPriceTickSize, minQuantityTickSize, minNotional math.LegacyDec,
+    openNotionalCap OpenNotionalCap,
 ) *BinaryOptionsMarketLaunchProposal {
     return &BinaryOptionsMarketLaunchProposal{
@@
-        MinNotional:         minNotional,
+        MinNotional:         minNotional,
+        OpenNotionalCap:     openNotionalCap,
     }
 }

If you prefer not to break callers, add an overload helper:

// NewBinaryOptionsMarketLaunchProposalWithCap is the preferred constructor including OpenNotionalCap.
func NewBinaryOptionsMarketLaunchProposalWithCap(
    title, description, ticker, oracleSymbol, oracleProvider string,
    oracleType oracletypes.OracleType, oracleScaleFactor uint32,
    expirationTimestamp, settlementTimestamp int64,
    admin, quoteDenom string,
    makerFeeRate, takerFeeRate, minPriceTickSize, minQuantityTickSize, minNotional math.LegacyDec,
    openNotionalCap OpenNotionalCap,
) *BinaryOptionsMarketLaunchProposal {
    p := NewBinaryOptionsMarketLaunchProposal(
        title, description, ticker, oracleSymbol, oracleProvider,
        oracleType, oracleScaleFactor, expirationTimestamp, settlementTimestamp,
        admin, quoteDenom, makerFeeRate, takerFeeRate, minPriceTickSize, minQuantityTickSize, minNotional,
    )
    p.OpenNotionalCap = openNotionalCap
    return p
}
🤖 Prompt for AI Agents
In chain/exchange/types/v2/proposal.go around lines 1656-1658, the
BinaryOptionsMarketLaunchProposal.ValidateBasic now requires OpenNotionalCap but
the existing constructor does not set it, causing validation failures; update
the primary constructor signature to accept an openNotionalCap parameter and
assign it to p.OpenNotionalCap, or alternatively add the new
NewBinaryOptionsMarketLaunchProposalWithCap helper that calls the existing
constructor then sets p.OpenNotionalCap to the provided value (or explicitly set
a default Uncapped value if you prefer not to change callers).

Comment on lines +86 to +88
OpenNotionalCap: exchangev2types.OpenNotionalCap{
Cap: &exchangev2types.OpenNotionalCap_Uncapped{},
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix Uncapped oneof: set the inner message to avoid nil.

Initialize the inner Uncapped message; otherwise the oneof may carry a nil payload.

Apply this diff:

-        OpenNotionalCap: exchangev2types.OpenNotionalCap{
-            Cap: &exchangev2types.OpenNotionalCap_Uncapped{},
-        },
+        OpenNotionalCap: exchangev2types.OpenNotionalCap{
+            Cap: &exchangev2types.OpenNotionalCap_Uncapped{
+                Uncapped: &exchangev2types.OpenNotionalCapUncapped{},
+            },
+        },
📝 Committable suggestion

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

Suggested change
OpenNotionalCap: exchangev2types.OpenNotionalCap{
Cap: &exchangev2types.OpenNotionalCap_Uncapped{},
},
OpenNotionalCap: exchangev2types.OpenNotionalCap{
Cap: &exchangev2types.OpenNotionalCap_Uncapped{
Uncapped: &exchangev2types.OpenNotionalCapUncapped{},
},
},
🤖 Prompt for AI Agents
In examples/chain/exchange/13_MsgInstantBinaryOptionsMarketLaunch/example.go
around lines 86 to 88, the OpenNotionalCap oneof sets Cap to
&exchangev2types.OpenNotionalCap_Uncapped{} which leaves the inner Uncapped
message nil; replace that with an initialized inner message so the oneof carries
a non-nil payload, e.g. set Cap to
&exchangev2types.OpenNotionalCap_Uncapped{Uncapped:
&exchangev2types.Uncapped{}}.

"injective.exchange.v2.MsgInstantSpotMarketLaunch",
"injective.exchange.v2.MsgLiquidatePosition",
"injective.exchange.v2.MsgMarketForcedSettlement",
"injective.exchange.v2.MsgOffsetPosition",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify MsgOffsetPosition proto definition in v2.

The new injective.exchange.v2.MsgOffsetPosition is correctly positioned alphabetically and represents new position offsetting functionality. Confirm the message is defined in the v2 exchange proto and that its corresponding handler is implemented.


🏁 Script executed:

#!/bin/bash
# Description: Verify MsgOffsetPosition exists in exchange v2 proto and check for handler implementation.

echo "=== Searching for MsgOffsetPosition definition ==="
find . -path "*exchange/v2*" -name "*.proto" -type f | xargs grep -A 5 "message MsgOffsetPosition" || echo "Proto definition not found"

echo -e "\n=== Searching for MsgOffsetPosition handler/implementation ==="
find . -name "*.go" -type f | xargs grep -l "MsgOffsetPosition" | head -10 || echo "Implementation not found"

Length of output: 1142


</script>

🏁 Script executed:

#!/bin/bash
# Verify MsgOffsetPosition handler implementation in the keeper

echo "=== Searching for MsgOffsetPosition in msgs.go ==="
grep -n "MsgOffsetPosition" ./chain/exchange/types/v2/msgs.go | head -20

echo -e "\n=== Searching for handler/keeper implementation ==="
find ./chain -name "*.go" -type f | xargs grep -l "OffsetPosition" | grep -v test | grep -v pb.go | xargs grep -B 3 -A 8 "func.*OffsetPosition" | head -40

echo -e "\n=== Checking message server or keeper method ==="
find ./chain -path "*/exchange/*" -name "*.go" -type f | xargs grep -n "MsgOffsetPosition" | grep -E "(Exec|msg_server)" | head -20

Length of output: 2631


</script>

🏁 Script executed:

#!/bin/bash
# Search for message server handler implementation

echo "=== Searching for msg_server.go in exchange v2 ==="
find ./chain -path "*/exchange/v2*" -name "*msg_server*" -o -path "*/exchange/v2*" -name "*keeper*" | grep -E "\.(go|proto)$"

echo -e "\n=== Searching for OffsetPosition in all exchange v2 go files ==="
find ./chain/exchange -path "*/v2/*" -name "*.go" ! -name "*.pb.go" -type f | xargs grep -l "OffsetPosition"

echo -e "\n=== Detailed search in keeper directory for OffsetPosition handler ==="
find ./chain/exchange -path "*/keeper/*" -name "*.go" ! -name "*.pb.go" | xargs grep -n "OffsetPosition" 2>/dev/null || echo "No matches in keeper"

echo -e "\n=== Checking for message server interface implementation ==="
find ./chain/exchange -path "*/v2/*" -name "*.go" ! -name "*.pb.go" | xargs grep -A 5 "func.*MsgOffsetPosition" | head -30

Length of output: 1784


Implement MsgOffsetPosition handler in exchange keeper.

The proto definition exists and message interface methods are implemented, but the corresponding keeper handler is missing. No OffsetPosition logic was found in the keeper directory, which means transactions cannot be processed. Add a OffsetPosition method to the message server/keeper to handle the actual position offsetting logic.

Comment on lines +399 to +468
// MsgInstantPerpetualMarketLaunch defines a SDK message for creating a new
// perpetual futures market by paying listing fee without governance
message MsgInstantPerpetualMarketLaunch {
option (amino.name) = "exchange/MsgInstantPerpetualMarketLaunch";
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
option (cosmos.msg.v1.signer) = "sender";

string sender = 1;
// Ticker for the derivative market.
string ticker = 2;
// type of coin to use as the base currency
string quote_denom = 3;
// Oracle base currency
string oracle_base = 4;
// Oracle quote currency
string oracle_quote = 5;
// Scale factor for oracle prices.
uint32 oracle_scale_factor = 6;
// Oracle type
injective.oracle.v1beta1.OracleType oracle_type = 7;
// maker_fee_rate defines the trade fee rate for makers on the perpetual
// market
string maker_fee_rate = 8 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];

// taker_fee_rate defines the trade fee rate for takers on the perpetual
// market
string taker_fee_rate = 9 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// initial_margin_ratio defines the initial margin ratio for the perpetual
// market
string initial_margin_ratio = 10 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// maintenance_margin_ratio defines the maintenance margin ratio for the
// perpetual market
string maintenance_margin_ratio = 11 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// min_price_tick_size defines the minimum tick size of the order's price and
// margin
string min_price_tick_size = 12 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// min_quantity_tick_size defines the minimum tick size of the order's
// quantity
string min_quantity_tick_size = 13 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// min_notional defines the minimum notional (in quote asset) required for
// orders in the market
string min_notional = 14 [
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

// MsgInstantPerpetualMarketLaunchResponse defines the
// Msg/InstantPerpetualMarketLaunchResponse response type.
message MsgInstantPerpetualMarketLaunchResponse {}

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

New messages lack Msg service RPCs — not routable.

MsgInstantPerpetualMarketLaunch and MsgInstantExpiryFuturesMarketLaunch are defined but not exposed in the Msg service; they cannot be broadcast/handled.

Add RPCs in the Msg service:

rpc InstantPerpetualMarketLaunch(MsgInstantPerpetualMarketLaunch)
    returns (MsgInstantPerpetualMarketLaunchResponse);

rpc InstantExpiryFuturesMarketLaunch(MsgInstantExpiryFuturesMarketLaunch)
    returns (MsgInstantExpiryFuturesMarketLaunchResponse);

Also confirm intentional removal of UpdateParams RPC while keeping the message type.

Also applies to: 534-604


🏁 Script executed:

#!/bin/bash
# Find and display the Msg service definition in the tx.proto file
rg -n "service Msg" proto/injective/exchange/v1beta1/tx.proto -A 100

Length of output: 4828


🏁 Script executed:

#!/bin/bash
# Search for InstantPerpetualMarketLaunch and InstantExpiryFuturesMarketLaunch message definitions
rg -n "message MsgInstant(PerpetualMarketLaunch|ExpiryFuturesMarketLaunch)" proto/injective/exchange/v1beta1/tx.proto

Length of output: 209


🏁 Script executed:

#!/bin/bash
# Check for UpdateParams RPC in the service
rg -n "UpdateParams" proto/injective/exchange/v1beta1/tx.proto

Length of output: 124


🏁 Script executed:

#!/bin/bash
# Display the full structure around lines 399-468 and 534-604 to verify message definitions
sed -n '395,610p' proto/injective/exchange/v1beta1/tx.proto

Length of output: 7925


uint64 last_outgoing_pool_id = 13;
Valset last_observed_valset = 14 [ (gogoproto.nullable) = false ];
repeated string ethereum_blacklist = 15;
repeated RateLimit rate_limits = 16;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify genesis state initialization handles rate_limits field.

The addition of rate_limits field (field number 16) to GenesisState enables rate limiting functionality. The field number is appropriately sequential and the type is correctly imported.

Verify that genesis initialization and export logic properly handle the new rate_limits field:


🏁 Script executed:

#!/bin/bash
# Description: Verify genesis state initialization includes rate_limits handling

# Search for GenesisState initialization and export functions
ast-grep --pattern $'func $_($$$) GenesisState {
  $$$
}'

# Search for genesis export functions that should handle rate_limits
ast-grep --pattern $'func ExportGenesis($$$) $_ {
  $$$
}'

# Search for InitGenesis functions
ast-grep --pattern $'func InitGenesis($$$) {
  $$$
  rate_limits
  $$$
}'

Length of output: 173



🏁 Script executed:

#!/bin/bash
# Search for peggy-specific genesis handling code

# Find Go files in peggy modules that might contain genesis handlers
fd --type f -e go -p '*peggy*' | grep -E '(genesis|keeper)' | head -20

# Search for InitGenesis and ExportGenesis functions in peggy context
rg -n 'func (InitGenesis|ExportGenesis)' --type go | grep -i peggy

# Look for files that import peggy genesis types
rg -n 'peggy.*genesis' --type go -i

Length of output: 629


</script>

🏁 Script executed:

#!/bin/bash
# Find all files in peggy directory structure
fd --type f -e go 'chain/peggy' | head -30

# Search for InitGenesis and ExportGenesis functions globally
rg -n 'func InitGenesis|func ExportGenesis' --type go -A 5 | grep -A 5 -B 2 'peggy'

# Search for rate_limits usage in Go files
rg -n 'rate_limits' --type go | grep -i peggy

Length of output: 538


</script>

🏁 Script executed:

#!/bin/bash
# List Go files in chain/peggy directory
fd --type f -e go . 'chain/peggy'

# Search for InitGenesis and ExportGenesis functions
rg -n 'func.*InitGenesis|func.*ExportGenesis' --type go

# Search for RateLimits or rate_limits in peggy code
rg -n 'RateLimits|rate_limits' --type go | grep -E 'chain/peggy.*go'

Length of output: 1752


</script>

🏁 Script executed:

#!/bin/bash
# Find keeper or module handler files in peggy
fd --type f -e go . 'chain/peggy' | grep -E '(keeper|module|handler)'

# List all directories under chain/peggy
fd --type d . 'chain/peggy'

# Search more broadly for InitGenesis in all code
rg -n 'InitGenesis' --type go -B 2 -A 10

# Search for ExportGenesis in all code
rg -n 'ExportGenesis' --type go -B 2 -A 10

Length of output: 18


</script>

🏁 Script executed:

#!/bin/bash
# Check full peggy directory structure
find chain/peggy -type f -name "*.go" | sort

# Search for any "peggy" module app or genesis registration
rg -n 'peggy.*module|peggy.*keeper|NewKeeper.*peggy' --type go -i

# Look for keeper in parent chain directory
fd --type d 'keeper' . 'chain'

# Search entire codebase for any InitGenesis pattern
rg -n 'type.*Keeper.*struct' --type go | head -20

Length of output: 3401


</script>

🏁 Script executed:

#!/bin/bash
# Look for app configuration and module registration
fd --type f -e go 'app.go'

# Search for peggy keeper anywhere in codebase
rg -n 'Keeper.*peggy|peggy.*Keeper' --type go -i

# Look for module setup files
fd --type f -e go | xargs grep -l 'peggy.*Module\|peggy.*Genesis' 2>/dev/null | head -10

# Check if there's a keeper directory at root or app level
fd --type d 'keeper'

Length of output: 61


</script>

🏁 Script executed:

#!/bin/bash
# Check if there are any Go files outside chain/peggy/types that reference peggy
rg -n 'package peggy|import.*peggy' --type go | grep -v 'chain/peggy/types' | head -20

# List entire chain/peggy directory structure
ls -la chain/peggy/ 2>/dev/null || echo "Directory listing failed"

# Search for any keeper implementation files anywhere
rg -n 'type.*Keeper struct' --type go | grep -i peggy

# Final check: see if module is registered in app
rg -n 'peggy' --type go | grep -E '(app\.go|module|Module|NewAppModule)' | head -20

Length of output: 1150


Genesis handlers for peggy module must be implemented to process the new rate_limits field.

The rate_limits field has been correctly added to GenesisState in the protobuf (field number 16) and properly generated in chain/peggy/types/genesis.pb.go with marshaling/unmarshaling support. However, verification reveals that the peggy module lacks InitGenesis and ExportGenesis handler implementations. Without these handlers:

  • The rate_limits field cannot be initialized from genesis files at chain startup
  • The rate_limits field cannot be exported during genesis export operations

Either implement genesis handlers for the peggy module to properly process this field, or confirm that peggy genesis handling is managed externally elsewhere in the application.

🤖 Prompt for AI Agents
In proto/injective/peggy/v1/genesis.proto around line 32 the new repeated field
rate_limits was added but the peggy module lacks InitGenesis and ExportGenesis
handlers to persist and export that field; implement InitGenesis to accept the
generated GenesisState, validate it (or call existing validation), iterate over
genesis.RateLimits and store each RateLimit into the peggy keeper/store (using
existing keeper methods or add new ones), and implement ExportGenesis to read
all rate limits from the keeper/store and populate a GenesisState.RateLimits
slice for export; then wire these functions into the module's AppModule
(module.go) InitGenesis/ExportGenesis hooks and add any necessary keeper
accessors and tests to ensure genesis load/export round-trips the rate_limits
field.

Comment on lines +57 to 60
// The creator's Injective address
string creator = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ];
// The sub-denom
string sub_denom = 2 [ (gogoproto.moretags) = "yaml:\"sub_denom\"" ];
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix YAML tag mismatch on the creator field.

The field creator on line 58 has a yaml tag of "denom", but the field name and HTTP route parameter (line 25) both use creator. This mismatch will cause serialization/deserialization inconsistencies.

Apply this diff to correct the yaml tag:

  message QueryDenomAuthorityMetadataRequest {
    // The creator's Injective address
-   string creator = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ];
+   string creator = 1 [ (gogoproto.moretags) = "yaml:\"creator\"" ];
    // The sub-denom
    string sub_denom = 2 [ (gogoproto.moretags) = "yaml:\"sub_denom\"" ];
  }
📝 Committable suggestion

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

Suggested change
// The creator's Injective address
string creator = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ];
// The sub-denom
string sub_denom = 2 [ (gogoproto.moretags) = "yaml:\"sub_denom\"" ];
// The creator's Injective address
string creator = 1 [ (gogoproto.moretags) = "yaml:\"creator\"" ];
// The sub-denom
string sub_denom = 2 [ (gogoproto.moretags) = "yaml:\"sub_denom\"" ];
🤖 Prompt for AI Agents
In proto/injective/tokenfactory/v1beta1/query.proto around lines 57 to 60, the
`creator` field currently has an incorrect YAML tag `yaml:"denom"`; update the
gogoproto.moretags for the `creator` field to use `yaml:"creator"` so the proto
field, HTTP route parameter, and serialization tag are consistent and avoid
(de)serialization mismatches.

Comment on lines 80 to 84
// QueryDenomsFromCreatorRequest defines the response structure for the
// DenomsFromCreator gRPC query.
message QueryDenomsFromCreatorResponse {
// The list of denoms
repeated string denoms = 1 [ (gogoproto.moretags) = "yaml:\"denoms\"" ];
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Correct the comment copy-paste error.

Line 80 references QueryDenomsFromCreatorRequest as the message name, but the message on line 82 is QueryDenomsFromCreatorResponse. The comment should match.

Apply this diff:

- // QueryDenomsFromCreatorRequest defines the response structure for the
+ // QueryDenomsFromCreatorResponse defines the response structure for the
  // DenomsFromCreator gRPC query.
  message QueryDenomsFromCreatorResponse {
📝 Committable suggestion

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

Suggested change
// QueryDenomsFromCreatorRequest defines the response structure for the
// DenomsFromCreator gRPC query.
message QueryDenomsFromCreatorResponse {
// The list of denoms
repeated string denoms = 1 [ (gogoproto.moretags) = "yaml:\"denoms\"" ];
// QueryDenomsFromCreatorResponse defines the response structure for the
// DenomsFromCreator gRPC query.
message QueryDenomsFromCreatorResponse {
// The list of denoms
repeated string denoms = 1 [ (gogoproto.moretags) = "yaml:\"denoms\"" ];
🤖 Prompt for AI Agents
In proto/injective/tokenfactory/v1beta1/query.proto around lines 80 to 84, the
comment header incorrectly names the message as QueryDenomsFromCreatorRequest
while the declared message is QueryDenomsFromCreatorResponse; update the comment
to reference QueryDenomsFromCreatorResponse (e.g.,
"QueryDenomsFromCreatorResponse defines the response structure for the
DenomsFromCreator gRPC query.") so the comment matches the message name and
intent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants