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

  • New Features

    • Position offsetting for perpetual/derivative positions.
    • Instant market launches for perpetual and expiry futures.
    • OpenNotionalCap to limit market exposure.
    • Open interest query endpoint and example.
    • Streaming support for order failure and conditional-trigger-failure events.
    • Peggy rate-limit messages for cross-chain transfers.
  • Improvements

    • Denom query names clarified to "auction exchange transfer".
    • Batch order updates extended with spot/derivative/binary 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

Adds MsgOffsetPosition and OpenNotionalCap across protobufs and Go types; introduces Peggy rate-limit messages and OpenInterest query; renames denom-decimal RPCs to auction_exchange_transfer variants; updates client interfaces, examples, ABI formatting, and several codec/registration changes.

Changes

Cohort / File(s) Summary
Exchange protobufs & core types
proto/injective/exchange/v1beta1/*.proto, proto/injective/exchange/v2/*.proto, chain/exchange/types/*.go, chain/exchange/types/v2/*.go
Added OpenNotionalCap message and fields to markets and proposals; introduced MsgInstantPerpetualMarketLaunch / MsgInstantExpiryFuturesMarketLaunch and MsgOffsetPosition; renamed denom-decimal RPCs to auction_exchange_transfer variants; added OpenInterest RPC and orderbook seq fields; added post_only_mode_blocks_amount_after_downtime param; updated many v2 messages, validation, getters, and proposal constructors; removed MsgSetDelegationTransferReceivers.
Stream & examples
proto/injective/stream/v2/query.proto, examples/chain/12_ChainStream/example.go, various exchange examples examples/chain/exchange/*
Added order failure and conditional-trigger-failure filters and update types; updated examples to use new filters, OpenNotionalCap fields, auction_exchange_transfer denom calls, OpenInterest examples, and MsgOffsetPosition example.
Peggy protobufs & types
proto/injective/peggy/v1/*.proto, chain/peggy/types/*.go
Added rate-limit proto (RateLimit, BridgeTransfer), MsgCreate/Update/RemoveRateLimit RPCs/messages, genesis rate_limits field, and EventValidatorJailed/JailReason. Registered new msg types in codec/interface registry.
Tokenfactory, txfees & related protos
proto/injective/tokenfactory/*, proto/injective/txfees/*, proto/osmosis/txfees/*
Added small request/response fields (sub_denom, denoms, base_fee) and minor documentation comments; added fields to several tx messages (name, symbol, receiver, burnFromAddress, change-admin fields).
EVM/abigen & errors
chain/evm/precompiles/*, chain/evm/types/errors.go
Reformatted ABI JSON strings and updated Bin values for several precompile bindings; added RevertSelector and RevertReasonBytes() helper for ABI-encoded revert reasons.
Client interfaces & implementation
client/chain/chain_v2.go, client/chain/context.go, client/chain/chain_test_support.go
Renamed FetchDenomDecimal(s) → FetchAuctionExchangeTransferDenomDecimal(s), added FetchOpenInterest; registered Hyperlane module interfaces in codec. Test support mocks updated accordingly.
Client utilities & tests
client/chain/markets_assistant*.go, client/exchange/exchange_test_support.go
Removed ExchangeClient dependency from MarketsAssistant constructors and related tests; removed large MockExchangeClient test support file.
Makefile, go.mod, injective_data
Makefile, go.mod, injective_data/chain_messages_list.json
Updated clone tags and find/extract logic in Makefile; bumped and added dependencies (hyperlane-cosmos, cosmos-sdk/cometbft/ethereum variants); updated chain_messages_list.json with new/removed messages.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Client as Chain Client V2
    participant Msg as MsgOffsetPosition
    participant Node as Node/Broadcast

    User->>Client: AsyncBroadcastMsg(MsgOffsetPosition)
    Client->>Msg: ValidateBasic()
    Note over Msg: validate sender, market_id, subaccount,\noffsetting subaccounts, nonces, duplicates
    Msg-->>Client: validation result
    Client->>Msg: GetSignBytes() / GetSigners()
    Msg-->>Client: sign bytes / signers
    Client->>Node: Broadcast transaction
    Node-->>Client: Tx response
    Client-->>User: formatted response
Loading
sequenceDiagram
    participant User
    participant Client as Chain Client V2
    participant Msg as MsgInstant*MarketLaunch
    participant Node as Node/Broadcast

    User->>Client: Create market launch message
    Client->>Msg: ValidateBasic()
    Note over Msg: validate ticker, denoms, oracle params,\nfees, margins, tick/notional, OpenNotionalCap
    alt OpenNotionalCap present
        Msg->>Msg: ValidateOpenNotionalCap()
    end
    Msg-->>Client: validation result
    Client->>Node: Broadcast transaction
    Node-->>Client: Tx response
    Client-->>User: success / error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Areas warranting extra attention:
    • Proto changes impacting wire formats (exchange v2/v1beta1, peggy): ensure generated code and migrations align.
    • MsgOffsetPosition and related validation/duplicate-detection logic across msgs and batch order flows.
    • Removal of MockExchangeClient: tests depending on it need replacement or adjustments.
    • Renamed RPCs and client method surface (denom → auction_exchange_transfer): verify all call sites and generated clients updated.
    • ABI/Bin changes and RevertReasonBytes: confirm no behavioural regressions in contract bindings.

Poem

🐰
I nibble on caps and offset the plot,
rate limits and launches — I like this new spot.
Orders may fail, streams carry the cry,
Open interest peaks, then hops me nearby.
A happy rabbit in protobuf sky.

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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'CP-651 update protos for v1.17.0 upgrade' directly and clearly summarizes the main change - updating proto definitions for a specific version upgrade.
✨ 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

📜 Recent 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 0cf6aec and 2a8c959.

⛔ Files ignored due to path filters (30)
  • chain/exchange/types/exchange.pb.go is excluded by !**/*.pb.go
  • chain/exchange/types/v2/market.pb.go is excluded by !**/*.pb.go
  • exchange/accounts_rpc/pb/goadesign_goagen_injective_accounts_rpc.pb.go is excluded by !**/*.pb.go
  • exchange/accounts_rpc/pb/goadesign_goagen_injective_accounts_rpc_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/auction_rpc/pb/goadesign_goagen_injective_auction_rpc.pb.go is excluded by !**/*.pb.go
  • exchange/auction_rpc/pb/goadesign_goagen_injective_auction_rpc_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/campaign_rpc/pb/goadesign_goagen_injective_campaign_rpc.pb.go is excluded by !**/*.pb.go
  • exchange/campaign_rpc/pb/goadesign_goagen_injective_campaign_rpc_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/derivative_exchange_rpc/pb/goadesign_goagen_injective_derivative_exchange_rpc.pb.go is excluded by !**/*.pb.go
  • exchange/derivative_exchange_rpc/pb/goadesign_goagen_injective_derivative_exchange_rpc_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/event_provider_api/pb/goadesign_goagen_event_provider_api.pb.go is excluded by !**/*.pb.go
  • exchange/event_provider_api/pb/goadesign_goagen_event_provider_api_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/exchange_rpc/pb/goadesign_goagen_injective_exchange_rpc.pb.go is excluded by !**/*.pb.go
  • exchange/exchange_rpc/pb/goadesign_goagen_injective_exchange_rpc_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/explorer_rpc/pb/goadesign_goagen_injective_explorer_rpc.pb.go is excluded by !**/*.pb.go
  • exchange/explorer_rpc/pb/goadesign_goagen_injective_explorer_rpc_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/health_rpc/pb/goadesign_goagen_health.pb.go is excluded by !**/*.pb.go
  • exchange/health_rpc/pb/goadesign_goagen_health_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/insurance_rpc/pb/goadesign_goagen_injective_insurance_rpc.pb.go is excluded by !**/*.pb.go
  • exchange/insurance_rpc/pb/goadesign_goagen_injective_insurance_rpc_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/meta_rpc/pb/goadesign_goagen_injective_meta_rpc.pb.go is excluded by !**/*.pb.go
  • exchange/meta_rpc/pb/goadesign_goagen_injective_meta_rpc_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/oracle_rpc/pb/goadesign_goagen_injective_oracle_rpc.pb.go is excluded by !**/*.pb.go
  • exchange/oracle_rpc/pb/goadesign_goagen_injective_oracle_rpc_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/portfolio_rpc/pb/goadesign_goagen_injective_portfolio_rpc.pb.go is excluded by !**/*.pb.go
  • exchange/portfolio_rpc/pb/goadesign_goagen_injective_portfolio_rpc_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/spot_exchange_rpc/pb/goadesign_goagen_injective_spot_exchange_rpc.pb.go is excluded by !**/*.pb.go
  • exchange/spot_exchange_rpc/pb/goadesign_goagen_injective_spot_exchange_rpc_grpc.pb.go is excluded by !**/*.pb.go
  • exchange/trading_rpc/pb/goadesign_goagen_injective_trading_rpc.pb.go is excluded by !**/*.pb.go
  • exchange/trading_rpc/pb/goadesign_goagen_injective_trading_rpc_grpc.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (4)
  • Makefile (2 hunks)
  • chain/exchange/types/v2/events.go (2 hunks)
  • proto/injective/exchange/v1beta1/exchange.proto (2 hunks)
  • proto/injective/exchange/v2/market.proto (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • proto/injective/exchange/v2/market.proto
🧰 Additional context used
🧬 Code graph analysis (1)
chain/exchange/types/v2/events.go (1)
chain/exchange/types/v2/events.pb.go (9)
  • EventOrderFail (1698-1703)
  • EventOrderFail (1707-1707)
  • EventOrderFail (1708-1710)
  • EventTriggerConditionalMarketOrderFailed (2393-2400)
  • EventTriggerConditionalMarketOrderFailed (2406-2406)
  • EventTriggerConditionalMarketOrderFailed (2407-2409)
  • EventTriggerConditionalLimitOrderFailed (2472-2479)
  • EventTriggerConditionalLimitOrderFailed (2485-2485)
  • EventTriggerConditionalLimitOrderFailed (2486-2488)
⏰ 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). (2)
  • GitHub Check: lint
  • GitHub Check: run-tests
