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

Summary by CodeRabbit

  • New Features

    • Added instant market launch for perpetual and expiry futures markets
    • Introduced position offsetting functionality via new transaction type
    • Added open notional cap configuration for derivative and binary options markets
    • Enabled open interest queries for markets
    • Implemented rate limiting for bridge transfer tokens
    • Added order failure and conditional order trigger failure event streaming
  • Updates

    • Renamed denomination decimal queries for auction exchange transfers
    • Extended batch order updates to support market orders
    • Added post-only mode recovery period parameter

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

coderabbitai bot commented Oct 17, 2025

Walkthrough

This pull request introduces open notional cap constraints for derivative and binary options markets, adds position offsetting functionality via new MsgOffsetPosition and MsgInstantMarketLaunch messages, renames denomination queries to auction transfer variants, implements rate limiting in the Peggy module, and updates multiple protocol buffer definitions and corresponding Go implementations. The chain client removes external exchange client dependency.

Changes

Cohort / File(s) Summary
Makefile & Build
Makefile
Updated git clone references to v1.17.0-beta and v1.17.0-beta.3; enhanced message extraction for both tx.pb.go and msgs.pb.go files.
EVM Precompiles ABI Reformatting
chain/evm/precompiles/bank/*, chain/evm/precompiles/staking/i_staking_module.abigen.go
Restructured ABI JSON strings in contract metadata for FixedSupplyBankERC20, BankModule, MintBurnBankERC20, and StakingModule precompiles with reordered fields and internalType support; updated corresponding bytecode references.
EVM Error Handling
chain/evm/types/errors.go
Added RevertSelector (Keccak256 hash of "Error(string)") and RevertReasonBytes() function for ABI-encoded revert reason construction.
Exchange Type Core
chain/exchange/types/codec.go, chain/exchange/types/market.go, chain/exchange/types/key.go
Registered MsgInstantPerpetualMarketLaunch and MsgInstantExpiryFuturesMarketLaunch in codec; added four market ID prefixes (SPOT, PERPETUAL, EXPIRY_FUTURES, BINARY_OPTIONS); introduced DerivativeMarketOpenInterestPrefix store key.
Exchange Error & Permission Updates
chain/exchange/types/errors.go, chain/exchange/types/market_admin.go
Renamed error messages to lowercase; added three new errors (ErrPositionNotOffsettable, ErrOffsettingSubaccountIDsEmpty, ErrInvalidOpenNotionalCap); added OpenNotionalCapPerm flag to MarketAdminPermissions.
Exchange Parameter Validation
chain/exchange/types/params.go
Added MaxTickSizeDecimalPlaces constant (15); removed MinDerivativeOrderPrice; refactored ValidateTickSize with dynamic decimal scaling; replaced derivative price lower-bound check with explicit conditional trigger price validation.
Exchange Message Types
chain/exchange/types/msgs.go
Added MsgInstantPerpetualMarketLaunch and MsgInstantExpiryFuturesMarketLaunch with full validation; removed price lower-bound check; updated trigger price validation logic.
Expected Keepers
chain/exchange/types/expected_keepers.go
Removed SetDelegationTransferReceiver method from StakingKeeper interface.
Exchange v2 Types
chain/exchange/types/v2/codec.go, chain/exchange/types/v2/msgs.go, chain/exchange/types/v2/events.go, chain/exchange/types/v2/market.go
Registered MsgOffsetPosition and replaced UpdateDenomDecimalsProposal with UpdateAuctionExchangeTransferDenomDecimalsProposal in codec; added GetMarkPrice() accessors; added GetOpenNotionalCap() getters to markets; implemented MsgOffsetPosition with validation for sender, market ID, subaccounts, and non-duplicate offsetting IDs; added ensureNoDuplicateMarketOrders() helper and integrated into MsgBatchUpdateOrders; extended validation to include OpenNotionalCap checks.
Exchange v2 Parameters & Position
chain/exchange/types/v2/params.py, chain/exchange/types/v2/position.go
Added PostOnlyModeBlocksAmountAfterDowntime parameter; added ValidatePostOnlyModeBlocksAmountAfterDowntime() and ValidateOpenNotionalCap() validators; updated GetLiquidationMarketOrderWorstPrice() to return pointer; added GetOffsettingMarketOrderWorstPrice() method.
Exchange v2 Proposals
chain/exchange/types/v2/proposal.go
Renamed UpdateDenomDecimalsProposal to UpdateAuctionExchangeTransferDenomDecimalsProposal; added OpenNotionalCap field to multiple market launch and param update proposals (Perpetual, ExpiryFutures, BinaryOptions, DerivativeMarketParam); updated all associated validators and constructors.
Peggy Types
chain/peggy/types/codec.go, chain/peggy/types/key.go
Registered rate limit messages (MsgCreateRateLimit, MsgUpdateRateLimit, MsgRemoveRateLimit) in codec; added RateLimitsKey and MintAmountsERC20Key store prefixes; added GetMintAmountERC20Key() helper.
Client Chain v2
client/chain/chain_v2.go, client/chain/chain_test_support.go
Renamed FetchDenomDecimal/FetchDenomDecimals to FetchAuctionExchangeTransferDenomDecimal/FetchAuctionExchangeTransferDenomDecimals with updated request/response types; added FetchOpenInterest() method; updated mock implementations accordingly.
Markets Assistant
client/chain/markets_assistant.go, client/chain/markets_assistant_test.go, client/chain/markets_assistant_test_support.go, client/chain/context.go
Removed exchange client parameter from NewMarketsAssistantWithAllTokens() and NewHumanReadableMarketsAssistantWithAllTokens(); removed exchange import from tests; added hyperlane-cosmos module imports; set OpenNotionalCap to Uncapped for BTC/USDT test market.
Exchange Test Support Deletion
client/exchange/exchange_test_support.go
Removed entire MockExchangeClient type and all associated method implementations.
Examples - Market Launches & Offsetting
examples/chain/exchange/4_MsgInstantPerpetualMarketLaunch/example.go, examples/chain/exchange/5_MsgInstantExpiryFuturesMarketLaunch/example.go, examples/chain/exchange/13_MsgInstantBinaryOptionsMarketLaunch/example.go, examples/chain/exchange/30_MsgOffsetPosition/example.go
Added OpenNotionalCap fields to market launch examples; created new MsgOffsetPosition example with async broadcast and gas price handling.
Examples - Batch Orders & Queries
examples/chain/exchange/9_MsgBatchUpdateOrders/example.go, examples/chain/exchange/25_MsgUpdateDerivativeMarket/example.go, examples/chain/exchange/query/...*
Added spot/derivative market orders to batch update; added OpenNotionalCap to derivative market update; renamed denom query examples to auction variants; added OpenInterest query example.
Examples - Streaming & Explorer
examples/chain/12_ChainStream/example.go, examples/explorer/...*
Added OrderFailuresFilter and ConditionalOrderTriggerFailuresFilter to stream request; updated explorer examples with new network/address/hash values.
Proto - Exchange
proto/injective/exchange/v1beta1/...*, proto/injective/exchange/v2/...*
Added OpenNotionalCap message and variants; added MsgInstantPerpetualMarketLaunch, MsgInstantExpiryFuturesMarketLaunch to v1beta1 tx; removed UpdateParams RPC; added OffsettingPosition execution type; added PostOnlyModeBlocksAmountAfterDowntime param; renamed DenomDecimals proposals to AuctionExchangeTransferDenomDecimals; added OpenNotionalCap to market launch/param proposals; added MsgOffsetPosition and MsgOffsetPositionResponse; added OpenInterest RPC; added seq fields to orderbook responses; renamed denom queries to auction variants.
Proto - Peggy
proto/injective/peggy/v1/...*
Added rate_limit.proto with RateLimit and BridgeTransfer messages; added rate limit messages (MsgCreateRateLimit, etc.) to msgs.proto; added rate_limits to genesis; added JailReason enum and EventValidatorJailed message to events.
Proto - Permissions, Token Factory, Stream
proto/injective/permissions/v1beta1/...*, proto/injective/tokenfactory/v1beta1/...*, proto/injective/stream/v2/query.proto, proto/osmosis/txfees/v1beta1/query.proto
Added documentation comments to permissions proto files; added name, symbol fields to MsgCreateDenom; added receiver to MsgMint; added burnFromAddress to MsgBurn; added denom, new_admin to MsgChangeAdmin; added sub_denom to QueryDenomAuthorityMetadataRequest; added denoms to QueryDenomsFromCreatorResponse; added order failure stream filters and update messages; added base_fee to QueryEipBaseFeeResponse.
Dependencies
go.mod
Added hyperlane-cosmos v1.0.1-inj; bumped cosmos-sdk v0.50.9→v0.50.12; bumped cometbft, ibc-go, ethereum/go-ethereum to InjectiveLabs versions; updated indirect dependencies (pebble, gnark-crypto, fastssz, etc.).
Message Registry
injective_data/chain_messages_list.json
Added MsgInstantExpiryFuturesMarketLaunch, MsgInstantPerpetualMarketLaunch (v1beta1), MsgOffsetPosition (v2), and Peggy rate limit messages; removed MsgSetDelegationTransferReceivers.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant ChainClient as Chain Client
    participant Validator as Validator
    participant Mempool as Mempool/Chain
    
    User->>ChainClient: MsgOffsetPosition(sender, market, offsetting_subaccounts)
    ChainClient->>ChainClient: ValidateBasic()
    activate ChainClient
    note over ChainClient: - Validate sender address<br/>- Validate market ID hex<br/>- Validate subaccount<br/>- Check nonces non-empty<br/>- Ensure no self-offsetting<br/>- Check no duplicate offsetting IDs
    deactivate ChainClient
    
    ChainClient->>ChainClient: GetSignBytes() + GetSigners()
    ChainClient->>Validator: AsyncBroadcastMsg(signed_tx)
    Validator->>Mempool: Add to mempool
    Mempool->>Validator: Tx included in block
    Validator-->>ChainClient: Response (tx_hash)
    ChainClient-->>User: tx_hash + result JSON
Loading
sequenceDiagram
    actor Admin
    participant ProposalHandler as Proposal Handler
    participant Validator as Network
    
    Admin->>ProposalHandler: MsgInstantPerpetualMarketLaunch / MsgInstantExpiryFuturesMarketLaunch
    activate ProposalHandler
    note over ProposalHandler: Validate:<br/>- Sender address<br/>- Ticker + denom format<br/>- Oracle parameters<br/>- Fee/margin constraints<br/>- Tick size constraints<br/>- OpenNotionalCap (new)
    alt OpenNotionalCap present
        ProposalHandler->>ProposalHandler: ValidateOpenNotionalCap()
        note over ProposalHandler: Enforce mutual exclusivity<br/>and non-negative cap values
    end
    deactivate ProposalHandler
    
    ProposalHandler->>Validator: Create market with prefixed ID
    note over Validator: Market ID = PREFIX + components
    Validator-->>Admin: Market created (market_id)
Loading
sequenceDiagram
    participant Client as Client
    participant ChainRPC as Chain RPC
    
    Client->>ChainRPC: FetchAuctionExchangeTransferDenomDecimal(denom)
    note over ChainRPC: (renamed from FetchDenomDecimal)
    activate ChainRPC
    ChainRPC->>ChainRPC: Query QueryAuctionExchangeTransferDenomDecimalRequest
    note over ChainRPC: (updated request type)
    deactivate ChainRPC
    ChainRPC-->>Client: QueryAuctionExchangeTransferDenomDecimalResponse
    
    Client->>ChainRPC: FetchOpenInterest(marketId)
    note over ChainRPC: (new endpoint)
    ChainRPC-->>Client: QueryOpenInterestResponse { balance: LegacyDec }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60–75 minutes

Complexity factors:

  • Heterogeneous changes: Proto definitions, generated Go types, type implementations, client APIs, examples, and dependencies all modified in coordinated fashion.
  • Dense logic: OpenNotionalCap validation across 8+ proposal and message types; market ID prefix logic; position offsetting with worst-price calculations; duplicate order detection.
  • Breaking changes: Client API method renames (FetchDenomDecimal → FetchAuctionExchangeTransferDenomDecimal); removal of exchange client dependency; removal of MsgSetDelegationTransferReceivers.
  • Scope: 90+ files across multiple subsystems (exchange, peggy, client, proto, examples); multiple new features integrated (offset position, rate limiting, open notional caps).
  • Protocol changes: Extensive proto modifications require careful validation that request/response types align across v1beta1 and v2 variants.

Rationale: While many changes follow consistent patterns (e.g., OpenNotionalCap field additions, method renamings), the diversity of affected domains, logic density in validation, and architectural changes (client refactoring) require separate reasoning for each coherent subsystem, pushing into the 4 (Complex) category.

Poem

🐰 Hoppy refactoring, markets now capped,
Positions offset, delegations unmapped!
New auction transfers, rate limits take flight,
Proto dreams realized, types shine so bright.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.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 pull request title "CP-651 update protos for v1.17.0 upgrade" is concise, clear, and directly related to the primary objective of the changeset. The raw summary confirms that the changes extensively update protobuf definitions across multiple modules (exchange, peggy, stream, permissions, tokenfactory) to align with the v1.17.0-beta and v1.17.0-beta.3 releases. The title includes a ticket reference (CP-651) for traceability and effectively communicates that this is a proto upgrade for a version release. While the title is somewhat broad and doesn't enumerate the specific new features (like MsgOffsetPosition or OpenNotionalCap), the instructions acknowledge that comprehensive detail is not required for a title, and this one sufficiently conveys the primary change for a teammate scanning the repository history.
✨ 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 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.

1 participant