Conversation
…-beta and indexer v1.18.59. Added examples also for new vouchers functionality
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis PR updates Injective's chain modules with codec registrations for voucher claims, refactors authorization logic in the exchange module, adds new oracle functionality (Chainlink data streams and Pyth support), expands parameters and validation constraints, introduces client query support for auction and insurance vouchers, updates dependencies, and migrates ~200+ example files to environment-based configuration using godotenv. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 17
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
Makefile (1)
43-163:⚠️ Potential issue | 🟠 MajorRemove stale OCR artifacts during
copy-chain-types.Line 43 starts a full sync, but removed modules are not cleaned first. Since OCR copy steps were dropped, stale
chain/ocrfiles can persist and still be picked up byextract-message-names(downstream symptom: OCR message names remain in the generated JSON). This causes surface drift.Proposed fix
copy-chain-types: clone-injective-core + rm -rf chain/ocr cp -r injective-core/injective-chain/codec chain mkdir -p chain/crypto/codec && cp injective-core/injective-chain/crypto/codec/*.go chain/crypto/codec🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Makefile` around lines 43 - 163, The copy-chain-types Makefile target leaves stale chain/ocr files causing OCR artifacts to be picked up by extract-message-names; update the copy-chain-types recipe (the target named copy-chain-types and the subsequent make extract-message-names invocation) to remove any preexisting generated modules before copying—e.g., rm -rf chain/ocr (or a broader rm -rf chain/<removed-module>) or clean the whole chain tree—so that removed OCR files are deleted prior to copying proto and running make extract-message-names.chain/exchange/types/params.go (1)
328-352:⚠️ Potential issue | 🟠 MajorWire these stricter validators into the param set.
ParamSetPairs()still usesValidateFeeat Line 124 and Line 125, andParams.Validate()does the same at Line 193 and Line 196. That means a zero funding cap, a funding cap above 3%, and an interest rate above 1% still pass module-param validation, so the tighter rules here never actually take effect.🐛 Suggested wiring
- paramtypes.NewParamSetPair(KeyDefaultHourlyFundingRateCap, &p.DefaultHourlyFundingRateCap, ValidateFee), - paramtypes.NewParamSetPair(KeyDefaultHourlyInterestRate, &p.DefaultHourlyInterestRate, ValidateFee), + paramtypes.NewParamSetPair(KeyDefaultHourlyFundingRateCap, &p.DefaultHourlyFundingRateCap, ValidateHourlyFundingRateCap), + paramtypes.NewParamSetPair(KeyDefaultHourlyInterestRate, &p.DefaultHourlyInterestRate, ValidateHourlyInterestRate),- if err := ValidateFee(p.DefaultHourlyFundingRateCap); err != nil { + if err := ValidateHourlyFundingRateCap(p.DefaultHourlyFundingRateCap); err != nil { return fmt.Errorf("default_hourly_funding_rate_cap is incorrect: %w", err) } - if err := ValidateFee(p.DefaultHourlyInterestRate); err != nil { + if err := ValidateHourlyInterestRate(p.DefaultHourlyInterestRate); err != nil { return fmt.Errorf("default_hourly_interest_rate is incorrect: %w", err) }Also applies to: 354-374
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@chain/exchange/types/params.go` around lines 328 - 352, ParamSetPairs() and Params.Validate() are still wired to the old ValidateFee validator so the new stricter validators (e.g., ValidateHourlyFundingRateCap and the corresponding interest-rate validator around lines 354-374) are never applied; update the param wiring by replacing calls to ValidateFee in ParamSetPairs and Params.Validate with the new specific validators (ValidateHourlyFundingRateCap for the hourly funding cap parameter and the stricter interest-rate validator for the interest-rate parameter) so zero, >3% caps, and >1% interest values fail validation at module param load time.
🟡 Minor comments (4)
examples/chain/insurance/query/2_Voucher/example.go-64-69 (1)
64-69:⚠️ Potential issue | 🟡 MinorFail fast when query/marshal errors occur.
At Line 64 and Line 68, errors are logged but execution continues, which can produce misleading output (
null) and hide failures.✅ Suggested fix
res, err := chainClient.FetchInsuranceVoucher(ctx, denom, address) if err != nil { - fmt.Println(err) + fmt.Fprintln(os.Stderr, err) + os.Exit(1) } - str, _ := json.MarshalIndent(res, "", "\t") + str, err := json.MarshalIndent(res, "", "\t") + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } fmt.Print(string(str))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/insurance/query/2_Voucher/example.go` around lines 64 - 69, The code prints errors but continues, producing misleading output; change both error-handling points to fail fast: after the query result check where variable err is inspected (the block handling if err != nil) replace fmt.Println(err) with immediate termination (e.g., return the error from the function or call log.Fatalf with a clear message including err) and for json.MarshalIndent call capture its error (e.g., b, err := json.MarshalIndent(res, "", "\t")) and if err != nil fail immediately in the same way instead of ignoring the error, ensuring you reference the existing variables res and err so the function exits on real failures.examples/chain/insurance/query/1_Vouchers/example.go-64-69 (1)
64-69:⚠️ Potential issue | 🟡 MinorFail fast on query error and check marshal failures.
Continuing after a fetch error can output misleading
nullJSON and return success.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/insurance/query/1_Vouchers/example.go` around lines 64 - 69, The current snippet continues after a potential fetch error and ignores the marshal error; update the error handling so you fail fast when the fetch returned err (handle the existing if err != nil block by logging/returning/exiting instead of continuing) and check the result of json.MarshalIndent (capture its error, handle/log it and return/exit on failure) around the MarshalIndent call that produces str and err for res; ensure you don’t print or treat str when either the fetch err or the marshal err is non-nil.examples/chain/auction/query/1_Vouchers/example.go-64-69 (1)
64-69:⚠️ Potential issue | 🟡 MinorStop on fetch failure and handle marshal errors explicitly.
Current flow logs the error but still prints marshaled output, which can silently emit
nulland exit successfully.Suggested error handling fix
res, err := chainClient.FetchAuctionVouchers(ctx, denom) if err != nil { - fmt.Println(err) + fmt.Fprintln(os.Stderr, err) + os.Exit(1) } - str, _ := json.MarshalIndent(res, "", "\t") + str, err := json.MarshalIndent(res, "", "\t") + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } fmt.Print(string(str))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/auction/query/1_Vouchers/example.go` around lines 64 - 69, The code currently ignores a fetch error and proceeds to marshal and print res; change the block around the fetch error handling (the err check) to stop execution on failure (e.g., log the error and exit or return) so you do not operate on an invalid res, and then handle the json.MarshalIndent call explicitly by checking its returned error before printing (do not ignore the second return value); reference the existing err variable, res value, json.MarshalIndent, and fmt.Print/fmt.Println to locate and update those checks.examples/chain/auction/query/2_Voucher/example.go-63-69 (1)
63-69:⚠️ Potential issue | 🟡 MinorStop after a failed voucher query.
Right now a failed
FetchAuctionVoucherstill falls through toMarshalIndent, so the example can printnulland exit successfully even though the query failed. The marshal error is ignored too.🐛 Proposed fix
res, err := chainClient.FetchAuctionVoucher(ctx, denom, address) if err != nil { - fmt.Println(err) + panic(err) } -str, _ := json.MarshalIndent(res, "", "\t") +str, err := json.MarshalIndent(res, "", "\t") +if err != nil { + panic(err) +} fmt.Print(string(str))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/auction/query/2_Voucher/example.go` around lines 63 - 69, The example currently continues after a failed chainClient.FetchAuctionVoucher call and also ignores json.MarshalIndent errors; update the FetchAuctionVoucher error path to stop execution (e.g., print the error and return/exit) instead of falling through, and check the error from json.MarshalIndent before printing the result. Target the FetchAuctionVoucher call/err handling and the json.MarshalIndent(res, "", "\t") result/err handling to ensure you bail out on the fetch error and handle marshal errors properly.
🧹 Nitpick comments (8)
injective_data/ofac.json (1)
1-99: Consider enforcing address validation + dedupe in CI for this data file.Since this is compliance-sensitive data edited manually, a lightweight automated check for
^0x[0-9a-fA-F]{40}$and uniqueness would reduce future risk of malformed/duplicate entries.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@injective_data/ofac.json` around lines 1 - 99, Add a CI check that validates each entry in the JSON array (the list of 0x... addresses in ofac.json) matches the regex ^0x[0-9a-fA-F]{40}$ and that all entries are unique; implement this as a lightweight script (shell/node/python) run in the pipeline that reads the array, fails on any address that doesn't match the pattern or on any duplicates, and returns a non-zero exit code so PRs with malformed or duplicate addresses are rejected.proto/injective/permissions/v1beta1/params.proto (1)
36-45: Consider adding thedeprecatedfield option for tooling support.While the field is renamed with a
deprecated_prefix and documented, adding the proto3deprecatedoption would enable tooling and code generators to emit deprecation warnings.💡 Suggested improvement
// EVM addresses of contracts that will not bypass module-to-module transfers - repeated string deprecated_enforced_restrictions_contracts = 2; + repeated string deprecated_enforced_restrictions_contracts = 2 [deprecated = true];🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@proto/injective/permissions/v1beta1/params.proto` around lines 36 - 45, Add the proto3 deprecated option to the existing field definition for deprecated_enforced_restrictions_contracts in params.proto so tooling and generators emit deprecation warnings; locate the repeated string field named deprecated_enforced_restrictions_contracts (field number 2) and append the field option (deprecated=true) to its declaration (taking care to preserve any existing options/semantics), e.g., by updating the field's option list so the deprecated flag is set.examples/chain/auction/2_MsgClaimVoucher/example.go (1)
80-85: Handle marshal errors and remove redundant post-broadcast gas update.The marshal error is ignored, and Lines 83-85 have no effect in this one-shot example (no further tx).
Suggested cleanup
- str, _ := json.MarshalIndent(response, "", "\t") + str, err := json.MarshalIndent(response, "", "\t") + if err != nil { + panic(err) + } fmt.Print(string(str)) - - gasPrice = chainClient.CurrentChainGasPrice(ctx) - gasPrice = int64(float64(gasPrice) * 1.1) - chainClient.SetGasPrice(gasPrice)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/auction/2_MsgClaimVoucher/example.go` around lines 80 - 85, Handle the json.MarshalIndent error instead of ignoring it: check the returned error from json.MarshalIndent(response, "", "\t") and log or return it (referencing response and json.MarshalIndent) so failures are surfaced; then remove the redundant post-broadcast gas update (calls to chainClient.CurrentChainGasPrice, the gasPrice reassignment and chainClient.SetGasPrice) since this is a one-shot example and no further transactions occur (referencing gasPrice, chainClient.CurrentChainGasPrice, and chainClient.SetGasPrice).examples/chain/auction/query/1_Vouchers/example.go (1)
59-59: Use a bounded context for the RPC call.Using
context.Background()here can hang indefinitely on node/network issues; a short timeout makes the example more robust.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/auction/query/1_Vouchers/example.go` at line 59, Replace the unbounded context.Background() used for the RPC call with a bounded context using context.WithTimeout (e.g., ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)) and ensure you defer cancel() immediately; update the variable ctx used by the subsequent RPC invocation(s) in this file (the ctx declared on the line showing "ctx := context.Background()") so the call times out on network/node hangs and import time if not already imported.examples/chain/insurance/query/1_Vouchers/example.go (1)
59-59: Prefer a timeout-bound context for RPC queries.A bounded context makes this example safer under node/network stalls.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/chain/insurance/query/1_Vouchers/example.go` at line 59, Replace the unbounded context created by context.Background() (assigned to ctx) with a timeout-bound context via context.WithTimeout, capture the cancel function, assign the returned context back to ctx, and defer cancel() so RPC queries (e.g., anywhere using ctx in this example) are bounded (use a sensible timeout like 5–30s).proto/injective/oracle/v1beta1/oracle.proto (1)
17-19: Also reserve the deleted field name for JSON/TextFormat compatibility.The field number is protected by
reserved 3;, but reserving the field name prevents accidental reuse in JSON and TextFormat encodings. Per protobuf best practices, add the name to the reservation.🧩 Minimal diff
// Reserved field number 3: previously // accept_unverified_chainlink_data_streams_reports (bool). Do not reuse. reserved 3; +reserved "accept_unverified_chainlink_data_streams_reports";🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@proto/injective/oracle/v1beta1/oracle.proto` around lines 17 - 19, The reserved field number 3 is already protected but you must also reserve the deleted field name to avoid reuse in JSON/TextFormat; update the reservation for number 3 to also include the name "accept_unverified_chainlink_data_streams_reports" in the same reserved statement in proto/injective/oracle/v1beta1/oracle.proto so both the numeric slot and the field name are reserved for the deleted field.chain/oracle/types/pyth.go (1)
8-21: MakeNewPythPriceStateuse the samepublishTimetype as the model.
UpdateandPythPriceState.PublishTimealready useuint64; aligning the constructor keeps this helper consistent at the API boundary.♻️ Proposed change
func NewPythPriceState( priceID common.Hash, emaPrice, emaConf, conf math.LegacyDec, - publishTime int64, + publishTime uint64, price math.LegacyDec, blockTime int64, ) *PythPriceState { return &PythPriceState{ @@ - PublishTime: uint64(publishTime), + PublishTime: publishTime,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@chain/oracle/types/pyth.go` around lines 8 - 21, The constructor NewPythPriceState currently takes publishTime as int64 while PythPriceState.PublishTime and Update use uint64; change the NewPythPriceState signature to accept publishTime uint64 (instead of int64) and assign it directly to PublishTime without casting, updating any callers as needed; reference NewPythPriceState, PythPriceState.PublishTime, and Update to locate the types to keep the API boundary consistent.chain/exchange/types/params.go (1)
248-285: Consider a shared positive-coin validator.These three validators are identical aside from the field name in the error text, so the next rule change or message fix will need to land in three places.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@chain/exchange/types/params.go` around lines 248 - 285, The three validators ValidateSpotMarketInstantListingFee, ValidateDerivativeMarketInstantListingFee and ValidateBinaryOptionsMarketInstantListingFee duplicate the same sdk.Coin validation logic; extract a single reusable validator that performs the type assertion, IsValid and Amount.IsPositive checks and accepts a field name (or returns a closure) to produce the proper error message, then have each of the three functions delegate to that shared validator so the validation logic lives in one place and only the error label differs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@chain/exchange/types/common_utils.go`:
- Around line 45-48: The exported variable name ExchangeAuctionFeesAddress
replaces the previous public API AuctionFeesAddress and breaks downstream
imports; restore a deprecated alias by reintroducing the old exported variable
(AuctionFeesAddress) and set it to the same value as ExchangeAuctionFeesAddress
(derived from AuctionSubaccountID.Hex() via common.HexToAddress(...).Bytes()),
and add a short deprecation comment pointing users to
auctiontypes.AuctionFeesSubaccountAddress so both symbols
(ExchangeAuctionFeesAddress and AuctionFeesAddress) coexist.
In `@chain/exchange/types/params.go`:
- Line 44: MaxMarketLaunchDenomLength is set to 256 which exceeds Cosmos SDK
v0.50.14's denom max length of 128; change the constant
MaxMarketLaunchDenomLength from 256 to 128 to match SDK ValidateDenom
constraints, update any associated validation/tests that reference this constant
(e.g., functions that use MaxMarketLaunchDenomLength for input validation) and
run tests to ensure no other logic assumes the larger length.
In `@chain/exchange/types/v2/msgs.go`:
- Around line 612-623: The validators for market launch denoms (e.g., the
Spot/Perpetual/Binary/Expiry ValidateBasic methods in
chain/exchange/types/v2/msgs.go and the similar validators in proposal.go and v1
msgs.go) only check empty or too-long strings and must also reject invalid denom
formats; add a shared helper (e.g., validateMarketLaunchDenom) and call it from
each validator to: 1) check empty, 2) check length against
MaxMarketLaunchDenomLength, and 3) call sdk.ValidateDenom(denom) and wrap any
error with the provided invalidErr (like
ErrInvalidBaseDenom/ErrInvalidQuoteDenom) and a contextual message; replace the
duplicated checks in the Spot/Perpetual/Binary/Expiry validators and
corresponding proposal validators with calls to this helper to ensure consistent
denom validation across v1 and v2.
In `@chain/exchange/types/v2/position.go`:
- Around line 358-367: The helper currently only caps closingQuantity’s upper
bound and can accept negative values, which may expand p.Quantity; update the
logic around p.Quantity and closingQuantity in this function (referencing
p.Quantity, closingQuantity and the returned PositionDelta) to treat any
non-positive closingQuantity as a no-op: if closingQuantity is zero or negative
return the zero PositionDelta immediately (same shape as the existing
zero-return branch), otherwise clamp closingQuantity to
math.LegacyMinDec(p.Quantity, closingQuantity) before proceeding. Ensure you use
the Dec helpers (IsZero/IsNegative or equivalent) to detect non-positive values.
In `@chain/oracle/types/pyth.go`:
- Around line 46-49: The Validate method on PriceAttestation should verify the
raw PriceId hex string before using common.HexToHash: fetch the price ID string
(via p.GetPriceID or the field used to build GetPriceIDHash), strip a leading
"0x" with strings.TrimPrefix, ensure its length is exactly 64 characters, and
call hex.DecodeString to confirm it is valid hex; if any check fails return
ErrInvalidPythPriceID. Update PriceAttestation.Validate (and any helper that
calls common.HexToHash) to perform these checks and add imports for encoding/hex
and strings.
In `@chain/peggy/types/key.go`:
- Around line 120-124: Add deprecated aliases for the previous plural exported
names so downstream code doesn't break: create new variables (e.g.,
RateLimitsKey, MintAmountsERC20Key, RateLimitInflowsKey, RateLimitOutflowsKey,
RateLimitNetOutflowsKey) that are simple aliases to the existing RateLimitKey,
MintAmountERC20Key, RateLimitInflowKey, RateLimitOutflowKey,
RateLimitNetOutflowKey respectively, mark them with a deprecation comment, and
ensure they reference the same byte slice values so the byte prefixes remain
unchanged.
In `@chain/peggy/types/msgs.go`:
- Around line 556-563: The hash currently includes Members by relying on
fmt.Sprintf("%s", b.Members), which uses Go's non-canonical slice formatting;
change the code that computes the tmhash.Sum input so Members are canonicalized:
produce a deterministic string by first creating a slice of canonical member
encodings (e.g., for each *BridgeValidator use a stable representation like
address and power or any stable fields: fmt.Sprintf("%s:%d", m.Address,
m.Power)), sort that slice lexicographically to fix ordering, join with a
separator (e.g., ","), and then include that joined string in the fmt.Sprintf
that creates the byte input to tmhash.Sum (leave RewardAmount.String() as-is);
update references around Members and BridgeValidator so the hasher uses the
sorted, serialized members rather than fmt.Sprintf of the raw slice.
In `@client/chain/chain_v2.go`:
- Around line 290-296: You added four voucher query methods
(FetchAuctionVouchers, FetchAuctionVoucher, FetchInsuranceVouchers,
FetchInsuranceVoucher) directly to the public ChainClientV2 interface which is
source-breaking; instead extract these methods into a new extension interface
(e.g., ChainClientV2VoucherExt or VoucherQueryer) and leave ChainClientV2
unchanged, implement the new extension on the concrete chain client type(s) that
currently implement ChainClientV2, and update only call sites that need voucher
queries to accept the extension interface (or use type assertion) so existing
downstream implementations and mocks of ChainClientV2 remain compatible.
In `@examples/chain/auction/2_MsgClaimVoucher/example.go`:
- Around line 30-31: Replace the hard-coded secrets ("12345678" and
"f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3) in the
example (where the key/passphrase are provided) with reads from environment
variables (e.g., os.Getenv) and add a fail-fast check that returns an error or
logs and exits if those env vars are missing; update any code that assumes the
literal values (the array or variables holding the passphrase/private key) to
use the env-sourced values instead so no secrets are committed in example.go.
In `@examples/chain/auction/query/1_Vouchers/example.go`:
- Around line 28-31: The example currently hardcodes sensitive credentials
("12345678" and "f9db9bf330e23cb...") in the call that chooses between a raw
private key and a keyring fallback; remove these literals and read the
passphrase and private key from environment variables or prompt input instead
(e.g., use os.Getenv("AUCTION_PASSPHRASE") / os.Getenv("AUCTION_PRIVKEY") or a
secure prompt), validate they are present and return a clear error if not
provided, and keep the boolean argument (false) and the comment about keyring
fallback intact so the example still demonstrates using a keyring when the env
var is absent.
In `@examples/chain/insurance/1_MsgClaimVoucher/example.go`:
- Around line 25-32: The example currently embeds a raw private key and
passphrase in the InitCosmosKeyring call (affecting senderAddress,
cosmosKeyring); remove the hard-coded literal values and instead read the
passphrase and private key from environment variables (e.g., os.Getenv) or
change InitCosmosKeyring invocation to require an existing keyring entry only,
failing with a clear error if not present; update the call site to pass the
env-derived values and document that the example expects the key and/or
passphrase to be supplied via environment or pre-created keyring entry rather
than hard-coded.
- Around line 74-81: The example uses chainClient.BroadcastMsg with
txtypes.BroadcastMode_BROADCAST_MODE_SYNC which returns before the tx is
committed; replace that call with the helper that waits for commit (e.g., a
Broadcast-and-wait helper or using BROADCAST_MODE_BLOCK / a WaitForCommit helper
provided by the client) so the code only prints the result after the transaction
is included, and then remove the now-unused txtypes import; update the call
sites referencing BroadcastMsg and BroadcastMode_BROADCAST_MODE_SYNC to the
commit-waiting helper (or the BLOCK broadcast mode) and adjust error/response
handling accordingly.
In `@examples/chain/insurance/query/1_Vouchers/example.go`:
- Around line 28-31: The example embeds sensitive values ("12345678" and
"f9db9bf330e23cb...") directly; replace those hardcoded literals with
environment-driven inputs (e.g., read os.Getenv("VOUCHER_ID") and
os.Getenv("PRIVATE_KEY") or prompt the user at runtime) wherever those values
are passed (the example argument list supplying the ID and private key), add a
clear fallback/error when the env var is missing, and update the example
README/comments to instruct users to set these environment variables rather than
copy secrets into the source.
In `@examples/chain/insurance/query/2_Voucher/example.go`:
- Around line 22-29: The example hardcodes a private key string passed to
InitCosmosKeyring; remove the literal and instead load the key from a secure
source (e.g., use os.Getenv("INJECTIVE_PRIV_KEY") or pass an empty string so the
keyring fallback is used), update the call to chainclient.InitCosmosKeyring
accordingly, and adjust the inline comment to note that the key must be provided
via env/config rather than embedded in source; reference the InitCosmosKeyring
call and the senderAddress/cosmosKeyring variables when making the change.
In `@go.mod`:
- Line 38: Update the grpc dependency to a patched release: change the module
version for google.golang.org/grpc from v1.75.0 to v1.79.3 (or later) in go.mod
and then run the Go module update commands (e.g., go get
google.golang.org/grpc@v1.79.3 and go mod tidy) to ensure the new version is
resolved; verify no code-level API changes affect usages of grpc in the codebase
after the upgrade.
- Line 207: The go.mod currently pins go.opentelemetry.io/otel/sdk at v1.38.0
which is vulnerable; update the dependency line referencing
go.opentelemetry.io/otel/sdk (the v1.38.0 entry) to v1.40.0 or later, then run
the module update (e.g., go get or go mod tidy) to refresh go.sum so the project
uses the patched OpenTelemetry SDK and the GHSA-hfvc-g4fc-pqhx entry is no
longer applicable.
In `@proto/injective/permissions/v1beta1/query.proto`:
- Around line 91-100: The RPC HTTP annotations for Vouchers and Voucher replaced
the old parameterized REST paths and broke compatibility; update the rpc options
for rpc Vouchers (QueryVouchersRequest -> QueryVouchersResponse) and rpc Voucher
(QueryVoucherRequest -> QueryVoucherResponse) to include legacy
additional_bindings that preserve the previous routes (e.g. /vouchers/{denom}
for Vouchers and /voucher/{denom}/{address} for Voucher) so grpc-gateway clients
continue to work, keeping the new fixed path as the primary binding or
documenting an explicit breaking change if you intend to remove them.
---
Outside diff comments:
In `@chain/exchange/types/params.go`:
- Around line 328-352: ParamSetPairs() and Params.Validate() are still wired to
the old ValidateFee validator so the new stricter validators (e.g.,
ValidateHourlyFundingRateCap and the corresponding interest-rate validator
around lines 354-374) are never applied; update the param wiring by replacing
calls to ValidateFee in ParamSetPairs and Params.Validate with the new specific
validators (ValidateHourlyFundingRateCap for the hourly funding cap parameter
and the stricter interest-rate validator for the interest-rate parameter) so
zero, >3% caps, and >1% interest values fail validation at module param load
time.
In `@Makefile`:
- Around line 43-163: The copy-chain-types Makefile target leaves stale
chain/ocr files causing OCR artifacts to be picked up by extract-message-names;
update the copy-chain-types recipe (the target named copy-chain-types and the
subsequent make extract-message-names invocation) to remove any preexisting
generated modules before copying—e.g., rm -rf chain/ocr (or a broader rm -rf
chain/<removed-module>) or clean the whole chain tree—so that removed OCR files
are deleted prior to copying proto and running make extract-message-names.
---
Minor comments:
In `@examples/chain/auction/query/1_Vouchers/example.go`:
- Around line 64-69: The code currently ignores a fetch error and proceeds to
marshal and print res; change the block around the fetch error handling (the err
check) to stop execution on failure (e.g., log the error and exit or return) so
you do not operate on an invalid res, and then handle the json.MarshalIndent
call explicitly by checking its returned error before printing (do not ignore
the second return value); reference the existing err variable, res value,
json.MarshalIndent, and fmt.Print/fmt.Println to locate and update those checks.
In `@examples/chain/auction/query/2_Voucher/example.go`:
- Around line 63-69: The example currently continues after a failed
chainClient.FetchAuctionVoucher call and also ignores json.MarshalIndent errors;
update the FetchAuctionVoucher error path to stop execution (e.g., print the
error and return/exit) instead of falling through, and check the error from
json.MarshalIndent before printing the result. Target the FetchAuctionVoucher
call/err handling and the json.MarshalIndent(res, "", "\t") result/err handling
to ensure you bail out on the fetch error and handle marshal errors properly.
In `@examples/chain/insurance/query/1_Vouchers/example.go`:
- Around line 64-69: The current snippet continues after a potential fetch error
and ignores the marshal error; update the error handling so you fail fast when
the fetch returned err (handle the existing if err != nil block by
logging/returning/exiting instead of continuing) and check the result of
json.MarshalIndent (capture its error, handle/log it and return/exit on failure)
around the MarshalIndent call that produces str and err for res; ensure you
don’t print or treat str when either the fetch err or the marshal err is
non-nil.
In `@examples/chain/insurance/query/2_Voucher/example.go`:
- Around line 64-69: The code prints errors but continues, producing misleading
output; change both error-handling points to fail fast: after the query result
check where variable err is inspected (the block handling if err != nil) replace
fmt.Println(err) with immediate termination (e.g., return the error from the
function or call log.Fatalf with a clear message including err) and for
json.MarshalIndent call capture its error (e.g., b, err :=
json.MarshalIndent(res, "", "\t")) and if err != nil fail immediately in the
same way instead of ignoring the error, ensuring you reference the existing
variables res and err so the function exits on real failures.
---
Nitpick comments:
In `@chain/exchange/types/params.go`:
- Around line 248-285: The three validators ValidateSpotMarketInstantListingFee,
ValidateDerivativeMarketInstantListingFee and
ValidateBinaryOptionsMarketInstantListingFee duplicate the same sdk.Coin
validation logic; extract a single reusable validator that performs the type
assertion, IsValid and Amount.IsPositive checks and accepts a field name (or
returns a closure) to produce the proper error message, then have each of the
three functions delegate to that shared validator so the validation logic lives
in one place and only the error label differs.
In `@chain/oracle/types/pyth.go`:
- Around line 8-21: The constructor NewPythPriceState currently takes
publishTime as int64 while PythPriceState.PublishTime and Update use uint64;
change the NewPythPriceState signature to accept publishTime uint64 (instead of
int64) and assign it directly to PublishTime without casting, updating any
callers as needed; reference NewPythPriceState, PythPriceState.PublishTime, and
Update to locate the types to keep the API boundary consistent.
In `@examples/chain/auction/2_MsgClaimVoucher/example.go`:
- Around line 80-85: Handle the json.MarshalIndent error instead of ignoring it:
check the returned error from json.MarshalIndent(response, "", "\t") and log or
return it (referencing response and json.MarshalIndent) so failures are
surfaced; then remove the redundant post-broadcast gas update (calls to
chainClient.CurrentChainGasPrice, the gasPrice reassignment and
chainClient.SetGasPrice) since this is a one-shot example and no further
transactions occur (referencing gasPrice, chainClient.CurrentChainGasPrice, and
chainClient.SetGasPrice).
In `@examples/chain/auction/query/1_Vouchers/example.go`:
- Line 59: Replace the unbounded context.Background() used for the RPC call with
a bounded context using context.WithTimeout (e.g., ctx, cancel :=
context.WithTimeout(context.Background(), 10*time.Second)) and ensure you defer
cancel() immediately; update the variable ctx used by the subsequent RPC
invocation(s) in this file (the ctx declared on the line showing "ctx :=
context.Background()") so the call times out on network/node hangs and import
time if not already imported.
In `@examples/chain/insurance/query/1_Vouchers/example.go`:
- Line 59: Replace the unbounded context created by context.Background()
(assigned to ctx) with a timeout-bound context via context.WithTimeout, capture
the cancel function, assign the returned context back to ctx, and defer cancel()
so RPC queries (e.g., anywhere using ctx in this example) are bounded (use a
sensible timeout like 5–30s).
In `@injective_data/ofac.json`:
- Around line 1-99: Add a CI check that validates each entry in the JSON array
(the list of 0x... addresses in ofac.json) matches the regex ^0x[0-9a-fA-F]{40}$
and that all entries are unique; implement this as a lightweight script
(shell/node/python) run in the pipeline that reads the array, fails on any
address that doesn't match the pattern or on any duplicates, and returns a
non-zero exit code so PRs with malformed or duplicate addresses are rejected.
In `@proto/injective/oracle/v1beta1/oracle.proto`:
- Around line 17-19: The reserved field number 3 is already protected but you
must also reserve the deleted field name to avoid reuse in JSON/TextFormat;
update the reservation for number 3 to also include the name
"accept_unverified_chainlink_data_streams_reports" in the same reserved
statement in proto/injective/oracle/v1beta1/oracle.proto so both the numeric
slot and the field name are reserved for the deleted field.
In `@proto/injective/permissions/v1beta1/params.proto`:
- Around line 36-45: Add the proto3 deprecated option to the existing field
definition for deprecated_enforced_restrictions_contracts in params.proto so
tooling and generators emit deprecation warnings; locate the repeated string
field named deprecated_enforced_restrictions_contracts (field number 2) and
append the field option (deprecated=true) to its declaration (taking care to
preserve any existing options/semantics), e.g., by updating the field's option
list so the deprecated flag is set.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 852ce7c9-9b69-4894-bd94-1edbccb0a6ec
⛔ Files ignored due to path filters (32)
chain/auction/types/auction.pb.gois excluded by!**/*.pb.gochain/auction/types/genesis.pb.gois excluded by!**/*.pb.gochain/auction/types/query.pb.gois excluded by!**/*.pb.gochain/auction/types/tx.pb.gois excluded by!**/*.pb.gochain/common/vouchers/types/vouchers.pb.gois excluded by!**/*.pb.gochain/exchange/types/exchange.pb.gois excluded by!**/*.pb.gochain/exchange/types/v2/exchange.pb.gois excluded by!**/*.pb.gochain/insurance/types/events.pb.gois excluded by!**/*.pb.gochain/insurance/types/genesis.pb.gois excluded by!**/*.pb.gochain/insurance/types/insurance.pb.gois excluded by!**/*.pb.gochain/insurance/types/query.pb.gois excluded by!**/*.pb.gochain/insurance/types/tx.pb.gois excluded by!**/*.pb.gochain/oracle/types/events.pb.gois excluded by!**/*.pb.gochain/oracle/types/genesis.pb.gois excluded by!**/*.pb.gochain/oracle/types/oracle.pb.gois excluded by!**/*.pb.gochain/peggy/types/genesis.pb.gois excluded by!**/*.pb.gochain/peggy/types/msgs.pb.gois excluded by!**/*.pb.gochain/peggy/types/rate_limit.pb.gois excluded by!**/*.pb.gochain/permissions/types/events.pb.gois excluded by!**/*.pb.gochain/permissions/types/genesis.pb.gois excluded by!**/*.pb.gochain/permissions/types/params.pb.gois excluded by!**/*.pb.gochain/permissions/types/permissions.pb.gois excluded by!**/*.pb.gochain/permissions/types/query.pb.gois excluded by!**/*.pb.gochain/txfees/types/tx.pb.gois excluded by!**/*.pb.gochain/txfees/types/txfees.pb.gois excluded by!**/*.pb.gochain/wasmx/types/tx.pb.gois excluded by!**/*.pb.goexchange/accounts_rpc/pb/goadesign_goagen_injective_accounts_rpc.pb.gois excluded by!**/*.pb.goexchange/derivative_exchange_rpc/pb/goadesign_goagen_injective_derivative_exchange_rpc.pb.gois excluded by!**/*.pb.goexchange/event_provider_api/pb/goadesign_goagen_event_provider_api.pb.gois excluded by!**/*.pb.goexchange/explorer_rpc/pb/goadesign_goagen_injective_explorer_rpc.pb.gois excluded by!**/*.pb.goexchange/spot_exchange_rpc/pb/goadesign_goagen_injective_spot_exchange_rpc.pb.gois excluded by!**/*.pb.gogo.sumis excluded by!**/*.sum
📒 Files selected for processing (71)
Makefilechain/auction/types/codec.gochain/downtime-detector/types/keys.gochain/evm/types/errors.gochain/exchange/types/authz_common.gochain/exchange/types/common_utils.gochain/exchange/types/errors.gochain/exchange/types/key.gochain/exchange/types/msgs.gochain/exchange/types/params.gochain/exchange/types/proposal.gochain/exchange/types/v2/authz.gochain/exchange/types/v2/derivative.gochain/exchange/types/v2/derivative_orders.gochain/exchange/types/v2/fee_discounts.gochain/exchange/types/v2/msgs.gochain/exchange/types/v2/params.gochain/exchange/types/v2/position.gochain/exchange/types/v2/proposal.gochain/insurance/types/codec.gochain/oracle/types/chainlink_data_streams.gochain/oracle/types/codec.gochain/oracle/types/oracle.gochain/oracle/types/params.gochain/oracle/types/pyth.gochain/peggy/types/key.gochain/peggy/types/msgs.gochain/types/config.gochain/types/util.gochain/wasmx/types/params.goclient/chain/chain_test_support.goclient/chain/chain_v2.goexamples/chain/auction/2_MsgClaimVoucher/example.goexamples/chain/auction/query/1_Vouchers/example.goexamples/chain/auction/query/2_Voucher/example.goexamples/chain/insurance/1_MsgClaimVoucher/example.goexamples/chain/insurance/query/1_Vouchers/example.goexamples/chain/insurance/query/2_Voucher/example.gogo.modinjective_data/chain_messages_list.jsoninjective_data/ofac.jsonproto/injective/auction/v1beta1/auction.protoproto/injective/auction/v1beta1/genesis.protoproto/injective/auction/v1beta1/query.protoproto/injective/auction/v1beta1/tx.protoproto/injective/common/vouchers/v1/vouchers.protoproto/injective/exchange/v1beta1/exchange.protoproto/injective/exchange/v2/exchange.protoproto/injective/insurance/v1beta1/events.protoproto/injective/insurance/v1beta1/genesis.protoproto/injective/insurance/v1beta1/insurance.protoproto/injective/insurance/v1beta1/query.protoproto/injective/insurance/v1beta1/tx.protoproto/injective/ocr/v1beta1/genesis.protoproto/injective/ocr/v1beta1/ocr.protoproto/injective/ocr/v1beta1/query.protoproto/injective/ocr/v1beta1/tx.protoproto/injective/oracle/v1beta1/events.protoproto/injective/oracle/v1beta1/genesis.protoproto/injective/oracle/v1beta1/oracle.protoproto/injective/peggy/v1/genesis.protoproto/injective/peggy/v1/msgs.protoproto/injective/peggy/v1/rate_limit.protoproto/injective/permissions/v1beta1/events.protoproto/injective/permissions/v1beta1/genesis.protoproto/injective/permissions/v1beta1/params.protoproto/injective/permissions/v1beta1/permissions.protoproto/injective/permissions/v1beta1/query.protoproto/injective/txfees/v1beta1/tx.protoproto/injective/txfees/v1beta1/txfees.protoproto/injective/wasmx/v1/tx.proto
💤 Files with no reviewable changes (4)
- proto/injective/ocr/v1beta1/ocr.proto
- proto/injective/ocr/v1beta1/tx.proto
- proto/injective/ocr/v1beta1/query.proto
- proto/injective/ocr/v1beta1/genesis.proto
| // ExchangeAuctionFeesAddress is the bank address (inj1zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3t5qxqh) used for auction fees from the exchange module. | ||
| // Kept for backward compatibility with external senders (e.g. smart contracts) that already send funds here. | ||
| // New code should use auctiontypes.AuctionFeesSubaccountAddress. | ||
| var ExchangeAuctionFeesAddress = sdk.AccAddress(common.HexToAddress(AuctionSubaccountID.Hex()).Bytes()) |
There was a problem hiding this comment.
Keep a deprecated alias to avoid breaking public SDK API.
Line 48 introduces ExchangeAuctionFeesAddress, but removing the old exported variable name breaks downstream builds importing types.AuctionFeesAddress.
Proposed fix
var ExchangeAuctionFeesAddress = sdk.AccAddress(common.HexToAddress(AuctionSubaccountID.Hex()).Bytes())
+
+// Deprecated: use ExchangeAuctionFeesAddress or auctiontypes.AuctionFeesSubaccountAddress.
+var AuctionFeesAddress = ExchangeAuctionFeesAddress📝 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.
| // ExchangeAuctionFeesAddress is the bank address (inj1zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3t5qxqh) used for auction fees from the exchange module. | |
| // Kept for backward compatibility with external senders (e.g. smart contracts) that already send funds here. | |
| // New code should use auctiontypes.AuctionFeesSubaccountAddress. | |
| var ExchangeAuctionFeesAddress = sdk.AccAddress(common.HexToAddress(AuctionSubaccountID.Hex()).Bytes()) | |
| // ExchangeAuctionFeesAddress is the bank address (inj1zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3t5qxqh) used for auction fees from the exchange module. | |
| // Kept for backward compatibility with external senders (e.g. smart contracts) that already send funds here. | |
| // New code should use auctiontypes.AuctionFeesSubaccountAddress. | |
| var ExchangeAuctionFeesAddress = sdk.AccAddress(common.HexToAddress(AuctionSubaccountID.Hex()).Bytes()) | |
| // Deprecated: use ExchangeAuctionFeesAddress or auctiontypes.AuctionFeesSubaccountAddress. | |
| var AuctionFeesAddress = ExchangeAuctionFeesAddress |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@chain/exchange/types/common_utils.go` around lines 45 - 48, The exported
variable name ExchangeAuctionFeesAddress replaces the previous public API
AuctionFeesAddress and breaks downstream imports; restore a deprecated alias by
reintroducing the old exported variable (AuctionFeesAddress) and set it to the
same value as ExchangeAuctionFeesAddress (derived from AuctionSubaccountID.Hex()
via common.HexToAddress(...).Bytes()), and add a short deprecation comment
pointing users to auctiontypes.AuctionFeesSubaccountAddress so both symbols
(ExchangeAuctionFeesAddress and AuctionFeesAddress) coexist.
|
|
||
| MaxOracleProviderLength int = 256 | ||
|
|
||
| MaxMarketLaunchDenomLength int = 256 |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In Cosmos SDK v0.50.14, what length range does types.ValidateDenomaccept by default, and does Injective overrideSetCoinDenomRegexanywhere ininjective-core?
💡 Result:
In Cosmos SDK v0.50.14, types.ValidateDenom accepts denoms matching the regex [a-zA-Z][a-zA-Z0-9/:._-]{2,127}, which means a length range of 3 to 128 characters. No evidence found that Injective overrides SetCoinDenomRegex in injective-core; searches across Injective repositories show no such calls.
Citations:
- 1: https://github.com/cosmos/cosmos-sdk/blob/main/types/coin.go
- 2: https://docs.cosmos.network/v0.50/build/architecture/adr-004-split-denomination-keys
- 3: feat(x/bank): Replace regex parsing of denom validation to generated parsing cosmos/cosmos-sdk#19511
- 4: fix: fix ragel denom validation introduced in #19511 cosmos/cosmos-sdk#19701
- 5: [Feature]: Move away from Regexp parsing of denom validity / decimal amounts cosmos/cosmos-sdk#17221
🏁 Script executed:
# Check Cosmos SDK version in go.mod
fd -t f go.mod | head -5Repository: InjectiveLabs/sdk-go
Length of output: 70
🏁 Script executed:
# Find usages of MaxMarketLaunchDenomLength
rg "MaxMarketLaunchDenomLength" --type goRepository: InjectiveLabs/sdk-go
Length of output: 5060
🏁 Script executed:
# Get context from params.go around line 44
cat -n chain/exchange/types/params.go | head -80Repository: InjectiveLabs/sdk-go
Length of output: 3281
🏁 Script executed:
# Check if ValidateDenom or similar SDK validation is called on BaseDenom/QuoteDenom
rg "ValidateDenom|ValidateCoins|ValidateCoin" chain/exchange/types/ -A 2 -B 2Repository: InjectiveLabs/sdk-go
Length of output: 381
🏁 Script executed:
# Get Cosmos SDK version from go.mod
cat go.mod | grep cosmos-sdkRepository: InjectiveLabs/sdk-go
Length of output: 1111
MaxMarketLaunchDenomLength exceeds Cosmos SDK's denom length limit.
The constant is set to 256 characters, but Cosmos SDK v0.50.14's ValidateDenom enforces a maximum of 128 characters (regex [a-zA-Z][a-zA-Z0-9/:._-]{2,127}). This creates a validation inconsistency: local checks allow up to 256 characters while SDK validation enforces 128. Reduce MaxMarketLaunchDenomLength to 128 to align with SDK constraints.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@chain/exchange/types/params.go` at line 44, MaxMarketLaunchDenomLength is set
to 256 which exceeds Cosmos SDK v0.50.14's denom max length of 128; change the
constant MaxMarketLaunchDenomLength from 256 to 128 to match SDK ValidateDenom
constraints, update any associated validation/tests that reference this constant
(e.g., functions that use MaxMarketLaunchDenomLength for input validation) and
run tests to ensure no other logic assumes the larger length.
| if msg.BaseDenom == "" { | ||
| return errors.Wrap(types.ErrInvalidBaseDenom, "base denom should not be empty") | ||
| } | ||
| if len(msg.BaseDenom) > types.MaxMarketLaunchDenomLength { | ||
| return errors.Wrapf(types.ErrInvalidBaseDenom, "base denom should not exceed %d characters", types.MaxMarketLaunchDenomLength) | ||
| } | ||
| if msg.QuoteDenom == "" { | ||
| return errors.Wrap(types.ErrInvalidQuoteDenom, "quote denom should not be empty") | ||
| } | ||
| if len(msg.QuoteDenom) > types.MaxMarketLaunchDenomLength { | ||
| return errors.Wrapf(types.ErrInvalidQuoteDenom, "quote denom should not exceed %d characters", types.MaxMarketLaunchDenomLength) | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
rg -n -C2 'ValidateDenom|BaseDenom == ""|QuoteDenom == ""|MaxMarketLaunchDenomLength' \
chain/exchange/types/v2/msgs.go \
chain/exchange/types/v2/proposal.go \
chain/exchange/types/msgs.goRepository: InjectiveLabs/sdk-go
Length of output: 11157
🏁 Script executed:
#!/bin/bash
# Verify sdk is imported in v2/msgs.go
head -50 chain/exchange/types/v2/msgs.go | grep -E "import|sdk"
# Confirm the alternative locations mentioned
echo "=== Line ranges for other launch validators ==="
sed -n '677,682p' chain/exchange/types/v2/msgs.go
echo "---"
sed -n '791,796p' chain/exchange/types/v2/msgs.go
echo "---"
sed -n '844,849p' chain/exchange/types/v2/msgs.goRepository: InjectiveLabs/sdk-go
Length of output: 2646
Add full denom validation to launch message validators.
The denom checks in these validators only reject empty or overlong values. Arbitrary non-empty strings still pass ValidateBasic(), allowing bad market-denom inputs past the stateless boundary. Use sdk.ValidateDenom() here to reject invalid denom formats, and consolidate the pattern across all launch validators in both msgs.go and proposal.go using a shared helper to prevent drift.
The affected validators are:
chain/exchange/types/v2/msgs.go: Spot (612–623), Perpetual (677–682), Binary (791–796), Expiry (844–849)chain/exchange/types/v2/proposal.go: Similar validators with the same gapchain/exchange/types/msgs.go(v1): Same pattern across all launch validators
Suggested direction
func validateMarketLaunchDenom(denom string, invalidErr error, name string) error {
if denom == "" {
return errors.Wrap(invalidErr, name+" should not be empty")
}
if len(denom) > types.MaxMarketLaunchDenomLength {
return errors.Wrapf(invalidErr, "%s should not exceed %d characters", name, types.MaxMarketLaunchDenomLength)
}
if err := sdk.ValidateDenom(denom); err != nil {
return errors.Wrapf(invalidErr, "invalid %s %q: %v", name, denom, err)
}
return nil
}- if msg.BaseDenom == "" {
- return errors.Wrap(types.ErrInvalidBaseDenom, "base denom should not be empty")
- }
- if len(msg.BaseDenom) > types.MaxMarketLaunchDenomLength {
- return errors.Wrapf(types.ErrInvalidBaseDenom, "base denom should not exceed %d characters", types.MaxMarketLaunchDenomLength)
- }
- if msg.QuoteDenom == "" {
- return errors.Wrap(types.ErrInvalidQuoteDenom, "quote denom should not be empty")
- }
- if len(msg.QuoteDenom) > types.MaxMarketLaunchDenomLength {
- return errors.Wrapf(types.ErrInvalidQuoteDenom, "quote denom should not exceed %d characters", types.MaxMarketLaunchDenomLength)
- }
+ if err := validateMarketLaunchDenom(msg.BaseDenom, types.ErrInvalidBaseDenom, "base denom"); err != nil {
+ return err
+ }
+ if err := validateMarketLaunchDenom(msg.QuoteDenom, types.ErrInvalidQuoteDenom, "quote denom"); err != nil {
+ return err
+ }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@chain/exchange/types/v2/msgs.go` around lines 612 - 623, The validators for
market launch denoms (e.g., the Spot/Perpetual/Binary/Expiry ValidateBasic
methods in chain/exchange/types/v2/msgs.go and the similar validators in
proposal.go and v1 msgs.go) only check empty or too-long strings and must also
reject invalid denom formats; add a shared helper (e.g.,
validateMarketLaunchDenom) and call it from each validator to: 1) check empty,
2) check length against MaxMarketLaunchDenomLength, and 3) call
sdk.ValidateDenom(denom) and wrap any error with the provided invalidErr (like
ErrInvalidBaseDenom/ErrInvalidQuoteDenom) and a contextual message; replace the
duplicated checks in the Spot/Perpetual/Binary/Expiry validators and
corresponding proposal validators with calls to this helper to ensure consistent
denom validation across v1 and v2.
| if p.Quantity.IsZero() || closingQuantity.IsZero() { | ||
| return math.LegacyZeroDec(), &PositionDelta{ | ||
| IsLong: !p.IsLong, | ||
| ExecutionQuantity: math.LegacyZeroDec(), | ||
| ExecutionMargin: math.LegacyZeroDec(), | ||
| ExecutionPrice: closingPrice, | ||
| } | ||
| } | ||
|
|
||
| closingQuantity = math.LegacyMinDec(p.Quantity, closingQuantity) |
There was a problem hiding this comment.
Treat non-positive closingQuantity as a no-op.
Line 367 only caps the upper bound. If a caller passes a negative quantity, Line 377 increases p.Quantity, so this close helper can silently expand the position instead.
Also applies to: 377-377
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@chain/exchange/types/v2/position.go` around lines 358 - 367, The helper
currently only caps closingQuantity’s upper bound and can accept negative
values, which may expand p.Quantity; update the logic around p.Quantity and
closingQuantity in this function (referencing p.Quantity, closingQuantity and
the returned PositionDelta) to treat any non-positive closingQuantity as a
no-op: if closingQuantity is zero or negative return the zero PositionDelta
immediately (same shape as the existing zero-return branch), otherwise clamp
closingQuantity to math.LegacyMinDec(p.Quantity, closingQuantity) before
proceeding. Ensure you use the Dec helpers (IsZero/IsNegative or equivalent) to
detect non-positive values.
| func (p *PriceAttestation) Validate() error { | ||
| if len(p.GetPriceIDHash().Bytes()) != 32 { | ||
| return ErrInvalidPythPriceID | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python - <<'PY'
import re, urllib.request
url = "https://raw.githubusercontent.com/ethereum/go-ethereum/v1.15.7/common/types.go"
src = urllib.request.urlopen(url).read().decode()
for pattern in [
r'func BytesToHash\(.*?\n}\n',
r'func HexToHash\(.*?\n}\n',
r'func \(h \*Hash\) SetBytes\(.*?\n}\n',
]:
m = re.search(pattern, src, re.S)
if m:
print(m.group(0))
print()
PYRepository: InjectiveLabs/sdk-go
Length of output: 2645
🏁 Script executed:
# First, locate the target file
find . -name "pyth.go" -type fRepository: InjectiveLabs/sdk-go
Length of output: 92
🏁 Script executed:
# Check the structure and find the file in question
git ls-files | grep -i "oracle.*pyth" | head -20Repository: InjectiveLabs/sdk-go
Length of output: 90
🏁 Script executed:
cat -n chain/oracle/types/pyth.goRepository: InjectiveLabs/sdk-go
Length of output: 2225
🏁 Script executed:
# Check imports and error definitions
head -20 chain/oracle/types/pyth.go && echo "---" && grep -r "ErrInvalidPythPriceID" chain/oracle/types/Repository: InjectiveLabs/sdk-go
Length of output: 672
🏁 Script executed:
# Search for where PriceAttestation is created/used
rg "PriceAttestation" --type go | head -30Repository: InjectiveLabs/sdk-go
Length of output: 2802
🏁 Script executed:
# Check if there's validation on PriceId at creation point
rg "PriceId.*=" --type go chain/oracle/ | head -20Repository: InjectiveLabs/sdk-go
Length of output: 716
🏁 Script executed:
# Check where Validate() is called
rg "\.Validate\(\)" --type go chain/oracle/ -B 2 -A 2Repository: InjectiveLabs/sdk-go
Length of output: 265
🏁 Script executed:
# Check proto file to understand PriceAttestation definition
find . -name "*.proto" | xargs grep -l "PriceAttestation" | head -1 | xargs cat | grep -A 15 "message PriceAttestation"Repository: InjectiveLabs/sdk-go
Length of output: 432
🏁 Script executed:
# Look at existing imports in pyth.go to check if hex/strings are already imported
head -10 chain/oracle/types/pyth.goRepository: InjectiveLabs/sdk-go
Length of output: 240
Validate PriceId format before calling HexToHash.
common.HexToHash returns a fixed [32]byte Hash regardless of input length, so the current check len(...Bytes()) != 32 will always pass. This allows malformed or short price IDs to bypass validation.
Validate the raw hex string (after removing the "0x" prefix) as exactly 64 characters and decodable hex before conversion:
Proposed fix
func (p *PriceAttestation) Validate() error {
- if len(p.GetPriceIDHash().Bytes()) != 32 {
+ raw := strings.TrimPrefix(p.PriceId, "0x")
+ if len(raw) != 64 {
+ return ErrInvalidPythPriceID
+ }
+ if _, err := hex.DecodeString(raw); err != nil {
return ErrInvalidPythPriceID
}Add encoding/hex and strings to the import block.
📝 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.
| func (p *PriceAttestation) Validate() error { | |
| if len(p.GetPriceIDHash().Bytes()) != 32 { | |
| return ErrInvalidPythPriceID | |
| } | |
| func (p *PriceAttestation) Validate() error { | |
| raw := strings.TrimPrefix(p.PriceId, "0x") | |
| if len(raw) != 64 { | |
| return ErrInvalidPythPriceID | |
| } | |
| if _, err := hex.DecodeString(raw); err != nil { | |
| return ErrInvalidPythPriceID | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@chain/oracle/types/pyth.go` around lines 46 - 49, The Validate method on
PriceAttestation should verify the raw PriceId hex string before using
common.HexToHash: fetch the price ID string (via p.GetPriceID or the field used
to build GetPriceIDHash), strip a leading "0x" with strings.TrimPrefix, ensure
its length is exactly 64 characters, and call hex.DecodeString to confirm it is
valid hex; if any check fails return ErrInvalidPythPriceID. Update
PriceAttestation.Validate (and any helper that calls common.HexToHash) to
perform these checks and add imports for encoding/hex and strings.
| "12345678", | ||
| "f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3", // keyring will be used if pk not provided | ||
| false, | ||
| ) |
There was a problem hiding this comment.
Avoid embedding keyring secrets/private keys in examples.
Please move these values to environment variables (or prompts) to prevent insecure copy/paste usage.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@examples/chain/insurance/query/1_Vouchers/example.go` around lines 28 - 31,
The example embeds sensitive values ("12345678" and "f9db9bf330e23cb...")
directly; replace those hardcoded literals with environment-driven inputs (e.g.,
read os.Getenv("VOUCHER_ID") and os.Getenv("PRIVATE_KEY") or prompt the user at
runtime) wherever those values are passed (the example argument list supplying
the ID and private key), add a clear fallback/error when the env var is missing,
and update the example README/comments to instruct users to set these
environment variables rather than copy secrets into the source.
| google.golang.org/protobuf v1.36.6 | ||
| golang.org/x/crypto v0.41.0 | ||
| google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 | ||
| google.golang.org/grpc v1.75.0 |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
gRPC-Go GHSA-p77j-4mvh-x3m3 patched version
💡 Result:
The patched version for gRPC-Go vulnerability GHSA-p77j-4mvh-x3m3 is v1.79.3 and later. Affected versions are below 1.79.3. This fix was released on 2026-03-17 and addresses an authorization bypass via missing leading slash in the HTTP/2 :path pseudo-header. Subsequent releases like v1.80.0 (2026-04-01) also include the patch.
Citations:
Upgrade gRPC-Go from 1.75.0 due to critical authorization bypass vulnerability.
google.golang.org/grpc v1.75.0 contains a critical authorization bypass vulnerability (GHSA-p77j-4mvh-x3m3) via missing leading slash in the HTTP/2 :path pseudo-header. Upgrade to v1.79.3 or later to resolve this issue.
🧰 Tools
🪛 OSV Scanner (2.3.5)
[CRITICAL] 38-38: google.golang.org/grpc 1.75.0: Authorization bypass in gRPC-Go via missing leading slash in :path in google.golang.org/grpc
(GO-2026-4762)
[CRITICAL] 38-38: google.golang.org/grpc 1.75.0: gRPC-Go has an authorization bypass via missing leading slash in :path
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@go.mod` at line 38, Update the grpc dependency to a patched release: change
the module version for google.golang.org/grpc from v1.75.0 to v1.79.3 (or later)
in go.mod and then run the Go module update commands (e.g., go get
google.golang.org/grpc@v1.79.3 and go mod tidy) to ensure the new version is
resolved; verify no code-level API changes affect usages of grpc in the codebase
after the upgrade.
| go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect | ||
| go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect | ||
| go.opentelemetry.io/otel/metric v1.38.0 // indirect | ||
| go.opentelemetry.io/otel/sdk v1.38.0 // indirect |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
OpenTelemetry Go SDK GHSA-9h8m-3fm2-qjrq patched version
💡 Result:
The patched version for GHSA-9h8m-3fm2-qjrq in the OpenTelemetry Go SDK (specifically go.opentelemetry.io/otel/sdk/resource) is v1.40.0. This vulnerability affects versions >=1.21.0 and <=1.39.0. The patch was included in commit d45961b, released on 2026-02-02 as part of v1.40.0. Note that a related follow-up vulnerability (GHSA-hfvc-g4fc-pqhx) was found in v1.40.0 to v1.42.0 on BSD systems, patched in v1.43.0 (2026-04-02). For full protection against the original issue and related problems, upgrade to at least v1.43.0.
Citations:
- 1: GHSA-9h8m-3fm2-qjrq
- 2: https://osv.dev/vulnerability/GHSA-9h8m-3fm2-qjrq
- 3: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.40.0
- 4: https://github.com/open-telemetry/opentelemetry-go/releases
🌐 Web query:
GO-2026-4394 OpenTelemetry vulnerability
💡 Result:
GO-2026-4394 is a high-severity vulnerability (CVSS 3.1: 7.0, AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H) in the OpenTelemetry Go SDK, specifically in go.opentelemetry.io/otel/sdk module versions >=1.21.0 and <1.40.0 (also reported as v1.20.0-1.39.0 in some sources). It allows arbitrary code execution via PATH hijacking on macOS/Darwin systems. The issue occurs in sdk/resource/host_id.go during resource detection, where the ioreg system command is executed without a secure PATH, enabling a local attacker with limited privileges who can modify the PATH environment variable to execute malicious code in the application's context (CWE-426: Untrusted Search Path). It is also tracked as CVE-2026-24051 and GHSA-9h8m-3fm2-qjrq. Patched in v1.40.0 via commit d45961bcda453fcbdb6469c22d6e88a1f9970a53, which uses an absolute path for ioreg on macOS. No known exploits. Multiple projects (Helm, etcd, Opentofu, OpenBao) have updated dependencies in response. Official sources: Go Vulnerability Database (pkg.go.dev/vuln/GO-2026-4394, published Feb 19, 2026), GitHub Advisory (GHSA-9h8m-3fm2-qjrq), OSV.dev, NVD (CVE-2026-24051).
Citations:
- 1: https://www.resolvedsecurity.com/vulnerability-catalog/GO-2026-4394
- 2: https://pkg.go.dev/vuln/GO-2026-4394
- 3: https://osv.dev/vulnerability/GO-2026-4394
- 4: https://cve.circl.lu/vuln/ghsa-9h8m-3fm2-qjrq
- 5: https://vulert.com/vuln-db/opentelemetry-go-sdk-vulnerable-to-arbitrary-code-execution-via-path-hijacking-in-go-opentelemetry-i-
- 6: https://scout.docker.com/vulnerabilities/id/CVE-2026-24051?n=sdk&ns=go.opentelemetry.io%2Fotel&s=github&t=golang&vr=%3E%3D1.21.0%2C%3C1.40.0
- 7: https://nvd.nist.gov/vuln/detail/cve-2026-24051
- 8: https://github.com/advisories/GHSA-9h8m-3fm2-qjrq/dependabot
🌐 Web query:
GHSA-9h8m-3fm2-qjrq PATH hijacking CVE details
💡 Result:
GHSA-9h8m-3fm2-qjrq is a high-severity vulnerability (CVSS 3.1: 7.0, AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H) in the OpenTelemetry Go SDK package go.opentelemetry.io/otel/sdk/resource. It enables arbitrary code execution via local PATH hijacking on macOS/Darwin systems. Affected versions: >=1.21.0 to <=1.39.0 (noted as v1.20.0-1.39.0 in some sources). Patched in: v1.40.0 via commit d45961bcda453fcbdb6469c22d6e88a1f9970a53. Description: The resource detection code in sdk/resource/host_id.go executes the 'ioreg' system command without a secure PATH, allowing an attacker who can modify the PATH environment variable to hijack the command and execute arbitrary code in the application's context. CVE ID: CVE-2026-24051. Weakness: CWE-426 (Untrusted Search Path). Published: February 2, 2026.
Citations:
- 1: GHSA-9h8m-3fm2-qjrq
- 2: https://cve.circl.lu/vuln/ghsa-9h8m-3fm2-qjrq
- 3: GHSA-9h8m-3fm2-qjrq
- 4: https://osv.dev/vulnerability/GHSA-9h8m-3fm2-qjrq
- 5: https://nvd.nist.gov/vuln/detail/CVE-2026-24051
🏁 Script executed:
# Search for any references to these vulnerabilities in the codebase
rg "GO-2026-4394|GHSA-9h8m-3fm2-qjrq|GHSA-hfvc-g4fc-pqhx" . -i 2>/dev/null || echo "No matches found"Repository: InjectiveLabs/sdk-go
Length of output: 80
Remove GHSA-hfvc-g4fc-pqhx from the vulnerability list; it does not affect v1.38.0.
v1.38.0 contains a critical PATH hijacking vulnerability (GO-2026-4394/GHSA-9h8m-3fm2-qjrq, CVSS 7.0) in the OpenTelemetry SDK's resource detection that allows arbitrary code execution on macOS/Darwin systems. This vulnerability affects all versions >=1.21.0 and <1.40.0.
Upgrade to v1.40.0 or later to resolve this issue.
🧰 Tools
🪛 OSV Scanner (2.3.5)
[HIGH] 207-207: go.opentelemetry.io/otel/sdk 1.38.0: OpenTelemetry Go SDK Vulnerable to Arbitrary Code Execution via PATH Hijacking in go.opentelemetry.io/otel/sdk
(GO-2026-4394)
[HIGH] 207-207: go.opentelemetry.io/otel/sdk 1.38.0: OpenTelemetry Go SDK Vulnerable to Arbitrary Code Execution via PATH Hijacking
[HIGH] 207-207: go.opentelemetry.io/otel/sdk 1.38.0: opentelemetry-go: BSD kenv command not using absolute path enables PATH hijacking
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@go.mod` at line 207, The go.mod currently pins go.opentelemetry.io/otel/sdk
at v1.38.0 which is vulnerable; update the dependency line referencing
go.opentelemetry.io/otel/sdk (the v1.38.0 entry) to v1.40.0 or later, then run
the module update (e.g., go get or go mod tidy) to refresh go.sum so the project
uses the patched OpenTelemetry SDK and the GHSA-hfvc-g4fc-pqhx entry is no
longer applicable.
| // Vouchers defines a gRPC query method for the vouchers for a given denom | ||
| rpc Vouchers(QueryVouchersRequest) returns (QueryVouchersResponse) { | ||
| option (google.api.http).get = | ||
| "/injective/permissions/v1beta1/vouchers/{denom}"; | ||
| option (google.api.http).get = "/injective/permissions/v1beta1/vouchers"; | ||
| } | ||
|
|
||
| // Voucher defines a gRPC query method for the vouchers for a given denom and | ||
| // address | ||
| rpc Voucher(QueryVoucherRequest) returns (QueryVoucherResponse) { | ||
| option (google.api.http).get = | ||
| "/injective/permissions/v1beta1/voucher/{denom}/{address}"; | ||
| option (google.api.http).get = "/injective/permissions/v1beta1/voucher"; | ||
| } |
There was a problem hiding this comment.
Preserve the old REST bindings for compatibility.
Switching these annotations from /vouchers/{denom} and /voucher/{denom}/{address} to fixed paths breaks existing grpc-gateway / REST clients. Add legacy additional_bindings or ship this as an explicit breaking API change.
🛠️ Suggested compatibility patch
rpc Vouchers(QueryVouchersRequest) returns (QueryVouchersResponse) {
- option (google.api.http).get = "/injective/permissions/v1beta1/vouchers";
+ option (google.api.http) = {
+ get: "/injective/permissions/v1beta1/vouchers"
+ additional_bindings {
+ get: "/injective/permissions/v1beta1/vouchers/{denom}"
+ }
+ };
}
@@
rpc Voucher(QueryVoucherRequest) returns (QueryVoucherResponse) {
- option (google.api.http).get = "/injective/permissions/v1beta1/voucher";
+ option (google.api.http) = {
+ get: "/injective/permissions/v1beta1/voucher"
+ additional_bindings {
+ get: "/injective/permissions/v1beta1/voucher/{denom}/{address}"
+ }
+ };
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@proto/injective/permissions/v1beta1/query.proto` around lines 91 - 100, The
RPC HTTP annotations for Vouchers and Voucher replaced the old parameterized
REST paths and broke compatibility; update the rpc options for rpc Vouchers
(QueryVouchersRequest -> QueryVouchersResponse) and rpc Voucher
(QueryVoucherRequest -> QueryVoucherResponse) to include legacy
additional_bindings that preserve the previous routes (e.g. /vouchers/{denom}
for Vouchers and /voucher/{denom}/{address} for Voucher) so grpc-gateway clients
continue to work, keeping the new fixed path as the primary binding or
documenting an explicit breaking change if you intend to remove them.
Replace hardcoded hex keys in InitCosmosKeyring call sites with
os.Getenv("INJECTIVE_PRIVATE_KEY"), call godotenv.Load() at startup, and
document variables in .env.example. Ignore .env in git.
Updated all proto definitions to match injective-core v1.19.0-beta and indexer v1.18.59. Added examples also for new vouchers functionality
Solves IC-986
Summary by CodeRabbit
New Features
Refactoring
Chores