🔇 Additional comments (7)
proto/injective/exchange/v1beta1/exchange.proto (2)

19-38: Proto schema additions look well-formed and integrate correctly.

The new OpenNotionalCap construct with its uncapped/capped variants follows proper protobuf conventions. Field numbering (1, 2) within the oneof is correct, and all proto options and annotations are consistently applied with the file's established patterns (compare to field patterns in Params message at lines 56–80). The empty OpenNotionalCapUncapped message is a valid marker-type pattern in proto3.


305-307: Field addition to DerivativeMarket is correctly integrated.

Field number 22 properly follows the existing sequence (field 21 at line 301). The (gogoproto.nullable) = false annotation is appropriate and consistent with other non-nullable embedded message fields throughout the file (e.g., order_info fields). The comment at line 306 clearly documents the field's purpose.

Makefile (2)

4-4: Let me verify if the beta versions mentioned in the PR description also exist:

Based on the verification results:

Both version tags exist in the upstream repositories — injective-indexer v1.17.16 and injective-core v1.17.0 are valid and cloneable. However, the Makefile versions differ from the PR description, which references "v1.17.0-beta" for indexer and "v1.17.0-beta.3" for core. These beta versions were not found in the web search results.

Confirm version mismatch between PR description and Makefile implementation. The Makefile correctly references valid release versions, but the PR description references different (beta) versions. Clarify whether:

  • The beta versions should be used instead, or
  • The PR description should be updated to match the Makefile

