Judging

Injective Peggy Bridge

Injective is a lightning fast interoperable layer one blockchain optimized for building premier Web3 finance applications. Injective provides developers with powerful plug-and-play modules for creating unmatched dApps.

  • Start date25 Feb 2026
  • End date17 Mar 2026
  • Total awards$105,500 in USDC
  • Duration20 days

Injective Peggy Bridge audit details

  • Total Prize Pool: $105,500 in USDC
    • HM awards: up to $96,000 in USDC
      • If no valid Highs or Mediums are found, the HM pool is $0
    • QA awards: $4,000 in USDC
    • Judge awards: $5,000 in USDC
    • Scout awards: $500 in USDC
  • Read our guidelines for more details
  • Starts February 25, 2026 20:00 UTC
  • Ends March 17, 2026 20:00 UTC

❗ Important notes for wardens

  1. Since this audit includes live/deployed code, all submissions will be treated as sensitive:
    • Wardens are encouraged to submit High-risk submissions affecting live code promptly, to ensure timely disclosure of such vulnerabilities to the sponsor and guarantee payout in the case where a sponsor patches a live critical during the audit.
    • Submissions will be hidden from all wardens (SR and non-SR alike) by default, to ensure that no sensitive issues are erroneously shared.
    • If the submissions include findings affecting live code, there will be no post-judging QA phase. This ensures that awards can be distributed in a timely fashion, without compromising the security of the project. (Senior members of C4 staff will review the judges’ decisions per usual.)
    • By default, submissions will not be made public until the report is published.
    • Exception: if the sponsor indicates that no submissions affect live code, then we’ll make submissions visible to all authenticated wardens, and open PJQA to verified wardens per the usual C4 process.
    • The "live criticals" exception therefore applies.
  2. Judging phase risk adjustments (upgrades/downgrades):
    • High- or Medium-risk submissions downgraded by the judge to Low-risk (QA) will be ineligible for awards.
    • Upgrading a Low-risk finding from a QA report to a Medium- or High-risk finding is not supported.
    • As such, wardens are encouraged to select the appropriate risk level carefully during the submission phase.

V12 findings

V12 is Zellic's in-house AI auditing tool. It is the only autonomous Solidity auditor that reliably finds Highs and Criticals. All issues found by V12 will be judged as out of scope and ineligible for awards.

V12 findings can be viewed here.

Publicly known issues

Anything included in this section is considered a publicly known issue and is therefore ineligible for awards.

Mint Limit Fund Loss

The peggy rate limit feature enforces a maximum absolute mint limit over which new deposits cannot make it into Injective from Ethereum and result in lost funds.

Permanent Fund Loss Due to Rate Limits

There is a bug in the Injective Peggy bridge's attestation processing logic. When a deposit claim fails validation by exceeding rate limits, the event nonce is permanently consumed and the attestation is marked as Observed but the tokens are never minted to the recipient. This leads to permanent fund freeze with no recovery method.

Rate Limit ID Update Bug

