# Table of Contents - [Definitions - Injective Docs](#definitions-injective-docs) - [Workflow - Injective Docs](#workflow-injective-docs) - [State - Injective Docs](#state-injective-docs) - [End-Block - Injective Docs](#end-block-injective-docs) - [Messages - Injective Docs](#messages-injective-docs) - [Parameters - Injective Docs](#parameters-injective-docs) - [Slashing - Injective Docs](#slashing-injective-docs) - [Events - Injective Docs](#events-injective-docs) - [Relay Semantics - Injective Docs](#relay-semantics-injective-docs) - [Future Improvements - Injective Docs](#future-improvements-injective-docs) - [Error Codes - Injective Docs](#error-codes-injective-docs) - [Peggy - Injective Docs](#peggy-injective-docs) - [Peggy - Injective Docs](#peggy-injective-docs) --- # Definitions - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy/01_definitions#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... ⌘KAsk AI Search... Navigation Peggy Definitions On this page * [Intro](https://docs.injective.network/developers-native/injective/peggy/01_definitions#intro) * [Key definitions](https://docs.injective.network/developers-native/injective/peggy/01_definitions#key-definitions) [​](https://docs.injective.network/developers-native/injective/peggy/01_definitions#intro) Intro =================================================================================================== This doc aims to provide an overview of `Peggy` (Injective’s Ethereum bridge) from a technical perspective and dive deep into its operational logic. Peggy is the name of the custom Cosmos SDK module built on Injective as well as the Ethereum contract (Peggy.sol) which make up both sides of the bridge. Connected via a middle-man process called `Peggo` users can securely move token assets between networks. To suggest improvements, please open a GitHub issue. ### [​](https://docs.injective.network/developers-native/injective/peggy/01_definitions#key-definitions) Key definitions Words matter and we seek clarity in the terminology so we can have clarity in our thinking and communication. To help better understand, some key definitions are: * `Operator` - this is a person (or people) who control and operate `Validator` and `Orchestrator` processes * `Validator` - this is an Injective Chain validating node (eg. `injectived` process) * `Validator Set` - the (active) set of Injective Chain `Validators` (Valset) along with their respective voting power as determined by their stake weight. Each validator is associated with an Ethereum address to be represented on the Ethereum network * `Orchestrator (Peggo)` - the off-chain process (`peggo`) that plays the middleman role between Injective and Ethereum. Orchestrators are responsible for keeping the bridge online and require active endpoints to fully synced Injective (Ethereum) nodes * `Peggy module` - the counterparty Cosmos module for `Peggy contract`. Besides providing services to bridge token assets, it automatically reflects on the active `Validator Set` as it changes over time. The update is later applied on Ethereum via `Peggo` * `Peggy Contract` - The Ethereum contract that holds all the ERC-20 tokens. It also maintains a compressed checkpointed representation of the Injective Chain `Validator Set` using `Delegate Keys` and normalized powers * `Delegate Keys` - when an `Operator` sets up their `Orchestrator` for the first time they register (on Injective) their `Validator`’s address with an Ethereum address. The corresponding key is used to sign messages and represent that validator on Ethereum. Optionally, one delegate Injective Chain account key can be provided to sign Injective messages (eg `Claims`) on behalf of the `Validator` * `Peggy Tx pool (withdrawals)` - when a user wishes to move their asset from Injective to Ethereum their individual tx gets pooled with others with the same asset * `Peggy Batch pool` - pooled withdrawals are batched together (by an `Orchestrator`) to be signed off and eventually relayed to Ethereum. These batches are kept within this pool * `Claim` - a signed proof (by an `Orchestrator`) that an event occurred in the `Peggy contract` * `Attestation` - an aggregate of claims for a particular event nonce emitted from `Peggy contract`. After a majority of `Orchestrators` attests to a claim, the event is acknowledged and executed on Injective * `Majority` - the majority of Injective network, 2/3 + 1 validators * `Deposit` - an asset transfer initiated from Ethereum to Injective * `Withdrawal` - an asset transfer initiated from Injective to Ethereum (present in `Peggy Tx pool`) * `Batch` - a batch of withdrawals with the same token type (present in `Peggy Batch pool`) [Peggy](https://docs.injective.network/developers-native/injective/peggy) [Workflow](https://docs.injective.network/developers-native/injective/peggy/02_workflow) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # Workflow - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy/02_workflow#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... ⌘KAsk AI Search... Navigation Peggy Workflow On this page * [Workflow](https://docs.injective.network/developers-native/injective/peggy/02_workflow#workflow) * [Conceptual Overview](https://docs.injective.network/developers-native/injective/peggy/02_workflow#conceptual-overview) * [Types of Assets](https://docs.injective.network/developers-native/injective/peggy/02_workflow#types-of-assets) * [Native Ethereum assets](https://docs.injective.network/developers-native/injective/peggy/02_workflow#native-ethereum-assets) * [Native Cosmos SDK assets](https://docs.injective.network/developers-native/injective/peggy/02_workflow#native-cosmos-sdk-assets) * [Orchestrator (Peggo) subprocesses](https://docs.injective.network/developers-native/injective/peggy/02_workflow#orchestrator-peggo-subprocesses) * [Batch Creator](https://docs.injective.network/developers-native/injective/peggy/02_workflow#batch-creator) * [Signer](https://docs.injective.network/developers-native/injective/peggy/02_workflow#signer) * [Oracle](https://docs.injective.network/developers-native/injective/peggy/02_workflow#oracle) * [Relayer](https://docs.injective.network/developers-native/injective/peggy/02_workflow#relayer) * [End-to-end Lifecycle](https://docs.injective.network/developers-native/injective/peggy/02_workflow#end-to-end-lifecycle) * [Peggy Smart Contract Deployment](https://docs.injective.network/developers-native/injective/peggy/02_workflow#peggy-smart-contract-deployment) * [Updating Injective Chain validator set on Ethereum](https://docs.injective.network/developers-native/injective/peggy/02_workflow#updating-injective-chain-validator-set-on-ethereum) * [Transferring ERC-20 tokens from Ethereum to Injective](https://docs.injective.network/developers-native/injective/peggy/02_workflow#transferring-erc-20-tokens-from-ethereum-to-injective) * [Withdrawing tokens from Injective to Ethereum](https://docs.injective.network/developers-native/injective/peggy/02_workflow#withdrawing-tokens-from-injective-to-ethereum) [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#workflow) Workflow ====================================================================================================== [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#conceptual-overview) Conceptual Overview ---------------------------------------------------------------------------------------------------------------------------- To recap, each `Operator` is responsible for maintaining 2 secure processes: 1. A fully synced Injective Chain `Validator` node (`injectived` process) 2. The `Orchestrator` service (`peggo orchestrator` process) which interacts with both networks. Implicitly, an RPC endpoint to a fully synced Ethereum node is required as well (see peggo .env example) Combined, these 2 entities accomplish 3 things: * Move token assets from Ethereum to Injective * Move token assets from Injective to Ethereum * Keep the `Peggy.sol` contract in sync with the active `Validator Set` on Injective It is possible to run `peggo` without ever being a `Validator`. Peggo automatically runs in “relayer mode” when configured to run with an address **not associated** with a `Validator`. In this mode, only 2 things can happen: * new token batches can be created on Injective * confirmed valsets/batches can be relayed to Ethereum [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#types-of-assets) Types of Assets -------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#native-ethereum-assets) Native Ethereum assets Any asset originating from Ethereum which implements the ERC-20 standard can be transferred from Ethereum to Injective by calling the `sendToInjective` function on the [Peggy.sol](https://github.com/InjectiveLabs/peggo/blob/master/solidity/contracts/Peggy.sol) contract which transfers tokens from the sender’s balance to the Peggy contract. The `Operators` all run their `peggo` processes which submit `MsgDepositClaim` messages describing the deposit they have observed. Once more than 66% of all voting power has submitted a claim for this specific deposit representative tokens are minted and issued to the Injective Chain address that the sender requested. These representative tokens have a denomination prefix of `peggy` concatenated with the ERC-20 token hex address, e.g. `peggy0xdac17f958d2ee523a2206206994597c13d831ec7`. ### [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#native-cosmos-sdk-assets) Native Cosmos SDK assets An asset native to a Cosmos SDK chain (e.g. `ATOM`) first must be represented on Ethereum before it’s possible to bridge it. To do so, the [Peggy contract](https://github.com/InjectiveLabs/peggo/blob/master/solidity/contracts/Peggy.sol) allows anyone to create a new ERC-20 token representing a Cosmos asset by calling the `deployERC20` function. This endpoint is not permissioned, so it is up to the validators and the users of the Peggy bridge to declare any given ERC-20 token as the representation of a given asset. When a user on Ethereum calls `deployERC20` they pass arguments describing the desired asset. [Peggy.sol](https://github.com/InjectiveLabs/peggo/blob/master/solidity/contracts/Peggy.sol) uses an ERC-20 factory to deploy the actual ERC-20 contract and assigns ownership of the entire balance of the new token to the Peggy contract itself before emitting an `ERC20DeployedEvent`. The peggo orchestrators observe this event and decide if a Cosmos asset has been accurately represented (correct decimals, correct name, no pre-existing representation). If this is the case, the ERC-20 contract address is adopted and stored as the definitive representation of that Cosmos asset on Ethereum. [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#orchestrator-peggo-subprocesses) `Orchestrator` (Peggo) subprocesses -------------------------------------------------------------------------------------------------------------------------------------------------------- The `peggo orchestrator` process consists of 4 subprocesses running concurrently at exact intervals (loops). These are: * `Signer` which signs new `Validator Set` updates and `Token Batches` with the `Operator`’s Ethereum keys and submits using [messages](https://docs.injective.network/developers-native/injective/peggy/04_messages.md#Ethereum-Signer-messages) . * `Oracle` which observes Ethereum events and sends them as [claims](https://docs.injective.network/developers-native/injective/peggy/04_messages.md#Oracle-messages) to Injective. * `Relayer` which submits confirmed `Validator Set` updates and `Token Batches` to the `Peggy Contract` on Ethereum * `Batch Creator` which observes (new) withdrawals on Injective and decides which of these to batch according to their type and the configured `PEGGO_MIN_BATCH_FEE_USD` value ### [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#batch-creator) Batch Creator The purpose of the `Batch Creator` is only in creating token batches on the Injective side. The relevant `Peggy module` RPC is not permissioned so anyone can create a batch. When a user wants to withdraw assets from Injective to Ethereum they send a special message to Injective (`MsgSendToEth`) which adds their withdrawal to `Peggy Tx Pool`. `Batch Creator` continually queries the pool for withdrawals (by token type) and issues a `MsgRequestBatch` to Injective when a potential batch satisfies the configured `PEGGO_MIN_BATCH_FEE_USD` value (see .env example). On the receiving end, all pooled withdrawals matching the token type in the request are moved from the `Outgoing Tx Pool` as a single batch and placed in the `Outgoing Batch Pool`. ### [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#signer) Signer The responsibility of Signer is to provide confirmations that an `Operator (Orchestrator)` is partaking in bridge activity. Failure to provide these confirmations results in slashing penalties for the orchestrator’s `Validator`. In other words, this process **must be running at all times** for a `Validator` node. Any payload moving in the Injective->Ethereum pipeline (`Validator Set` updates/`Token Batches`) requires `Validator` signatures to be successfully relayed to Ethereum. Certain calls on `Peggy Contract` accept an array of signatures to be checked against the `Validator Set` in the contract itself. `Orchestrators` make these signatures with their `Delegate Ethereum address`: this is an Ethereum address decided by the `Operator` upon initial setup ([SetOrchestratorAddress](https://docs.injective.network/developers-native/injective/peggy/04_messages.md#setorchestratoraddresses) ). This address then represents that validator on the Ethereum blockchain and will be added as a signing member of the multisig with a weighted voting power as close as possible to the Injective Chain voting power. Whenever `Signer` finds that there is a unconfirmed valset update (token batch) present within the `Peggy Module` it issues a `MsgConfirmValset` (`MsgConfirmBatch`) as proof that the operating `Validator` is active in bridge activity. ### [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#oracle) Oracle Monitors the Ethereum network for new events involving the `Peggy Contract`. Every event emitted by the contract has a unique event nonce. This nonce value is crucial in coordinating `Orchestrators` to properly observe contract activity and make sure Injective acknowledges them via `Claims`. Multiple claims of the same nonce make up an `Attestation` and when the majority (2/3) of orchestrators have observed an event its particular logic gets executed on Injective. If 2/3 of the validators can not agree on a single `Attestation`, the oracle is halted. This means no new events will be relayed from Ethereum until some of the validators change their votes. There is no slashing condition for this, with reasoning outlined in the [slashing spec](https://docs.injective.network/developers-native/injective/peggy/05_slashing) There are 4 types of events emitted from Peggy.sol: 1. `TransactionBatchExecutedEvent` - event indicating that a token batch (withdrawals) has been successfully relayed to Ethereum 2. `ValsetUpdatedEvent` - event indicating that a `Validator Set` update has been successfully relayed to Ethereum 3. `SendToInjectiveEvent` - event indicating that a new deposit to Injective has been initiated 4. `ERC20DeployedEvent` - event indicating a new Cosmos token has been registered on Ethereum Injective’s `Oracle` implementation ignores the last 12 blocks on Ethereum to ensure block finality. In reality, this means latest events are observed 2-3 minutes after they occurred. ### [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#relayer) Relayer `Relayer` bundles valset updates (or token batches) along with their confirmations into an Ethereum transaction and sends it to the `Peggy contract`. Keep in mind that these messages cost a variable amount of money based on wildly changing Ethereum gas prices, so it’s not unreasonable for a single batch to cost over a million gas. A major design decision for our relayer rewards was to always issue them on the Ethereum chain. This has downsides, namely some strange behavior in the case of validator set update rewards. But the upsides are undeniable, because the Ethereum messages pay `msg.sender` any existing bot in the Ethereum ecosystem will pick them up and try to submit them. This makes the relaying market much more competitive and less prone to cabal like behavior. [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#end-to-end-lifecycle) End-to-end Lifecycle ------------------------------------------------------------------------------------------------------------------------------ This document describes the end to end lifecycle of the Peggy bridge. ### [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#peggy-smart-contract-deployment) Peggy Smart Contract Deployment In order to deploy the Peggy contract, the validator set of the native chain (Injective Chain) must be known. Upon deploying the Peggy contract suite (Peggy Implementation, Proxy contract, and ProxyAdmin contracts), the Peggy contract (the Proxy contract) must be initialized with the validator set. Upon initialization a `ValsetUpdatedEvent` is emitted from the contract. The proxy contract is used to upgrade Peggy Implementation contract which is needed for bug fixing and potential improvements during initial phase. It is a simple wrapper or “proxy” which users interact with directly and is in charge of forwarding transactions to the Peggy implementation contract, which contains the logic. The key concept to understand is that the implementation contract can be replaced but the proxy (the access point) is never changed. The ProxyAdmin is a central admin for the Peggy proxy, which simplifies management. It controls upgradability and ownership transfers. The ProxyAdmin contract itself has a built-in expiration time which, once expired, prevents the Peggy implementation contract from being upgraded in the future. Then the following peggy genesis params should be updated: 1. `bridge_ethereum_address` with Peggy proxy contract address 2. `bridge_contract_start_height` with the height at which the Peggy proxy contract was deployed This completes the bootstrap of the Peggy bridge and the chain can be started. Afterward, `Operators` should start their `peggo` processes and eventually observe that the initial `ValsetUpdatedEvent` is attested on Injective. ### [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#updating-injective-chain-validator-set-on-ethereum) **Updating Injective Chain validator set on Ethereum** ![img.png](https://mintcdn.com/injectivelabs/uX2NM6Rg-WvYYnwC/developers-native/injective/peggy/images/valsetupdate.png?w=2500&fit=max&auto=format&n=uX2NM6Rg-WvYYnwC&q=85&s=583c7794b16d8dfd5202c2eea28f250e) A validator set is a series of Ethereum addresses with attached normalized powers used to represent the Injective validator set (Valset) in the Peggy contract on Ethereum. The Peggy contract stays in sync with the Injective Chain validator set through the following mechanism: 1. **Creating a new Valset on Injective:** A new Valset is automatically created on the Injective Chain when either: * the cumulative difference of the current validator set powers compared to the last recorded Valset exceeds 5% * a validator begins unbonding from the set 2. **Confirming a Valset on Injective:** Each `Operator` is responsible for confirming Valset updates that are created on Injective. The `Signer` process sends these confirmations via `MsgConfirmValset` by having the validator’s delegated Ethereum key sign over a compressed representation of the Valset data. The `Peggy module` verifies the validity of the signature and persists it to its state. 3. **Updating the Valset on the Peggy contract:** After a 2/3+ 1 majority of validators have submitted their confirmations for a given Valset, `Relayer` submits the new Valset data to the Peggy contract by calling `updateValset`. The Peggy contract then validates the data, updates the valset checkpoint, transfers valset rewards to sender and emits a `ValsetUpdatedEvent`. 4. **Acknowledging the `ValsetUpdatedEvent` on Injective:** `Oracle` witnesses the `ValsetUpdatedEvent` on Ethereum, and sends a `MsgValsetUpdatedClaim` which informs the `Peggy module` that the Valset has been updated on Ethereum. 5. **Pruning Valsets on Injective:** Once a 2/3 majority of validators send their claim for a given `ValsetUpdateEvent`, all the previous valsets are pruned from the `Peggy module` state. 6. **Validator Slashing:** Validators are subject to slashing after a configured window of time (`SignedValsetsWindow`) for not providing confirmations. Read more [valset slashing](https://docs.injective.network/developers-native/injective/peggy/05_slashing) * * * ### [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#transferring-erc-20-tokens-from-ethereum-to-injective) **Transferring ERC-20 tokens from Ethereum to Injective** ![img.png](https://mintcdn.com/injectivelabs/uX2NM6Rg-WvYYnwC/developers-native/injective/peggy/images/SendToCosmos.png?w=2500&fit=max&auto=format&n=uX2NM6Rg-WvYYnwC&q=85&s=bf93ab3d92777ea6d57ee1976f866bab) ERC-20 tokens are transferred from Ethereum to Injective through the following mechanism: 1. **Depositing ERC-20 tokens on the Peggy Contract:** A user initiates a transfer of ERC-20 tokens from Ethereum to Injective by calling the `sendToInjective` function on the Peggy contract which deposits tokens on the Peggy contract and emits a `SendToInjectiveEvent`. The deposited tokens will remain locked until withdrawn at some undetermined point in the future. This event contains the amount and type of tokens, as well as a destination address on the Injective Chain to receive the funds. 2. **Confirming the deposit:** Each `Oracle` witnesses the `SendToInjectiveEvent` and sends a `MsgDepositClaim` which contains the deposit information to the Peggy module. 3. **Minting tokens on the Injective:** Once a majority of validators confirm the deposit claim, the deposit is processed. * If the asset is Ethereum originated, the tokens are minted and transferred to the intended recipient’s address on the Injective Chain. * If the asset is Cosmos-SDK originated, the coins are unlocked and transferred to the intended recipient’s address on the Injective Chain. * * * ### [​](https://docs.injective.network/developers-native/injective/peggy/02_workflow#withdrawing-tokens-from-injective-to-ethereum) **Withdrawing tokens from Injective to Ethereum** ![img.png](https://mintcdn.com/injectivelabs/uX2NM6Rg-WvYYnwC/developers-native/injective/peggy/images/SendToEth.png?w=2500&fit=max&auto=format&n=uX2NM6Rg-WvYYnwC&q=85&s=7a685a6a1d42d001818e15c54fe2b8fc) 1. **Request Withdrawal from Injective:** A user can initiate the transfer of assets from the Injective Chain to Ethereum by sending a `MsgSendToEth` transaction to the peggy module. * If the asset is Ethereum native, the represented tokens are burnt. * If the asset is Cosmos SDK native, coins are locked in the module. The withdrawal is then added to `Outgoing Tx Pool`. 2. **Batch Creation:** A `Batch Creator` observes the pool of pending withdrawals. The batch creator (or any external third party) then requests a batch of to be created for given token by sending `MsgRequestBatch` to the Injective Chain. The `Peggy module` collects withdrawals matching the token type into a batch and puts it in `Outgoing Batch Pool`. 3. **Batch Confirmation:** Upon detecting the existence of an Outgoing Batch, the `Signer` signs over the batch with its Ethereum key and submits a `MsgConfirmBatch` tx to the Peggy module. 4. **Submit Batch to Peggy Contract:** Once a majority of validators confirm the batch, the `Relayer` calls `submitBatch` on the Peggy contract with the batch and its confirmations. The Peggy contract validates the signatures, updates the batch checkpoint, processes the batch ERC-20 withdrawals, transfers the batch fee to the tx sender and emits a `TransactionBatchExecutedEvent`. 5. **Send Withdrawal Claim to Injective:** `Oracles` witness the `TransactionBatchExecutedEvent` and send a `MsgWithdrawClaim` containing the withdrawal information to the Peggy module. 6. **Prune Batches** Once a majority of validators submit their `MsgWithdrawClaim` , the batch is deleted along and all previous batches are cancelled on the Peggy module. Withdrawals in cancelled batches get moved back into `Outgoing Tx Pool`. 7. **Batch Slashing:** Validators are responsible for confirming batches and are subject to slashing if they fail to do so. Read more on [batch slashing](https://docs.injective.network/developers-native/injective/peggy/05_slashing) . Note while that batching reduces individual withdrawal costs dramatically, this comes at the cost of latency and implementation complexity. If a user wishes to withdraw quickly they will have to pay a much higher fee. However this fee will be about the same as the fee every withdrawal from the bridge would require in a non-batching system. [Definitions](https://docs.injective.network/developers-native/injective/peggy/01_definitions) [State](https://docs.injective.network/developers-native/injective/peggy/03_state) ⌘I Assistant Responses are generated using AI and may contain mistakes. --- # State - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy/03_state#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... Ctrl KAsk AI Search... Navigation Peggy State On this page * [State](https://docs.injective.network/developers-native/injective/peggy/03_state#state) * [Module Params](https://docs.injective.network/developers-native/injective/peggy/03_state#module-params) * [Validator Info](https://docs.injective.network/developers-native/injective/peggy/03_state#validator-info) * [Ethereum Address by Validator](https://docs.injective.network/developers-native/injective/peggy/03_state#ethereum-address-by-validator) * [Validator by Ethereum Address](https://docs.injective.network/developers-native/injective/peggy/03_state#validator-by-ethereum-address) * [OrchestratorValidator](https://docs.injective.network/developers-native/injective/peggy/03_state#orchestratorvalidator) * [Valset](https://docs.injective.network/developers-native/injective/peggy/03_state#valset) * [SlashedValsetNonce](https://docs.injective.network/developers-native/injective/peggy/03_state#slashedvalsetnonce) * [ValsetNonce](https://docs.injective.network/developers-native/injective/peggy/03_state#valsetnonce) * [Valset Confirmation](https://docs.injective.network/developers-native/injective/peggy/03_state#valset-confirmation) * [Batch Confirmation](https://docs.injective.network/developers-native/injective/peggy/03_state#batch-confirmation) * [OutgoingTransferTx](https://docs.injective.network/developers-native/injective/peggy/03_state#outgoingtransfertx) * [LastTXPoolID](https://docs.injective.network/developers-native/injective/peggy/03_state#lasttxpoolid) * [OutgoingTxBatch](https://docs.injective.network/developers-native/injective/peggy/03_state#outgoingtxbatch) * [LastOutgoingBatchID](https://docs.injective.network/developers-native/injective/peggy/03_state#lastoutgoingbatchid) * [SlashedBlockHeight](https://docs.injective.network/developers-native/injective/peggy/03_state#slashedblockheight) * [LastUnbondingBlockHeight](https://docs.injective.network/developers-native/injective/peggy/03_state#lastunbondingblockheight) * [TokenContract & Denom](https://docs.injective.network/developers-native/injective/peggy/03_state#tokencontract-%26-denom) * [LastObservedValset](https://docs.injective.network/developers-native/injective/peggy/03_state#lastobservedvalset) * [LastEventNonce](https://docs.injective.network/developers-native/injective/peggy/03_state#lasteventnonce) * [LastObservedEthereumHeight](https://docs.injective.network/developers-native/injective/peggy/03_state#lastobservedethereumheight) * [LastEventByValidator](https://docs.injective.network/developers-native/injective/peggy/03_state#lasteventbyvalidator) * [Attestation](https://docs.injective.network/developers-native/injective/peggy/03_state#attestation) * [PastEthSignatureCheckpoint](https://docs.injective.network/developers-native/injective/peggy/03_state#pastethsignaturecheckpoint) * [EthereumBlacklist](https://docs.injective.network/developers-native/injective/peggy/03_state#ethereumblacklist) [​](https://docs.injective.network/developers-native/injective/peggy/03_state#state) State ============================================================================================= This doc lists all the data Peggy module reads/writes to its state as KV pairs ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#module-params) Module Params Params is a module-wide configuration structure that stores parameters and defines overall functioning of the peggy module. Detailed specification for each parameter can be found in the [Parameters section](https://docs.injective.network/developers-native/injective/peggy/08_params) . | key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0x4}` | Module params | `types.Params` | Protobuf encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#validator-info) Validator Info #### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#ethereum-address-by-validator) Ethereum Address by Validator Stores `Delegate Ethereum address` indexed by the `Validator`’s account address | key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0x1} + []byte(validatorAddr)` | Ethereum address | `common.Address` | Protobuf encoded | #### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#validator-by-ethereum-address) Validator by Ethereum Address Stores `Validator` account address indexed by the `Delegate Ethereum address` | key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xfb} + []byte(ethAddress)` | Validator address | `sdk.ValAddress` | Protobuf encoded | #### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#orchestratorvalidator) OrchestratorValidator When a validator would like to delegate their voting power to another key. The value is stored using the orchestrator address as the key | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xe8} + []byte(AccAddress)` | Orchestrator address assigned by a validator | `[]byte` | Protobuf encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#valset) Valset This is the validator set of the bridge. Created automatically by `Peggy module` during EndBlocker. Stored in two possible ways, first with a height and second without (unsafe). Unsafe is used for testing and export and import of state. Copy Ask AI type Valset struct { Nonce uint64 Members []*BridgeValidator Height uint64 RewardAmount math.Int RewardToken string } | key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0x2} + nonce (big endian encoded)` | Validator set | `types.Valset` | Protobuf encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#slashedvalsetnonce) SlashedValsetNonce The latest validator set slash nonce. This is used to track which validator set needs to be slashed and which already has been. | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xf5}` | Nonce | uint64 | encoded via big endian | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#valsetnonce) ValsetNonce Nonce of the latest validator set. Updated on each new validator set. | key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xf6}` | Nonce | `uint64` | encoded via big endian | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#valset-confirmation) Valset Confirmation `Singer` confirmation for a particular validator set. See [oracle messages](https://docs.injective.network/developers-native/injective/peggy/04_messages.md#ValsetConfirm) | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0x3} + (nonce + []byte(AccAddress)` | Validator Confirmation | `types.MsgValsetConfirm` | Protobuf encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#batch-confirmation) Batch Confirmation `Singer` confirmation for a particular token batch. See [oracle messages](https://docs.injective.network/developers-native/injective/peggy/04_messages.md#ConfirmBatch) | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xe1} + []byte(tokenContract) + nonce + []byte(AccAddress)` | Validator Batch Confirmation | `types.MsgConfirmBatch` | Protobuf encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#outgoingtransfertx) OutgoingTransferTx User withdrawals are pooled together in `Peggy Tx Pool` ready to be batched later by a `Batch Creator`. Each withdrawal is indexed by a unique nonce set by the `Peggy module` when the withdrawal was received. Copy Ask AI type OutgoingTransferTx struct { Id uint64 Sender string DestAddress string Erc20Token *ERC20Token Erc20Fee *ERC20Token } | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0x7} + []byte("lastTxPoolId")` | nonce of outgoing withdrawal | `uint64` | Big endian encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#lasttxpoolid) LastTXPoolID Monotonically increasing value for each withdrawal received by Injective | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0x6} + []byte("lastTxPoolId")` | Last used withdrawal ID | `uint64` | Big endian encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#outgoingtxbatch) OutgoingTxBatch `OutgoingTxBatch` represents a collection of withdrawals of the same token type. Created on every successful `MsgRequestBatch`. Stored in two possible ways, first with a height and second without (unsafe). Unsafe is used for testing and export and import of state. Currently [Peggy.sol](https://github.com/InjectiveLabs/peggo/blob/master/solidity/contracts/Peggy.sol) is hardcoded to only accept batches with a single token type and only pay rewards in that same token type. Copy Ask AI type OutgoingTxBatch struct { BatchNonce uint64 BatchTimeout uint64 Transactions []*OutgoingTransferTx TokenContract string Block uint64 } | key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xa} + []byte(tokenContract) + nonce (big endian encoded)` | A batch of outgoing transactions | `types.OutgoingTxBatch` | Protobuf encoded | | `[]byte{0xb} + block (big endian encoded)` | A batch of outgoing transactions | `types.OutgoingTxBatch` | Protobuf encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#lastoutgoingbatchid) LastOutgoingBatchID Monotonically increasing value for each batch created on Injective by some `Batch Creator` | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0x7} + []byte("lastBatchId")` | Last used batch ID | `uint64` | Big endian encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#slashedblockheight) SlashedBlockHeight Represents the latest slashed block height. There is always only a singe value stored. | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xf7}` | Latest height a batch slashing occurred | `uint64` | Big endian encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#lastunbondingblockheight) LastUnbondingBlockHeight Represents the latest bloch height at which a `Validator` started unbonding from the `Validator Set`. Used to determine slashing conditions. | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xf8}` | Latest height at which a Validator started unbonding | `uint64` | Big endian encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#tokencontract-&-denom) TokenContract & Denom A denom that is originally from a counter chain will be from a contract. The token contract and denom are stored in two ways. First, the denom is used as the key and the value is the token contract. Second, the contract is used as the key, the value is the denom the token contract represents. | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xf3} + []byte(denom)` | Token contract address | `[]byte` | stored in byte format | | `[]byte{0xf4} + []byte(tokenContract)` | Token denom | `[]byte` | stored in byte format | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#lastobservedvalset) LastObservedValset This entry represents the last observed Valset that was successfully relayed to Ethereum. Updates after an attestation of `ValsetUpdatedEvent` has been processed on Injective. | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xfa}` | Last observed Valset on Ethereum | `types.Valset` | Protobuf encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#lasteventnonce) LastEventNonce The nonce of the last observed event on Ethereum. This is set when `TryAttestation()` is called. There is always only a single value held in this store. | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xf2}` | Last observed event nonce | `uint64` | Big endian encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#lastobservedethereumheight) LastObservedEthereumHeight This block height of the last observed event on Ethereum. There will always only be a single value stored in this store. | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xf9}` | Last observed Ethereum Height | `uint64` | Protobuf encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#lasteventbyvalidator) LastEventByValidator This is the last observed event on Ethereum from a particular `Validator`. Updated every time the asssociated `Orchestrator` sends an event claim. Copy Ask AI type LastClaimEvent struct { EthereumEventNonce uint64 EthereumEventHeight uint64 } | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0xf1} + []byte(validator address)` | Last observed event by some Validator | `types.LastClaimEvent` | Protobuf encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#attestation) Attestation Attestation is an aggregate of claims that eventually becomes observed by all orchestrators as more votes (claims) are coming in. Once observed the claim’s particular logic gets executed. Each attestation is bound to a unique event nonce (generated by `Peggy contract`) and they must be processed in order. This is a correctness issue, if relaying out of order transaction replay attacks become possible. Copy Ask AI type Attestation struct { Observed bool Votes []string Height uint64 Claim *types.Any } | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0x5} + event nonce (big endian encoded) + []byte(claimHash)` | Attestation of occurred events/claims | `types.Attestation` | Protobuf encoded | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#pastethsignaturecheckpoint) PastEthSignatureCheckpoint A computed hash indicating that a validator set/token batch in fact existed on Injective. This checkpoint also exists in `Peggy contract`. Updated on each new valset update and token batch creation. | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0x1b}` | Last created checkpoint hash on Injective | `gethcommon.Hash` | store in byte format | ### [​](https://docs.injective.network/developers-native/injective/peggy/03_state#ethereumblacklist) EthereumBlacklist A list of known malicious Ethereum addresses that are prevented from using the bridge. | Key | Value | Type | Encoding | | --- | --- | --- | --- | | `[]byte{0x1c} + []byte(ethereum address)` | Empty \[\]byte slice | `gethcommon.Hash` | stored in byte format\] | [Workflow](https://docs.injective.network/developers-native/injective/peggy/02_workflow) [Messages](https://docs.injective.network/developers-native/injective/peggy/04_messages) Ctrl+I Assistant Responses are generated using AI and may contain mistakes. --- # End-Block - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy/06_end_block#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... Ctrl KAsk AI Search... Navigation Peggy End-Block On this page * [EndBlocker](https://docs.injective.network/developers-native/injective/peggy/06_end_block#endblocker) * [1\. Slashing](https://docs.injective.network/developers-native/injective/peggy/06_end_block#1-slashing) * [Validator slashing](https://docs.injective.network/developers-native/injective/peggy/06_end_block#validator-slashing) * [Batch Slashing](https://docs.injective.network/developers-native/injective/peggy/06_end_block#batch-slashing) * [2\. Cancelling timed out batches](https://docs.injective.network/developers-native/injective/peggy/06_end_block#2-cancelling-timed-out-batches) * [3\. Creating new Valset updates](https://docs.injective.network/developers-native/injective/peggy/06_end_block#3-creating-new-valset-updates) * [4\. Pruning old validator sets](https://docs.injective.network/developers-native/injective/peggy/06_end_block#4-pruning-old-validator-sets) * [5\. Attestation processing](https://docs.injective.network/developers-native/injective/peggy/06_end_block#5-attestation-processing) * [6\. Cleaning up processed attestations](https://docs.injective.network/developers-native/injective/peggy/06_end_block#6-cleaning-up-processed-attestations) [​](https://docs.injective.network/developers-native/injective/peggy/06_end_block#endblocker) EndBlocker =========================================================================================================== Upon the end of each block the following operations are performed to the state of the module [​](https://docs.injective.network/developers-native/injective/peggy/06_end_block#1-slashing) 1\. Slashing ------------------------------------------------------------------------------------------------------------- ### [​](https://docs.injective.network/developers-native/injective/peggy/06_end_block#validator-slashing) Validator slashing A validator is slashed for not signing over a valset update which passed the `SignedValsetsWindow`. In other words, if a validator fails to provide the confirmation for a valset update within a preconfigured amount of time, they will be slashed for `SlashFractionValset` portion of their stake and get jailed immediately. ### [​](https://docs.injective.network/developers-native/injective/peggy/06_end_block#batch-slashing) Batch Slashing A validator is slashed for not signing over a batch which passed the `SignedBatchesWindow`. In other words, if a validator fails to provide the confirmation for a batch within a preconfigured amount of time, they will be slashed for `SlashFractionBatch` portion of their stake and get jailed immediately. [​](https://docs.injective.network/developers-native/injective/peggy/06_end_block#2-cancelling-timed-out-batches) 2\. Cancelling timed out batches ----------------------------------------------------------------------------------------------------------------------------------------------------- Any batch still present in the `Outgoing Batch pool` whose `BatchTimeout` (a designated Ethereum height by which the batch should have executed) is exceeded gets removed from the pool and the withdrawals are reinserted back into the `Outgoing Tx pool`. [​](https://docs.injective.network/developers-native/injective/peggy/06_end_block#3-creating-new-valset-updates) 3\. Creating new Valset updates --------------------------------------------------------------------------------------------------------------------------------------------------- A new `Validator Set` update will be created automatically when: * there is a power diff greater than 5% between the latest and current validator set * a validator begins unbonding The new validator set is eventually relayed to `Peggy contract` on Ethereum. [​](https://docs.injective.network/developers-native/injective/peggy/06_end_block#4-pruning-old-validator-sets) 4\. Pruning old validator sets ------------------------------------------------------------------------------------------------------------------------------------------------- Previously observed valsets that passed the `SignedValsetsWindow` are removed from the state [​](https://docs.injective.network/developers-native/injective/peggy/06_end_block#5-attestation-processing) 5\. Attestation processing ----------------------------------------------------------------------------------------------------------------------------------------- Processes all attestations (an aggregate of claims for a particular event) currently being voted on. Each attestation is processed one by one to ensure each `Peggy contract` event is processed. After each processed attestation the module’s `lastObservedEventNonce` and `lastObservedEthereumBlockHeight` are updated. Depending on the type of claim in the attestation, the following is executed: * `MsgDepositClaim`: deposited tokens are minted/unlocked for the receiver address * `MsgWithdrawClaim`: corresponding batch is removed from the outgoing pool and any previous batch is cancelled * `MsgValsetUpdatedClaim`: the module’s `LastObservedValset` is updated * `MsgERC20DeployedClaim`: new token metadata is validated and registered within the module’s state (`denom <-> token_contract`) [​](https://docs.injective.network/developers-native/injective/peggy/06_end_block#6-cleaning-up-processed-attestations) 6\. Cleaning up processed attestations ----------------------------------------------------------------------------------------------------------------------------------------------------------------- Previously processed attestations (height earlier that `lastObservedEthereumBlockHeight`) are removed from the module state [Slashing](https://docs.injective.network/developers-native/injective/peggy/05_slashing) [Events](https://docs.injective.network/developers-native/injective/peggy/07_events) Ctrl+I Assistant Responses are generated using AI and may contain mistakes. --- # Messages - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy/04_messages#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... Ctrl KAsk AI Search... Navigation Peggy Messages On this page * [Messages](https://docs.injective.network/developers-native/injective/peggy/04_messages#messages) * [User messages](https://docs.injective.network/developers-native/injective/peggy/04_messages#user-messages) * [SendToEth](https://docs.injective.network/developers-native/injective/peggy/04_messages#sendtoeth) * [CancelSendToEth](https://docs.injective.network/developers-native/injective/peggy/04_messages#cancelsendtoeth) * [SubmitBadSignatureEvidence](https://docs.injective.network/developers-native/injective/peggy/04_messages#submitbadsignatureevidence) * [Batch Creator Messages](https://docs.injective.network/developers-native/injective/peggy/04_messages#batch-creator-messages) * [RequestBatch](https://docs.injective.network/developers-native/injective/peggy/04_messages#requestbatch) * [Oracle Messages](https://docs.injective.network/developers-native/injective/peggy/04_messages#oracle-messages) * [DepositClaim](https://docs.injective.network/developers-native/injective/peggy/04_messages#depositclaim) * [WithdrawClaim](https://docs.injective.network/developers-native/injective/peggy/04_messages#withdrawclaim) * [ValsetUpdatedClaim](https://docs.injective.network/developers-native/injective/peggy/04_messages#valsetupdatedclaim) * [ERC20DeployedClaim](https://docs.injective.network/developers-native/injective/peggy/04_messages#erc20deployedclaim) * [Signer Messages](https://docs.injective.network/developers-native/injective/peggy/04_messages#signer-messages) * [ConfirmBatch](https://docs.injective.network/developers-native/injective/peggy/04_messages#confirmbatch) * [ValsetConfirm](https://docs.injective.network/developers-native/injective/peggy/04_messages#valsetconfirm) * [Relayer Messages](https://docs.injective.network/developers-native/injective/peggy/04_messages#relayer-messages) * [Validator Messages](https://docs.injective.network/developers-native/injective/peggy/04_messages#validator-messages) * [SetOrchestratorAddresses](https://docs.injective.network/developers-native/injective/peggy/04_messages#setorchestratoraddresses) [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#messages) Messages ====================================================================================================== This is a reference document for Peggy message types. For code reference and exact arguments see the [proto definitions](https://github.com/InjectiveLabs/injective-core/blob/master/proto/injective/peggy/v1/msgs.proto) . [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#user-messages) User messages ---------------------------------------------------------------------------------------------------------------- These are messages sent on the Injective Chain peggy module by the end user. See [workflow](https://docs.injective.network/developers-native/injective/peggy/02_workflow) for a more detailed summary of the entire deposit and withdraw process. ### [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#sendtoeth) SendToEth Sent to Injective whenever a user wishes to make a withdrawal back to Ethereum. Submitted amount is removed from the user’s balance immediately. The withdrawal is added to the outgoing tx pool as a `types.OutgoingTransferTx` where it will remain until it is included in a batch. Copy Ask AI type MsgSendToEth struct { Sender string // sender's Injective address EthDest string // receiver's Ethereum address Amount types.Coin // amount of tokens to bridge BridgeFee types.Coin // additional fee for bridge relayers. Must be of same token type as Amount } ### [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#cancelsendtoeth) CancelSendToEth This message allows the user to cancel a specific withdrawal that is not yet batched. User balance is refunded (`Amount` + `BridgeFee`). Copy Ask AI type MsgCancelSendToEth struct { TransactionId uint64 // unique tx nonce of the withdrawal Sender string // original sender of the withdrawal } ### [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#submitbadsignatureevidence) SubmitBadSignatureEvidence This call allows anyone to submit evidence that a validator has signed a valset or batch that never existed. Subject contains the batch or valset. Copy Ask AI type MsgSubmitBadSignatureEvidence struct { Subject *types1.Any Signature string Sender string } [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#batch-creator-messages) Batch Creator Messages ---------------------------------------------------------------------------------------------------------------------------------- These messages are sent by the `Batch Creator` subprocess of `peggo` ### [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#requestbatch) RequestBatch This message is sent whenever some `Batch Creator` finds pooled withdrawals that when batched would satisfy their minimum batch fee (`PEGGO_MIN_BATCH_FEE_USD`). After receiving this message the `Peggy module` collects all withdrawals of the requested token denom, creates a unique token batch (`types.OutgoingTxBatch`) and places it in the `Outgoing Batch pool`. Withdrawals that are batched cannot be cancelled with `MsgCancelSendToEth`. Copy Ask AI type MsgRequestBatch struct { Orchestrator string // orchestrator address interested in creating the batch. Not permissioned. Denom string // the specific token whose withdrawals will be batched together } [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#oracle-messages) Oracle Messages -------------------------------------------------------------------------------------------------------------------- These messages are sent by the `Oracle` subprocess of `peggo` ### [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#depositclaim) DepositClaim Sent to Injective when a `SendToInjectiveEvent` is emitted from the `Peggy contract`. This occurs whenever a user is making an individual deposit from Ethereum to Injective. Copy Ask AI type MsgDepositClaim struct { EventNonce uint64 // unique nonce of the event BlockHeight uint64 // Ethereum block height at which the event was emitted TokenContract string // contract address of the ERC20 token Amount sdkmath.Int // amount of deposited tokens EthereumSender string // sender's Ethereum address CosmosReceiver string // receiver's Injective address Orchestrator string // address of the Orchestrator which observed the event } ### [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#withdrawclaim) WithdrawClaim Sent to Injective when a `TransactionBatchExecutedEvent` is emitted from the `Peggy contract`. This occurs when a `Relayer` has successfully called `submitBatch` on the contract to complete a batch of withdrawals. Copy Ask AI type MsgWithdrawClaim struct { EventNonce uint64 // unique nonce of the event BlockHeight uint64 // Ethereum block height at which the event was emitted BatchNonce uint64 // nonce of the batch executed on Ethereum TokenContract string // contract address of the ERC20 token Orchestrator string // address of the Orchestrator which observed the event } ### [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#valsetupdatedclaim) ValsetUpdatedClaim Sent to Injective when a `ValsetUpdatedEvent` is emitted from the `Peggy contract`. This occurs when a `Relayer` has successfully called `updateValset` on the contract to update the `Validator Set` on Ethereum. Copy Ask AI type MsgValsetUpdatedClaim struct { EventNonce uint64 // unique nonce of the event ValsetNonce uint64 // nonce of the valset BlockHeight uint64 // Ethereum block height at which the event was emitted Members []*BridgeValidator // members of the Validator Set RewardAmount sdkmath.Int // Reward for relaying the valset update RewardToken string // reward token contract address Orchestrator string // address of the Orchestrator which observed the event } ### [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#erc20deployedclaim) ERC20DeployedClaim Sent to Injective when a `ERC20DeployedEvent` is emitted from the `Peggy contract`. This occurs whenever the `deployERC20` method is called on the contract to issue a new token asset eligible for bridging. Copy Ask AI type MsgERC20DeployedClaim struct { EventNonce uint64 // unique nonce of the event BlockHeight uint64 // Ethereum block height at which the event was emitted CosmosDenom string // denom of the token TokenContract string // contract address of the token Name string // name of the token Symbol string // symbol of the token Decimals uint64 // number of decimals the token has Orchestrator string // address of the Orchestrator which observed the event } [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#signer-messages) Signer Messages -------------------------------------------------------------------------------------------------------------------- These messages are sent by the `Signer` subprocess of `peggo` ### [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#confirmbatch) ConfirmBatch When `Signer` finds a batch that the `Orchestrator` (`Validator`) has not signed off, it constructs a signature with its `Delegated Ethereum Key` and sends the confirmation to Injective. It’s crucial that a `Validator` eventually provides their confirmation for a created batch as they will be slashed otherwise. Copy Ask AI type MsgConfirmBatch struct { Nonce uint64 // nonce of the batch TokenContract string // contract address of batch token EthSigner string // Validator's delegated Ethereum address (previously registered) Orchestrator string // address of the Orchestrator confirming the batch Signature string // Validator's signature of the batch } ### [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#valsetconfirm) ValsetConfirm When `Signer` finds a valset update that the `Orchestrator` (`Validator`) has not signed off, it constructs a signature with its `Delegated Ethereum Key` and sends the confirmation to Injective. It’s crucial that a `Validator` eventually provides their confirmation for a created valset update as they will be slashed otherwise. Copy Ask AI type MsgValsetConfirm struct { Nonce uint64 // nonce of the valset Orchestrator string // address of the Orchestrator confirming the valset EthAddress string // Validator's delegated Ethereum address (previously registered) Signature string // Validator's signature of the valset } [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#relayer-messages) Relayer Messages ---------------------------------------------------------------------------------------------------------------------- The `Relayer` does not send any message to Injective, rather it constructs Ethereum transactions with Injective data to update the `Peggy contract` via `submitBatch` and `updateValset` methods. [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#validator-messages) Validator Messages -------------------------------------------------------------------------------------------------------------------------- These are messages sent directly using the validator’s message key. ### [​](https://docs.injective.network/developers-native/injective/peggy/04_messages#setorchestratoraddresses) SetOrchestratorAddresses Sent to Injective by an `Operator` managing a `Validator` node. Before being able to start their `Orchestrator` (`peggo`) process, they must register a chosen Ethereum address to represent their `Validator` on Ethereum. Optionally, an additional Injective address can be provided (`Orchestrator` field) to represent that `Validator` in the bridging process (`peggo`). Defaults to `Validator`’s own address if omitted. Copy Ask AI type MsgSetOrchestratorAddresses struct { Sender string // address of the Injective validator Orchestrator string // optional Injective address to represent the Validator in the bridging process (Defaults to Sender if left empty) EthAddress string // the Sender's (Validator) delegated Ethereum address } This message sets the Orchestrator’s delegate keys. [State](https://docs.injective.network/developers-native/injective/peggy/03_state) [Slashing](https://docs.injective.network/developers-native/injective/peggy/05_slashing) Ctrl+I Assistant Responses are generated using AI and may contain mistakes. --- # Parameters - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy/08_params#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... Ctrl KAsk AI Search... Navigation Peggy Parameters On this page * [Params](https://docs.injective.network/developers-native/injective/peggy/08_params#params) * [peggy\_id](https://docs.injective.network/developers-native/injective/peggy/08_params#peggy-id) * [contract\_source\_hash](https://docs.injective.network/developers-native/injective/peggy/08_params#contract-source-hash) * [bridge\_ethereum\_address](https://docs.injective.network/developers-native/injective/peggy/08_params#bridge-ethereum-address) * [bridge\_chain\_id](https://docs.injective.network/developers-native/injective/peggy/08_params#bridge-chain-id) * [Signing windows](https://docs.injective.network/developers-native/injective/peggy/08_params#signing-windows) * [target\_batch\_timeout](https://docs.injective.network/developers-native/injective/peggy/08_params#target-batch-timeout) * [Ethereum timing](https://docs.injective.network/developers-native/injective/peggy/08_params#ethereum-timing) * [Slash fractions](https://docs.injective.network/developers-native/injective/peggy/08_params#slash-fractions) * [valset\_reward](https://docs.injective.network/developers-native/injective/peggy/08_params#valset-reward) [​](https://docs.injective.network/developers-native/injective/peggy/08_params#params) Params ================================================================================================ This document describes and advises configuration of the Peggy module’s parameters. The default parameters can be found in the genesis.go of the peggy module. Copy Ask AI type Params struct { PeggyId string ContractSourceHash string BridgeEthereumAddress string BridgeChainId uint64 SignedValsetsWindow uint64 SignedBatchesWindow uint64 SignedClaimsWindow uint64 TargetBatchTimeout uint64 AverageBlockTime uint64 AverageEthereumBlockTime uint64 SlashFractionValset math.LegacyDec SlashFractionBatch math.LegacyDec SlashFractionClaim math.LegacyDec SlashFractionConflictingClaim math.LegacyDec UnbondSlashingValsetsWindow uint64 SlashFractionBadEthSignature math.LegacyDec CosmosCoinDenom string CosmosCoinErc20Contract string ClaimSlashingEnabled bool BridgeContractStartHeight uint64 ValsetReward types.Coin } [​](https://docs.injective.network/developers-native/injective/peggy/08_params#peggy-id) `peggy_id` ------------------------------------------------------------------------------------------------------ A random 32 byte value to prevent signature reuse, for example if the Injective Chain validators decided to use the same Ethereum keys for another chain also running Peggy we would not want it to be possible to play a deposit from chain A back on chain B’s Peggy. This value IS USED ON ETHEREUM so it must be set in your genesis.json before launch and not changed after deploying Peggy. Changing this value after deploying Peggy will result in the bridge being non-functional. To recover just set it back to the original value the contract was deployed with. [​](https://docs.injective.network/developers-native/injective/peggy/08_params#contract-source-hash) `contract_source_hash` ------------------------------------------------------------------------------------------------------------------------------ The code hash of a known good version of the Peggy contract solidity code. This can be used to verify the correct version of the contract has been deployed. This is a reference value for governance action only it is never read by any Peggy code [​](https://docs.injective.network/developers-native/injective/peggy/08_params#bridge-ethereum-address) `bridge_ethereum_address` ------------------------------------------------------------------------------------------------------------------------------------ is address of the bridge contract on the Ethereum side, this is a reference value for governance only and is not actually used by any Peggy module code. The Ethereum bridge relayer use this value to interact with Peggy contract for querying events and submitting valset/batches to Peggy contract. [​](https://docs.injective.network/developers-native/injective/peggy/08_params#bridge-chain-id) `bridge_chain_id` -------------------------------------------------------------------------------------------------------------------- The bridge chain ID is the unique identifier of the Ethereum chain. This is a reference value only and is not actually used by any Peggy code These reference values may be used by future Peggy client implementations to allow for consistency checks. [​](https://docs.injective.network/developers-native/injective/peggy/08_params#signing-windows) Signing windows ------------------------------------------------------------------------------------------------------------------ * `signed_valsets_window` * `signed_batches_window` * `signed_claims_window` These values represent the time in blocks that a validator has to submit a signature for a batch or valset, or to submit a claim for a particular attestation nonce. In the case of attestations this clock starts when the attestation is created, but only allows for slashing once the event has passed. Note that that claims slashing is not currently enabled see [slashing spec](https://docs.injective.network/developers-native/injective/peggy/05_slashing) [​](https://docs.injective.network/developers-native/injective/peggy/08_params#target-batch-timeout) `target_batch_timeout` ------------------------------------------------------------------------------------------------------------------------------ This is the ‘target’ value for when batches time out, this is a target because Ethereum is a probabilistic chain and you can’t say for sure what the block frequency is ahead of time. [​](https://docs.injective.network/developers-native/injective/peggy/08_params#ethereum-timing) Ethereum timing ------------------------------------------------------------------------------------------------------------------ * `average_block_time` * `average_ethereum_block_time` These values are the average Injective Chain block time and Ethereum block time respectively and they are used to compute what the target batch timeout is. It is important that governance updates these in case of any major, prolonged change in the time it takes to produce a block [​](https://docs.injective.network/developers-native/injective/peggy/08_params#slash-fractions) Slash fractions ------------------------------------------------------------------------------------------------------------------ * `slash_fraction_valset` * `slash_fraction_batch` * `slash_fraction_claim` * `slash_fraction_conflicting_claim` The slashing fractions for the various peggy related slashing conditions. The first three refer to not submitting a particular message, the third for failing to submit a claim and the last for submitting a different claim than other validators. Note that claim slashing is currently disabled as outlined in the [slashing spec](https://docs.injective.network/developers-native/injective/peggy/05_slashing) [​](https://docs.injective.network/developers-native/injective/peggy/08_params#valset-reward) `valset_reward` ---------------------------------------------------------------------------------------------------------------- Valset reward is the reward amount paid to a relayer when they relay a valset to the Peggy contract on Ethereum. [Events](https://docs.injective.network/developers-native/injective/peggy/07_events) [Relay Semantics](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics) Ctrl+I Assistant Responses are generated using AI and may contain mistakes. --- # Slashing - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy/05_slashing#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... Ctrl KAsk AI Search... Navigation Peggy Slashing On this page * [Slashing](https://docs.injective.network/developers-native/injective/peggy/05_slashing#slashing) * [Security Concerns](https://docs.injective.network/developers-native/injective/peggy/05_slashing#security-concerns) * [PEGGYSLASH-01: Signing fake validator set or tx batch evidence](https://docs.injective.network/developers-native/injective/peggy/05_slashing#peggyslash-01-signing-fake-validator-set-or-tx-batch-evidence) * [PEGGYSLASH-02: Failure to sign tx batch](https://docs.injective.network/developers-native/injective/peggy/05_slashing#peggyslash-02-failure-to-sign-tx-batch) * [PEGGYSLASH-03: Failure to sign validator set update](https://docs.injective.network/developers-native/injective/peggy/05_slashing#peggyslash-03-failure-to-sign-validator-set-update) * [PEGGYSLASH-04: Submitting incorrect Eth oracle claim (Disabled for now)](https://docs.injective.network/developers-native/injective/peggy/05_slashing#peggyslash-04-submitting-incorrect-eth-oracle-claim-disabled-for-now) * [PEGGYSLASH-05: Failure to submit Eth oracle claims (Disabled for now)](https://docs.injective.network/developers-native/injective/peggy/05_slashing#peggyslash-05-failure-to-submit-eth-oracle-claims-disabled-for-now) [​](https://docs.injective.network/developers-native/injective/peggy/05_slashing#slashing) Slashing ====================================================================================================== ### [​](https://docs.injective.network/developers-native/injective/peggy/05_slashing#security-concerns) Security Concerns The **Validator Set** is the actual set of keys with stake behind them, which are slashed for double-signs or other misbehavior. We typically consider the security of a chain to be the security of a _Validator Set_. This varies on each chain, but is our gold standard. Even IBC offers no more security than the minimum of both involved Validator Sets. The **Eth bridge relayer** is a binary run alongside the main `injectived` daemon by the validator set. It exists purely as a matter of code organization and is in charge of signing Ethereum transactions, as well as observing events on Ethereum and bringing them into the Injective Chain state. It signs transactions bound for Ethereum with an Ethereum key, and signs over events coming from Ethereum with an Injective Chain account key. We can add slashing conditions to any mis-signed message by any _Eth Signer_ run by the _Validator Set_ and be able to provide the same security as the _Validator Set_, just a different module detecting evidence of malice and deciding how much to slash. If we can prove a transaction signed by any _Eth Signer_ of the _Validator Set_ was illegal or malicious, then we can slash on the Injective Chain side and potentially provide 100% of the security of the _Validator Set_. Note that this also has access to the 3 week unbonding period to allow evidence to slash even if they immediately unbond. Below are various slashing conditions we use in Peggy. [​](https://docs.injective.network/developers-native/injective/peggy/05_slashing#peggyslash-01-signing-fake-validator-set-or-tx-batch-evidence) PEGGYSLASH-01: Signing fake validator set or tx batch evidence ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- This slashing condition is intended to stop validators from signing over a validator set and nonce that has never existed on the Injective Chain. It works via an evidence mechanism, where anyone can submit a message containing the signature of a validator over a fake validator set. This is intended to produce the effect that if a cartel of validators is formed with the intention of submitting a fake validator set, one defector can cause them all to be slashed. Copy Ask AI // This call allows anyone to submit evidence that a // validator has signed a valset, batch, or logic call that never // existed. Subject contains the batch, valset, or logic call. type MsgSubmitBadSignatureEvidence struct { Subject *types1.Any Signature string Sender string } **Implementation considerations:** The trickiest part of this slashing condition is determining that a validator set has never existed on Injective. To save space, we will need to clean up old validator sets. We could keep a mapping of validator set hash to true in the KV store, and use that to check if a validator set has ever existed. This is more efficient than storing the whole validator set, but its growth is still unbounded. It might be possible to use other cryptographic methods to cut down on the size of this mapping. It might be OK to prune very old entries from this mapping, but any pruning reduces the deterrence of this slashing condition. The implemented version of this slashing condition stores a map of hashes for all past events, this is smaller than storing entire batches or validator sets and doesn’t have to be accessed as frequently. A possible but not currently implemented efficiency optimization would be to remove hashes from this list after a given period. But this would require storing more metadata about each hash. Currently automatic evidence submission is not implemented in the relayer. By the time a signature is visible on Ethereum it’s already too late for slashing to prevent bridge highjacking or theft of funds. Furthermore since 66% of the validator set is required to perform this action anyways that same controlling majority could simply refuse the evidence. The most common case envisioned for this slashing condition is to break up a cabal of validators trying to take over the bridge by making it more difficult for them to trust one another and actually coordinate such a theft. The theft would involve exchanging of slashable Ethereum signatures and open up the possibility of a manual submission of this message by any defector in the group. Currently this is implemented as an ever growing array of hashes in state. [​](https://docs.injective.network/developers-native/injective/peggy/05_slashing#peggyslash-02-failure-to-sign-tx-batch) PEGGYSLASH-02: Failure to sign tx batch ------------------------------------------------------------------------------------------------------------------------------------------------------------------- This slashing condition is triggered when a validator does not sign a transaction batch within `SignedBatchesWindow` upon it’s creation by the Peggy module. This prevents two bad scenarios- 1. A validator simply does not bother to keep the correct binaries running on their system, 2. A cartel of >1/3 validators unbond and then refuse to sign updates, preventing any batches from getting enough signatures to be submitted to the Peggy Ethereum contract. [​](https://docs.injective.network/developers-native/injective/peggy/05_slashing#peggyslash-03-failure-to-sign-validator-set-update) PEGGYSLASH-03: Failure to sign validator set update ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- This slashing condition is triggered when a validator does not sign a validator set update which is produced by the Peggy module. This prevents two bad scenarios- 1. A validator simply does not bother to keep the correct binaries running on their system, 2. A cartel of >1/3 validators unbond and then refuse to sign updates, preventing any validator set updates from getting enough signatures to be submitted to the Peggy Ethereum contract. If they prevent validator set updates for longer than the Injective Chain unbonding period, they can no longer be punished for submitting fake validator set updates and tx batches (PEGGYSLASH-01 and PEGGYSLASH-03). To deal with scenario 2, PEGGYSLASH-03 will also need to slash validators who are no longer validating, but are still in the unbonding period for up to `UnbondSlashingValsetsWindow` blocks. This means that when a validator leaves the validator set, they will need to keep running their equipment for at least `UnbondSlashingValsetsWindow` blocks. This is unusual for the Injective Chain, and may not be accepted by the validators. The current value of `UnbondSlashingValsetsWindow` is 25,000 blocks, or about 12-14 hours. We have determined this to be a safe value based on the following logic. So long as every validator leaving the validator set signs at least one validator set update that they are not contained in then it is guaranteed to be possible for a relayer to produce a chain of validator set updates to transform the current state on the chain into the present state. It should be noted that both PEGGYSLASH-02 and PEGGYSLASH-03 could be eliminated with no loss of security if it where possible to perform the Ethereum signatures inside the consensus code. This is a pretty limited feature addition to Tendermint that would make Peggy far less prone to slashing. [​](https://docs.injective.network/developers-native/injective/peggy/05_slashing#peggyslash-04-submitting-incorrect-eth-oracle-claim-disabled-for-now) PEGGYSLASH-04: Submitting incorrect Eth oracle claim (Disabled for now) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The Ethereum oracle code (currently mostly contained in attestation.go), is a key part of Peggy. It allows the Peggy module to have knowledge of events that have occurred on Ethereum, such as deposits and executed batches. PEGGYSLASH-03 is intended to punish validators who submit a claim for an event that never happened on Ethereum. **Implementation considerations** The only way we know whether an event has happened on Ethereum is through the Ethereum event oracle itself. So to implement this slashing condition, we slash validators who have submitted claims for a different event at the same nonce as an event that was observed by >2/3s of validators. Although well-intentioned, this slashing condition is likely not advisable for most applications of Peggy. This is because it ties the functioning of the Injective Chain which it is installed on to the correct functioning of the Ethereum chain. If there is a serious fork of the Ethereum chain, different validators behaving honestly may see different events at the same event nonce and be slashed through no fault of their own. Widespread unfair slashing would be very disruptive to the social structure of the Injective Chain. Maybe PEGGYSLASH-04 is not necessary at all: The real utility of this slashing condition is to make it so that, if >2/3 of the validators form a cartel to all submit a fake event at a certain nonce, some number of them can defect from the cartel and submit the real event at that nonce. If there are enough defecting cartel members that the real event becomes observed, then the remaining cartel members will be slashed by this condition. However, this would require >1/2 of the cartel members to defect in most conditions. If not enough of the cartel defects, then neither event will be observed, and the Ethereum oracle will just halt. This is a much more likely scenario than one in which PEGGYSLASH-04 is actually triggered. Also, PEGGYSLASH-04 will be triggered against the honest validators in the case of a successful cartel. This could act to make it easier for a forming cartel to threaten validators who do not want to join. [​](https://docs.injective.network/developers-native/injective/peggy/05_slashing#peggyslash-05-failure-to-submit-eth-oracle-claims-disabled-for-now) PEGGYSLASH-05: Failure to submit Eth oracle claims (Disabled for now) ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- This is similar to PEGGYSLASH-04, but it is triggered against validators who do not submit an oracle claim that has been observed. In contrast to PEGGYSLASH-04, PEGGYSLASH-05 is intended to punish validators who stop participating in the oracle completely. **Implementation considerations** Unfortunately, PEGGYSLASH-05 has the same downsides as PEGGYSLASH-04 in that it ties the correct operation of the Injective Chain to the Ethereum chain. Also, it likely does not incentivize much in the way of correct behavior. To avoid triggering PEGGYSLASH-05, a validator simply needs to copy claims which are close to becoming observed. This copying of claims could be prevented by a commit-reveal scheme, but it would still be easy for a “lazy validator” to simply use a public Ethereum full node or block explorer, with similar effects on security. Therefore, the real usefulness of PEGGYSLASH-05 is likely minimal PEGGYSLASH-05 also introduces significant risks. Mostly around forks on the Ethereum chain. For example recently OpenEthereum failed to properly handle the Berlin hardfork, the resulting node ‘failure’ was totally undetectable to automated tools. It didn’t crash so there was no restart to perform, blocks where still being produced although extremely slowly. If this had occurred while Peggy was running with PEGGYSLASH-05 active it would have caused those validators to be removed from the set. Possibly resulting in a very chaotic moment for the chain as dozens of validators where removed for little to no fault of their own. Without PEGGYSLASH-04 and PEGGYSLASH-05, the Ethereum event oracle only continues to function if >2/3 of the validators voluntarily submit correct claims. Although the arguments against PEGGYSLASH-04 and PEGGYSLASH-05 are convincing, we must decide whether we are comfortable with this fact. Alternatively we must be comfortable with the Injective Chain potentially halting entirely due to Ethereum generated factors. [Messages](https://docs.injective.network/developers-native/injective/peggy/04_messages) [End-Block](https://docs.injective.network/developers-native/injective/peggy/06_end_block) Ctrl+I Assistant Responses are generated using AI and may contain mistakes. --- # Events - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy/07_events#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... Ctrl KAsk AI Search... Navigation Peggy Events On this page * [Events](https://docs.injective.network/developers-native/injective/peggy/07_events#events) * [EndBlocker](https://docs.injective.network/developers-native/injective/peggy/07_events#endblocker) * [EventAttestationObserved](https://docs.injective.network/developers-native/injective/peggy/07_events#eventattestationobserved) * [EventValidatorSlash](https://docs.injective.network/developers-native/injective/peggy/07_events#eventvalidatorslash) * [Handler](https://docs.injective.network/developers-native/injective/peggy/07_events#handler) * [EventSetOrchestratorAddresses](https://docs.injective.network/developers-native/injective/peggy/07_events#eventsetorchestratoraddresses) * [EventSendToEth](https://docs.injective.network/developers-native/injective/peggy/07_events#eventsendtoeth) * [EventBridgeWithdrawCanceled](https://docs.injective.network/developers-native/injective/peggy/07_events#eventbridgewithdrawcanceled) * [EventOutgoingBatch](https://docs.injective.network/developers-native/injective/peggy/07_events#eventoutgoingbatch) * [EventOutgoingBatchCanceled](https://docs.injective.network/developers-native/injective/peggy/07_events#eventoutgoingbatchcanceled) * [EventValsetConfirm](https://docs.injective.network/developers-native/injective/peggy/07_events#eventvalsetconfirm) * [EventConfirmBatch](https://docs.injective.network/developers-native/injective/peggy/07_events#eventconfirmbatch) * [EventDepositClaim](https://docs.injective.network/developers-native/injective/peggy/07_events#eventdepositclaim) * [EventWithdrawClaim](https://docs.injective.network/developers-native/injective/peggy/07_events#eventwithdrawclaim) * [EventERC20DeployedClaim](https://docs.injective.network/developers-native/injective/peggy/07_events#eventerc20deployedclaim) * [EventValsetUpdateClaim](https://docs.injective.network/developers-native/injective/peggy/07_events#eventvalsetupdateclaim) [​](https://docs.injective.network/developers-native/injective/peggy/07_events#events) Events ================================================================================================ The peggy module emits the following events: [​](https://docs.injective.network/developers-native/injective/peggy/07_events#endblocker) EndBlocker -------------------------------------------------------------------------------------------------------- ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventattestationobserved) EventAttestationObserved | Type | Attribute Key | Attribute Value | | --- | --- | --- | | int32 | attestation\_type | `{attestation_type}` | | string | bridge\_contract | `{bridge_contract_address}` | | uint64 | bridge\_chain\_id | `{bridge_chain_id}` | | \[\]byte | attestation\_id | `{attestation_id}` | | uint64 | nonce | `{event_nonce}` | ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventvalidatorslash) EventValidatorSlash | Type | Attribute Key | Attribute Value | | --- | --- | --- | | string | reason | `{reason_for_slashing}` | | int64 | power | `{validator_power}` | | string | consensus\_address | `{consensus_addr}` | | string | operator\_address | `{operator_addr}` | | string | moniker | `{validator_moniker}` | [​](https://docs.injective.network/developers-native/injective/peggy/07_events#handler) Handler -------------------------------------------------------------------------------------------------- ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventsetorchestratoraddresses) EventSetOrchestratorAddresses | Type | Attribute Key | Attribute Value | | --- | --- | --- | | string | validator\_address | `{validator_addr}` | | string | orchestrator\_address | `{orchestrator_addr}` | | string | operator\_eth\_address | `{eth_addr}` | ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventsendtoeth) EventSendToEth | Type | Attribute Key | Attribute Value | | --- | --- | --- | | message | outgoing\_tx\_id | `{tx_id}` | | string | sender | `{sender_addr}` | | string | receiver | `{dest_addr}` | | sdk.Coin | amount | `{token_amount}` | | sdk.Coin | bridge\_fee | `{token_amount}` | ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventbridgewithdrawcanceled) EventBridgeWithdrawCanceled | Type | Attribute Key | Attribute Value | | --- | --- | --- | | withdrawal\_cancelled | bridge\_contract | `{bridge_contract}` | | withdrawal\_cancelled | bridge\_chain\_id | `{bridge_chain_id}` | ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventoutgoingbatch) EventOutgoingBatch | Type | Attribute Key | Attribute Value | | --- | --- | --- | | string | denom | `{token_denom}` | | string | orchestrator\_address | `{orch_addr}` | | uint64 | batch\_nonce | `{batch_nonce}` | | uint64 | batch\_timeout | `{block_height}` | | \[\]uint64 | batch\_tx\_ids | `{ids}` | ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventoutgoingbatchcanceled) EventOutgoingBatchCanceled | Type | Attribute Key | Attribute Value | | --- | --- | --- | | string | bridge\_contract | `{bridge_contract}` | | uint64 | bridge\_chain\_id | `{bridge_chain_id}` | | uint64 | batch\_id | `{id}` | | uint64 | nonce | `{nonce}` | ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventvalsetconfirm) EventValsetConfirm | Type | Attribute Key | Attribute Value | | --- | --- | --- | | uint64 | valset\_nonce | `{nonce}` | | string | orchestrator\_address | `{prch_addr}` | ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventconfirmbatch) EventConfirmBatch | Type | Attribute Key | Attribute Value | | --- | --- | --- | | uint64 | batch\_nonce | `{nonce}` | | string | orchestrator\_address | `{orch_addr}` | ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventdepositclaim) EventDepositClaim | Type | Attribute Key | Attribute Value | | --- | --- | --- | | uint64 | event\_nonce | `{event_nonce}` | | uint64 | event\_height | `{event_height}` | | \[\]byte | attestation\_id | `{attestation_key}` | | string | ethereum\_sender | `{sender_addr}` | | string | cosmos\_receiver | `{receiver_addr}` | | string | token\_contract | `{contract_addr}` | | sdk.Int | amount | `{token_amount}` | | string | orchestrator\_address | `{orch_addr}` | | string | data | `{custom_data}` | ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventwithdrawclaim) EventWithdrawClaim | Type | Attribute Key | Attribute Value | | --- | --- | --- | | uint64 | event\_nonce | `{event_nonce}` | | uint64 | event\_height | `{event_height}` | | \[\]byte | attestation\_id | `{attestation_key}` | | uint64 | batch\_nonce | `{batch_nonce}` | | string | token\_contract | `{contract_addr}` | | string | orchestrator\_address | `{orch_addr}` | ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventerc20deployedclaim) EventERC20DeployedClaim | Type | Attribute Key | Attribute Value | | --- | --- | --- | | uint64 | event\_nonce | `{event_nonce}` | | uint64 | event\_height | `{event_height}` | | \[\]byte | attestation\_id | `{attestation_key}` | | string | cosmos\_denom | `{token_denom}` | | string | token\_contract | `{token_conntract_addr}` | | string | name | `{token_name}` | | string | symbol | `{token_symbol}` | | uint64 | decimals | `{token_decimals}` | | string | orchestrator\_address | `{orch_addr}` | ### [​](https://docs.injective.network/developers-native/injective/peggy/07_events#eventvalsetupdateclaim) EventValsetUpdateClaim | Type | Attribute Key | Attribute Value | | --- | --- | --- | | uint64 | event\_nonce | `{event_nonce}` | | uint64 | event\_height | `{event_height}` | | \[\]byte | attestation\_id | `{attestation_key}` | | uint64 | valset\_nonce | `{valset_nonce}` | | \[\]\*BridgeValidator | valset\_members | `{array_of_validators}` | | sdk.Int | reward\_amount | `{amount}` | | string | reward\_token | `{contract_addr}` | | string | orchestrator\_address | `{orch_addr}` | [End-Block](https://docs.injective.network/developers-native/injective/peggy/06_end_block) [Parameters](https://docs.injective.network/developers-native/injective/peggy/08_params) Ctrl+I Assistant Responses are generated using AI and may contain mistakes. --- # Relay Semantics - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... Ctrl KAsk AI Search... Navigation Peggy Relay Semantics On this page * [Relay Semantics](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#relay-semantics) * [Semantics for Validator set update relaying](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#semantics-for-validator-set-update-relaying) * [Sorting and Ordering of the Validator set and signatures](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#sorting-and-ordering-of-the-validator-set-and-signatures) * [Deciding what Validator set to relay](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#deciding-what-validator-set-to-relay) * [Semantics for transaction batch relaying](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#semantics-for-transaction-batch-relaying) * [Deciding what batch to relay](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#deciding-what-batch-to-relay) [​](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#relay-semantics) Relay Semantics =========================================================================================================================== This document is designed to assist developers in implementing alternate Peggy relayers. The two major components of the Orchestrator which interact with Ethereum. The Peggy bridge has been designed for increased efficiency, not for ease of use. This means there are many implicit requirements of these external binaries which this document does it’s best to make explicit. The Peggy `orchestrator` combines three distinct roles that need to be performed by external binaries in the Peggy bridge. This document highlights the requirements of the `relayer` which is one of those roles included in the `orchestrator`. [​](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#semantics-for-validator-set-update-relaying) Semantics for Validator set update relaying ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#sorting-and-ordering-of-the-validator-set-and-signatures) Sorting and Ordering of the Validator set and signatures When updating the validator set in the Peggy contract you must provide a copy of the old validator set. This _MUST_ only be taken from the last ValsetUpdated event on the Ethereum chain. Providing the old validator set is part of a storage optimization, instead of storing the entire validator set in Ethereum storage it is instead provided by each caller and stored in the much cheaper Ethereum event queue. No sorting of any kind is performed in the Peggy contract, meaning the list of validators and their new signatures must be submitted in exactly the same order as the last call. For the purpose of normal operation this requirement can be shortened to ‘sort the validators by descending power, and by Eth address bytes where power is equal’. Since the peggy module produces the validator sets they should always come in order. It is not possible for the relayer to change this order since it is part of the signature. But a change in this sorting method on the Peggy module side would halt valset updates and essentially decouple the bridge unless your implementation is smart enough to take a look at the last submitted order rather than blindly following sorting. ### [​](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#deciding-what-validator-set-to-relay) Deciding what Validator set to relay The Injective Chain simply produces a stream of validator sets, it does not make any judgement on how they are relayed. It’s up to the relayer implementation to determine how to optimize the gas costs of this relaying operation. For example lets say we had validator sets `A, B, C, and D` each is created when there is a 5% power difference between the last Peggy validator set snapshot in the store and the currently active validator set. 5% is an arbitrary constant. The specific value chosen here is a tradeoff made by the chain between how up to date the Ethereum validator set is and the cost to keep it updated. The higher this value is the lower the portion of the voting validator set is needed to highjack the bridge in the worst case. If we made a new validator set update every block 66% would need to collude, the 5% change threshold means 61% of the total voting power colluding in a given validator set may be able to steal the funds in the bridge. Copy Ask AI A -> B -> C -> D 5% 10% 15% The relayer should iterate over the event history for the Peggy Ethereum contract, it will determine that validator set A is currently in the Peggy bridge. It can choose to either relay validator sets B, C and then D or simply submit validator set D. Provided all validators have signed D it has more than 66% voting power and can pass on it’s own. Without paying potentially several hundred dollars more in Ethereum to relay the intermediate sets. Performing this check locally somehow, before submitting transactions, is essential to a cost effective relayer implementation. You can either use a local Ethereum signing implementation and sum the powers and signatures yourself, or you can simply use the `eth_call()` Ethereum RPC to simulate the call on your Ethereum node. Note that `eth_call()` often has funny gotchas. All calls fail on Geth based implementations if you don’t have any Ethereum to pay for gas, while on Parity based implementations your gas inputs are mostly ignored and an accurate gas usage is returned. [​](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#semantics-for-transaction-batch-relaying) Semantics for transaction batch relaying ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- In order to submit a transaction batch you also need to submit the last set of validators and their staking powers. This is to facilitate the same storage optimization mentioned there. ### [​](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics#deciding-what-batch-to-relay) Deciding what batch to relay Making a decision about which batch to relay is very different from deciding which validator set to relay. Batch relaying is primarily motivated by fees, not by a desire to maintain the integrity of the bridge. So the decision mostly comes down to fee computation, this is further complicated by the concept of ‘batch requests’. Which is an unpermissioned transaction that requests the Peggy module generate a new batch for a specific token type. Batch requests are designed to allow the user to withdraw their tokens from the send to Ethereum tx pool at any time up until a relayer shows interest in actually relaying them. While transactions are in the pool there’s no risk of a double spend if the user is allowed to withdraw them by sending a MsgCancelSendToEth. Once the transaction enters a batch due to a ‘request batch’ that is no longer the case and the users funds must remain locked until the Oracle informs the Peggy module that the batch containing the users tokens has become somehow invalid to submit or has been executed on Ethereum. A relayer uses the query endpoint `BatchFees` to iterate over the send to Eth tx pool for each token type, the relayer can then observe the price for the ERC-20 tokens being relayed on a dex and compute the gas cost of executing the batch (via `eth_call()`) as well as the gas cost of liquidating the earnings on a dex if desired. Once a relayer determines that a batch is good and profitable it can send a `MsgRequestBatch` and the batch will be created for the relayer to relay. There are also existing batches, which the relayer should also judge for profitability and make an attempt at relaying using much the same method. [Parameters](https://docs.injective.network/developers-native/injective/peggy/08_params) [Future Improvements](https://docs.injective.network/developers-native/injective/peggy/10_future_improvements) Ctrl+I Assistant Responses are generated using AI and may contain mistakes. --- # Future Improvements - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy/10_future_improvements#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... Ctrl KAsk AI Search... Navigation Peggy Future Improvements On this page * [Future Improvements](https://docs.injective.network/developers-native/injective/peggy/10_future_improvements#future-improvements) * [Native Ethereum Signing](https://docs.injective.network/developers-native/injective/peggy/10_future_improvements#native-ethereum-signing) * [Improved Validator Incentives](https://docs.injective.network/developers-native/injective/peggy/10_future_improvements#improved-validator-incentives) [​](https://docs.injective.network/developers-native/injective/peggy/10_future_improvements#future-improvements) Future Improvements ======================================================================================================================================= ### [​](https://docs.injective.network/developers-native/injective/peggy/10_future_improvements#native-ethereum-signing) Native Ethereum Signing Validators run a required `Eth Signer` in the peggo orchestrator because we can not yet insert this sort of simple signature logic into Cosmos SDK based chains without significant modification to Tendermint. This may be possible in the future with [modifications to Tendermint](https://github.com/tendermint/tendermint/issues/6066) . It should be noted that both [PEGGYSLASH-02](https://docs.injective.network/developers-native/injective/peggy/05_slashing) and [PEGGYSLASH-03](https://docs.injective.network/developers-native/injective/peggy/05_slashing) could be eliminated with no loss of security if it where possible to perform the Ethereum signatures inside the consensus code. This is a pretty limited feature addition to Tendermint that would make Peggy far less prone to slashing. ### [​](https://docs.injective.network/developers-native/injective/peggy/10_future_improvements#improved-validator-incentives) Improved Validator Incentives Currently validators in Peggy have only one carrot - the extra activity brought to the chain by a functioning bridge. There are on the other hand a lot of negative incentives (sticks) that the validators must watch out for. These are outlined in the [slashing spec](https://docs.injective.network/developers-native/injective/peggy/05_slashing) . One negative incentive that is not covered under slashing is the cost of submitting oracle submissions and signatures. Currently these operations are not incentivized, but still cost the validators fees to submit. This isn’t a severe issue considering the relatively cheap transaction fees on the Injective Chain currently, but of course is an important factor to consider as transaction fees rise. Some positive incentives for correctly participating in the operation of the bridge should be under consideration. In addition to eliminating the fees for mandatory submissions. [Relay Semantics](https://docs.injective.network/developers-native/injective/peggy/09_relay_semantics) [Error Codes](https://docs.injective.network/developers-native/injective/peggy/99_errors) Ctrl+I Assistant Responses are generated using AI and may contain mistakes. --- # Error Codes - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy/99_errors#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... Ctrl KAsk AI Search... Navigation Peggy Error Codes This document lists the error codes used in the module. | Module | Error Code | description | | --- | --- | --- | | peggy | 1 | internal | | peggy | 2 | duplicate | | peggy | 3 | invalid | | peggy | 4 | timeout | | peggy | 5 | unknown | | peggy | 6 | empty | | peggy | 7 | outdated | | peggy | 8 | unsupported | | peggy | 9 | non contiguous event nonce | | peggy | 10 | no unbatched txs found | | peggy | 11 | can not set orchestrator addresses more than once | | peggy | 12 | supply cannot exceed max ERC20 value | | peggy | 13 | invalid ethereum sender on claim | | peggy | 14 | invalid ethereum destination | | peggy | 15 | missing previous claim for validator | [Future Improvements](https://docs.injective.network/developers-native/injective/peggy/10_future_improvements) [Permissions](https://docs.injective.network/developers-native/injective/permissions) Ctrl+I Assistant Responses are generated using AI and may contain mistakes. --- # Peggy - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... Ctrl KAsk AI Search... Navigation Peggy Peggy On this page * [Abstract](https://docs.injective.network/developers-native/injective/peggy#abstract) * [Contents](https://docs.injective.network/developers-native/injective/peggy#contents) * [Components](https://docs.injective.network/developers-native/injective/peggy#components) * [Peggo Functionalities](https://docs.injective.network/developers-native/injective/peggy#peggo-functionalities) [​](https://docs.injective.network/developers-native/injective/peggy#abstract) Abstract ------------------------------------------------------------------------------------------ The peggy module enables the Injective Chain to support a trustless, on-chain bidirectional ERC-20 token bridge to Ethereum. In this system, holders of ERC-20 tokens on Ethereum can convert their ERC-20 tokens to Cosmos-native coins on the Injective Chain and vice-versa. This decentralized bridge is secured and operated by the validators of the Injective Chain. [​](https://docs.injective.network/developers-native/injective/peggy#contents) Contents ------------------------------------------------------------------------------------------ 1. [Definitions](https://docs.injective.network/developers-native/injective/peggy/01_definitions) 2. [Workflow](https://docs.injective.network/developers-native/injective/peggy/02_workflow) 3. [State](https://docs.injective.network/developers-native/injective/peggy/03_state) 4. [Messages](https://docs.injective.network/developers-native/injective/peggy/04_messages) 5. [Slashing](https://docs.injective.network/developers-native/injective/peggy/05_slashing) 6. [End-Block](https://docs.injective.network/developers-native/injective/peggy/06_end_block) 7. [Events](https://docs.injective.network/developers-native/injective/peggy/07_events) 8. [Parameters](https://docs.injective.network/developers-native/injective/peggy/08_params) ### [​](https://docs.injective.network/developers-native/injective/peggy#components) Components 1. **[Peggy](https://etherscan.io/address/0xF955C57f9EA9Dc8781965FEaE0b6A2acE2BAD6f3) smart contract on Ethereum** 2. **Peggy module on the Injective Chain** 3. **[Peggo](https://github.com/InjectiveLabs/peggo) (off-chain relayer aka orchestrator)** * **Oracle** (Observes events of Peggy contract and send claims to the Peggy module) * **EthSigner** (Signs Valset and Batch confirmations to the Peggy module) * **Batch Requester** (Sends batch token withdrawal requests to the Peggy module) * **Valset Relayer** (Submits Validator set updates to the Peggy contract) * **Batch Relayer** (Submits batches of token withdrawals to the Peggy contract) In addition to running an `injectived` node to sign blocks, Injective Chain validators must also run the `peggo` orchestrator to relay data from the Peggy smart contract on Ethereum and the Peggy module on the Injective Chain. ### [​](https://docs.injective.network/developers-native/injective/peggy#peggo-functionalities) Peggo Functionalities 1. **Maintaining an up-to-date checkpoint of the Injective Chain validator set on Ethereum** 2. **Transferring ERC-20 tokens from Ethereum to the Injective Chain** 3. **Transferring pegged tokens from the Injective Chain to Ethereum** [Error Codes](https://docs.injective.network/developers-native/injective/oracle/99_errors) [Definitions](https://docs.injective.network/developers-native/injective/peggy/01_definitions) Ctrl+I Assistant Responses are generated using AI and may contain mistakes. --- # Peggy - Injective Docs [Skip to main content](https://docs.injective.network/developers-native/injective/peggy/index#content-area) [Injective Docs home page![light logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)![dark logo](https://mintcdn.com/injectivelabs/QlZaYS7qaDAyLKCM/img/injective-logo-192x192.png?fit=max&auto=format&n=QlZaYS7qaDAyLKCM&q=85&s=07e0ad67fc7a332d74f7d418e2727dbd)](https://docs.injective.network/) ![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg) English Search... ⌘KAsk AI Search... Navigation Peggy Peggy On this page * [Abstract](https://docs.injective.network/developers-native/injective/peggy/index#abstract) * [Contents](https://docs.injective.network/developers-native/injective/peggy/index#contents) * [Components](https://docs.injective.network/developers-native/injective/peggy/index#components) * [Peggo Functionalities](https://docs.injective.network/developers-native/injective/peggy/index#peggo-functionalities) [​](https://docs.injective.network/developers-native/injective/peggy/index#abstract) Abstract ------------------------------------------------------------------------------------------------ The peggy module enables the Injective Chain to support a trustless, on-chain bidirectional ERC-20 token bridge to Ethereum. In this system, holders of ERC-20 tokens on Ethereum can convert their ERC-20 tokens to Cosmos-native coins on the Injective Chain and vice-versa. This decentralized bridge is secured and operated by the validators of the Injective Chain. [​](https://docs.injective.network/developers-native/injective/peggy/index#contents) Contents ------------------------------------------------------------------------------------------------ 1. [Definitions](https://docs.injective.network/developers-native/injective/peggy/01_definitions) 2. [Workflow](https://docs.injective.network/developers-native/injective/peggy/02_workflow) 3. [State](https://docs.injective.network/developers-native/injective/peggy/03_state) 4. [Messages](https://docs.injective.network/developers-native/injective/peggy/04_messages) 5. [Slashing](https://docs.injective.network/developers-native/injective/peggy/05_slashing) 6. [End-Block](https://docs.injective.network/developers-native/injective/peggy/06_end_block) 7. [Events](https://docs.injective.network/developers-native/injective/peggy/07_events) 8. [Parameters](https://docs.injective.network/developers-native/injective/peggy/08_params) ### [​](https://docs.injective.network/developers-native/injective/peggy/index#components) Components 1. **[Peggy](https://etherscan.io/address/0xF955C57f9EA9Dc8781965FEaE0b6A2acE2BAD6f3) smart contract on Ethereum** 2. **Peggy module on the Injective Chain** 3. **[Peggo](https://github.com/InjectiveLabs/peggo) (off-chain relayer aka orchestrator)** * **Oracle** (Observes events of Peggy contract and send claims to the Peggy module) * **EthSigner** (Signs Valset and Batch confirmations to the Peggy module) * **Batch Requester** (Sends batch token withdrawal requests to the Peggy module) * **Valset Relayer** (Submits Validator set updates to the Peggy contract) * **Batch Relayer** (Submits batches of token withdrawals to the Peggy contract) In addition to running an `injectived` node to sign blocks, Injective Chain validators must also run the `peggo` orchestrator to relay data from the Peggy smart contract on Ethereum and the Peggy module on the Injective Chain. ### [​](https://docs.injective.network/developers-native/injective/peggy/index#peggo-functionalities) Peggo Functionalities 1. **Maintaining an up-to-date checkpoint of the Injective Chain validator set on Ethereum** 2. **Transferring ERC-20 tokens from Ethereum to the Injective Chain** 3. **Transferring pegged tokens from the Injective Chain to Ethereum** [Error Codes](https://docs.injective.network/developers-native/injective/oracle/99_errors) [Definitions](https://docs.injective.network/developers-native/injective/peggy/01_definitions) ⌘I Assistant Responses are generated using AI and may contain mistakes. ---