169-169: Extract-message-names enhancement verified and approved.

The updated find command correctly extends message extraction to include both tx.pb.go and msgs.pb.go files using proper find syntax. Verification confirms both file types exist throughout the chain module structure (e.g., ./chain/peggy/types/msgs.pb.go, ./chain/auction/types/tx.pb.go, etc.), validating that the expanded grep extraction will capture message definitions from both sources.

chain/exchange/types/v2/events.go (3)

3-6: LGTM!

The import of cosmossdk.io/math is necessary for the new GetMarkPrice() methods that return math.LegacyDec type.


39-45: LGTM!

The getter methods provide explicit accessors for the MarkPrice field on both conditional order failure events. These methods correctly return the math.LegacyDec mark price value and likely support interface compliance or maintain a consistent API pattern.


29-33: No issues found; the code change is correct.

The verification confirms that empty CID strings are acceptable and intentionally handled throughout the codebase. Downstream code in chain/exchange/types/v2/msgs.go and chain/exchange/types/common_order.go explicitly checks for empty CIDs using cid != "", treating them as "no CID provided." By appending CIDs unconditionally, the three parallel arrays (Hashes, Flags, Cids) remain aligned while allowing empty entries to represent the absence of a CID—this is semantically correct and improves data consistency.


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.

@aarmoa aarmoa merged commit a9bfddd into dev Nov 10, 2025
6 checks passed
@aarmoa aarmoa deleted the cp-651/update_protos_for_v1_17_0_upgrade branch November 10, 2025 14:51
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