Price ID is not updated in rate-limit configuration (we're aware and a fix is under way)

Rate Limit Pre-Existing Mint Amounts

We are aware the creating a rate limit does not consider amounts of existing token deposits and a fix is already made.

Blacklist DoS

We are aware that blacklisted addresses can block withdrawals unless the blacklist is updated in the peggy module.

Blacklist / Non-Standard Token Behaviour (i.e. fee-on-transfer)

Blacklist validation is only performed during SendToEth submission. The BuildOutgoingTXBatch function does not revalidate blacklist status when creating batches from the transaction pool. The batch cannot be processed because the transfer might not succeed depending on the asset type (usdt, fee-on-transfer erc20 tokens)

Coingecko Dependency in Peggo

The Peggo Orchestrator relies exclusively on the CoinGecko API for USD price information, creating a single point of failure. Price-information queries are entirely dependent on the CoinGecko API, causing all withdrawal requests to enter a pending state when API failures occur.

Code Scope

Please ignore ResetPeggyModuleState from the audit as well as this was meant as a helper method for a testnet migration (never expected to be used in prod)

Overview

The peggy module enables the Injective Chain to support a trustless, on-chain bidirectional token bridge. In this system,
holders of ERC-20 tokens on the Ethereum chain can instantaneously convert their ERC-20 tokens to Cosmos-native coins on
the Injective Chain and vice-versa.

This bridge is fully governed by Injective Chain validators.

Peggo is a Go implementation of the Peggy Orchestrator for the Injective Chain.


Scope

Files in scope

FilenSLOC
peggo/orchestrator/batch_creator.go102
peggo/orchestrator/cosmos/client/context.go133
peggo/orchestrator/cosmos/codec/codec.go37
peggo/orchestrator/cosmos/keyring.go173
peggo/orchestrator/cosmos/network.go79
peggo/orchestrator/cosmos/peggy/broadcast.go295
peggo/orchestrator/cosmos/peggy/query.go227
peggo/orchestrator/cosmos/tendermint/client.go30
peggo/orchestrator/ethereum/committer/committer.go98
peggo/orchestrator/ethereum/committer/eth_committer.go169
peggo/orchestrator/ethereum/keystore/keycache.go123
peggo/orchestrator/ethereum/keystore/keystore.go156
peggo/orchestrator/ethereum/network.go254
peggo/orchestrator/ethereum/peggy/message_signatures.go113
peggo/orchestrator/ethereum/peggy/peggy_contract.go119
peggo/orchestrator/ethereum/peggy/pending_transactions.go91
peggo/orchestrator/ethereum/peggy/send_to_cosmos.go65
peggo/orchestrator/ethereum/peggy/submit_batch.go118
peggo/orchestrator/ethereum/peggy/utils.go75
peggo/orchestrator/ethereum/peggy/valset_update.go127
peggo/orchestrator/ethereum/provider/provider.go117
peggo/orchestrator/ethereum/util/contract.go91
peggo/orchestrator/ethereum/util/noncecache.go73
peggo/orchestrator/ethereum/util/peggy.go90
peggo/orchestrator/health_check.go96
peggo/orchestrator/loops/const_time_loop.go44
peggo/orchestrator/loops/paranoid_group.go59
peggo/orchestrator/oracle.go296
peggo/orchestrator/orchestrator.go104
peggo/orchestrator/pricefeed/coingecko.go144
peggo/orchestrator/relayer.go374
peggo/orchestrator/signer.go97
peggo/orchestrator/version/version.go29
injective-chain/modules/peggy/abci.go276
injective-chain/modules/peggy/client/cli/query.go211
injective-chain/modules/peggy/client/cli/tx.go369
injective-chain/modules/peggy/types/abi_json.go38
injective-chain/modules/peggy/types/batch.go45
injective-chain/modules/peggy/types/codec.go76
injective-chain/modules/peggy/types/errors.go23
injective-chain/modules/peggy/types/ethereum.go114
injective-chain/modules/peggy/types/ethereum_signer.go61
injective-chain/modules/peggy/types/events.go12
injective-chain/modules/peggy/types/expected_keepers.go49
injective-chain/modules/peggy/types/genesis.go13
injective-chain/modules/peggy/types/key.go149
injective-chain/modules/peggy/types/msgs.go465
injective-chain/modules/peggy/types/params.go297
injective-chain/modules/peggy/types/params_legacy.go58
injective-chain/modules/peggy/types/rate_limit.go112
injective-chain/modules/peggy/types/types.go173
injective-chain/modules/peggy/exported/exported.go11
injective-chain/modules/peggy/migrations/v2/migrate.go23
injective-chain/modules/peggy/module.go125
peggo/solidity/contracts/InjToken.sol22
peggo/solidity/contracts/Peggy.sol291
peggo/solidity/contracts/PeggySubgraph.sol27
injective-chain/modules/peggy/keeper/attestation.go378
injective-chain/modules/peggy/keeper/attestation_handler.go117
injective-chain/modules/peggy/keeper/batch.go259
injective-chain/modules/peggy/keeper/cosmos_originated.go128
injective-chain/modules/peggy/keeper/evidence.go107
injective-chain/modules/peggy/keeper/genesis.go167
injective-chain/modules/peggy/keeper/grpc_query.go357
injective-chain/modules/peggy/keeper/hooks.go78
injective-chain/modules/peggy/keeper/keeper.go669
injective-chain/modules/peggy/keeper/migrator.go24
injective-chain/modules/peggy/keeper/msg_server.go545
injective-chain/modules/peggy/keeper/pool.go383
injective-chain/modules/peggy/keeper/rate_limit.go182
Totals10819

For a machine-readable version, see scope.txt

Files out of scope

File
cli/flags/**.**
cli/**.**
client/docs/**.**
cmd/injectived/**.**
cmd/peggo/**.**
injective-chain/app/ante/**.**
injective-chain/app/**.**
injective-chain/client/**.**
injective-chain/codec/**.**
injective-chain/crypto/codec/**.**
injective-chain/crypto/ethsecp256k1/**.**
injective-chain/crypto/hd/**.**
injective-chain/crypto/keyring/**.**
injective-chain/crypto/ledger/driver/**.**
injective-chain/crypto/ledger/hub/**.**
injective-chain/hyperlane/core/01_interchain_security/**.**
injective-chain/hyperlane/core/02_post_dispatch/**.**
injective-chain/hyperlane/core/**.**
injective-chain/hyperlane/**.**
injective-chain/lanes/exchange/**.**
injective-chain/lanes/governance/**.**
injective-chain/lanes/helpers/**.**
injective-chain/lanes/oracle/**.**
injective-chain/lanes/**.**
injective-chain/modules/auction/**.**
injective-chain/modules/downtime-detector/**.**
injective-chain/modules/erc20/client/cli/**.**
injective-chain/modules/erc20/exported/**.**
injective-chain/modules/erc20/keeper/**.**
injective-chain/modules/erc20/module/**.**
injective-chain/modules/erc20/types/**.**
injective-chain/modules/evm/ante/**.**
injective-chain/modules/evm/client/cli/**.**
injective-chain/modules/evm/**.**
injective-chain/modules/exchange/**.**
injective-chain/modules/insurance/**.**
injective-chain/modules/oracle/**.**
injective-chain/modules/peggy/types/attestation.pb.go
injective-chain/modules/peggy/types/batch.pb.go
injective-chain/modules/peggy/types/ethereum_signer.pb.go
injective-chain/modules/peggy/types/events.pb.go
injective-chain/modules/peggy/types/genesis.pb.go
injective-chain/modules/peggy/types/msgs.pb.go
injective-chain/modules/peggy/types/msgs.pb.gw.go
injective-chain/modules/peggy/types/params.pb.go
injective-chain/modules/peggy/types/pool.pb.go
injective-chain/modules/peggy/types/query.pb.go
injective-chain/modules/peggy/types/query.pb.gw.go
injective-chain/modules/peggy/types/rate_limit.pb.go
injective-chain/modules/peggy/types/types.pb.go
injective-chain/modules/peggy/testpeggy/**.**
injective-chain/modules/permissions/client/cli/**.**
injective-chain/modules/permissions/contract-hook-example/evm/**.**
injective-chain/modules/permissions/contract-hook-example/src/**.**
injective-chain/modules/permissions/exported/**.**
injective-chain/modules/permissions/integration/utils/**.**
injective-chain/modules/permissions/keeper/**.**
injective-chain/modules/permissions/module/**.**
injective-chain/modules/permissions/types/**.**
injective-chain/modules/tokenfactory/client/cli/**.**
injective-chain/modules/tokenfactory/exported/**.**
injective-chain/modules/tokenfactory/keeper/**.**
injective-chain/modules/tokenfactory/migrations/v2/**.**
injective-chain/modules/tokenfactory/**.**
injective-chain/modules/txfees/**.**
injective-chain/modules/wasmx/**.**
injective-chain/server/indexer/**.**
injective-chain/server/**.**
injective-chain/stream/client/**.**
injective-chain/stream/server/**.**
injective-chain/stream/test/**.**
injective-chain/stream/types/**.**
injective-chain/types/**.**
injective-chain/version/**.**
injective-chain/wasmbinding/bindings/**.**
injective-chain/wasmbinding/**.**
injective-chain/websocket/**.**
interchaintest/circle/**.**
interchaintest/foundry/**.**
interchaintest/helpers/**.**
interchaintest/security/wasm-auth-evm-attack/src/**.**
interchaintest/security/wasm-evm-attack/src/**.**
interchaintest/**.**
peggo/migration/mainnet/**.**
peggo/solidity/contracts/HashingTest.sol
peggo/solidity/contracts/Peggy_Sepolia.sol
peggo/solidity/contracts/TestERC20.sol
peggo/solidity/wrappers/HashingTest.sol/**.**
peggo/solidity/wrappers/InjToken/**.**
peggo/solidity/wrappers/Peggy/**.**
peggo/solidity/wrappers/TestERC20.sol/**.**
peggo/test/peggo/**.**
scripts/**.**
version/**.**
Totals: 917

For a machine-readable version, see out_of_scope.txt

Additional context

Areas of concern (where to focus for bugs)

DoS Attacks

Any exploit resulting in a blocked pipeline (deposits, withdrawals), or any exploit resulting in a chain halt are of utmost importance.

Fund Loss

Any exploit resulting in fund drain is important provided that the fund loss that is achieved is of a non-negligible amount and not attribute-able to normal truncation of mathematical operations.

Main invariants

  • Only registered validators (orchestrators) can submit ETH claims to the Injective chain
  • Anyone can create an outgoing batch on Injective
  • Anyone can submit a batch/valset update to Injective

Trusted roles in the protocol

N/A

Unless otherwise noted in this README, trusted roles follow the centralization assumptions listed in the official C4 documentation here.

Running tests

Prerequisites

The codebase requires Golang to be installed alongside the jq command line toolkit for properly setting up a genesis configuration for the injectived node.

Additionally, the Solidity codebase relies on Python, the solc-select package it supports, NodeJS, and yarn to properly setup the contracts for compilation.

Versions utilized:

  • Go: 1.23.9
  • jq: 1.7
  • Python: 3.12
  • solc-select: N/A
  • NodeJS: 24.10.0
  • yarn: 1.22.22

Compilation

In order to compile the injectived node, the following instruction must be executed:

make install

This will automate most of the compilation steps required to compile the project.

Once compilation finishes, the setup script must be executed to generate the relevant genesis files for a node to run properly:

./setup.sh

Running Tests

Unit tests for the Golang scope of the codebase can be executed as follows:

go test -v ./injective-chain-modules/peggy/...

The Solidity portion of the codebase does not contain any tests.

E2E Tests

The End-to-End test suite has an additional dependency on Docker.

To execute e2e tests, the Docker image must be first created via the following command:

make image

Once the command has successfully built the Docker image, e2e tests can be executed through:

make ictest-peggo

Miscellaneous

Employees of Injective and employees' family members are ineligible to participate in this audit.

Code4rena's rules cannot be overridden by the contents of this README. In case of doubt, please check with C4 staff.