# Signet - Full Documentation > Signet is a pragmatic Ethereum rollup with sustainable economic incentives This file contains the complete documentation for Signet. For a curated overview with links, see /llms.txt Last updated: 2025-12-12 ================================================================================ ## DOCUMENTATION-------------------------------------------------------------------------------- ### Bug Bounty URL: https://signet.sh/docs/more-info/security/bug-bounty/ Description: Information around Signet's bug bounty program. -------------------------------------------------------------------------------- # Bug Bounty Security is a first-class priority. This program rewards responsibly disclosed vulnerabilities across the Signet stack. Help us find and fix vulnerabilities across the Signet stack, from smart contracts to infrastructure to documentation. {{< callout type="info" title="Program Summary" >}} Rewards range from $10k to $50k based on [severity tier](http://localhost:1313/docs/more-info/security/bug-bounty/#severity-tiers). $50k quarterly budget for medium and high issues. Uncapped rewards for critical issues. - **high** or **critical**: immediately [report a vulnerability]({{< relref "/docs/more-info/security/report/" >}}) - **medium** or **low**: report on the appropriate Github repository {{< /callout >}} ## Scope ### Smart Contracts - [Passage], [Rollup Passage], [Transactor], [Host Orders], [Rollup Orders], [Zenith], [Permit2] - **Impact**: asset loss, unauthorized actions, state forgery, unexpected EVM behavior ### Services - [builder], [signet] - **Impact**: finality forgery, censorship, authentication bypass, data integrity failure, key leakage, asymmetric DDoS, cryptographic misuse ### Libraries - [trevm], [ajj], [signet-sdk], [bin-base], [node-components], [signet-infra-components] - **Impact**: forgery, data integrity, parsing bugs, cryptographic misuse ### Infrastructure - CI/CD pipelines, containers, signing services, secrets - **Impact**: remote code execution, privilege escalation, key extraction ### Dashboards & Faucets - Block explorer, [Pecorino Faucet] - **Impact**: data exfiltration ### Docs & Config - [Documentation]({{< relref "docs/build-on-signet" >}}), [Github] - **Impact**: misconfigurations or specs that materially change security posture {{< callout type="warning" title="Out of Scope" >}} Third-party services, phishing/social engineering/physical attacks, volumetric DoS, low-impact issues (missing headers, version strings, unexploitable CVEs). [Pecorino Testnet]({{< relref "docs/build-on-signet/pecorino/" >}}) can be used for PoCs but is **not a target**. {{< /callout >}} ## Rules of Engagement - Test with your own accounts and funds only - No destructive testing, safe PoCs only - Coordinated disclosure, give us time to fix before publishing - Respect rate limits (Pecorino L1 funds available on request) ## Safe Harbor Good-faith security research on in-scope assets is authorized. Follow this policy and we won't pursue legal action under anti-hacking or anti-circumvention laws. {{< callout type="danger" >}} Protection does not apply to actions that put mainnet users or funds at risk. {{}} ## Rewards & Budget ### Severity Tiers **Critical: up to $50,000** - Drain or freeze L1/L2 funds - Finalize invalid state, forge state or finality - Extract or compromise production keys **High: up to $20,000** - Censorship routes, indefinite censorship or censorship-escape bypass - Authentication bypass - Unauthorized privileged action - Message replay or forgery under realistic conditions **Medium: up to $10,000** - Griefing with measurable loss (stuck funds, fee theft) - Replay/ordering abuse - Sensitive info disclosure enabling escalation - Asymmetric DoS **Low: no payment** - Non-trivial best-practice gaps with theoretical impact - Noisy but contained DoS requiring sustained traffic ### Budget & Terms - **Quarterly budget:** $50,000 for Medium and High (Critical has no cap) - **Duplicates:** First valid report wins; related issues may be consolidated - **Quality bar:** Working PoC or clear exploit path required for Medium+ severity - **Payment:** Net-30 after validation (critical may be paid post-mitigation). USDC (Ethereum Mainnet) or USD. Tax documents may be required. ## How to Report Fill out the [report template]({{< relref "/docs/more-info/security/report/" >}}) and submit via: - **Email (high/critical):** - **GitHub issue (medium/low):** File on the relevant repo at [Github] Test funds available via [Pecorino faucet]. ## Triage & SLAs - **Acknowledgement:** within 1 day - **Initial triage:** within 4 days - **Fix targets:** Critical ≤14 days, High ≤30 days, Medium-Low best effort - **Disclosure:** Coordinated with reporter, case-by-case - **Updates:** At meaningful milestones ## Legal & Compliance - No NDA required. You retain ownership of your report - Do not access personal data or non-public keys. If you do: stop, report, delete - Do not retain exploit data beyond what's required for the report - Rewards may be subject to sanctions/export rules - Terms may evolve - This is not legal advice ## Publication & Recognition - Addition to the [Hall of Fame] with tiers by severity - Optional researcher write-ups may be published after fixes, with attribution ## Get In Touch Feedback? Reach us on [@signetsh] or [@signetsh]: https://x.com/signetsh [ajj]: https://github.com/init4tech/ajj [bin-base]: https://github.com/init4tech/bin-base [builder]: https://github.com/init4tech/builder [github]: https://github.com/init4tech/ [hall of fame]: /docs/more-info/security/hall-of-fame/ [host explorer]: https://explorer-host.pecorino.signet.sh/ [host orders]: https://github.com/init4tech/zenith/blob/main/src/orders/HostOrders.sol [node-components]: https://github.com/init4tech/node-components [passage]: https://github.com/init4tech/zenith/blob/main/src/passage/Passage.sol [pecorino faucet]: https://faucet.pecorino.signet.sh/ [permit2]: https://github.com/init4tech/zenith/blob/main/src/passage/PassagePermit2.sol [rollup explorer]: https://explorer.pecorino.signet.sh/ [rollup orders]: https://github.com/init4tech/zenith/blob/main/src/orders/RollupOrders.sol [rollup passage]: https://github.com/init4tech/zenith/blob/main/src/passage/RollupPassage.sol [signet]: https://github.com/init4tech/signet [signet-infra-components]: https://github.com/init4tech/signet-infra-components [signet-sdk]: https://github.com/init4tech/signet-sdk [transactor]: https://github.com/init4tech/zenith/blob/main/src/Transactor.sol [trevm]: https://github.com/init4tech/trevm [zenith]: https://github.com/init4tech/zenith/blob/main/src/Zenith.sol -------------------------------------------------------------------------------- ### FAQ URL: https://signet.sh/docs/more-info/faq/ Description: Frequently asked questions about Signet -------------------------------------------------------------------------------- # FAQ {{< details title="What is Signet?" >}} Signet is a pragmatic Ethereum rollup designed to offer sustainable economic incentives. It aims to modernize and streamline rollups by simplifying their architecture and focusing on efficiency. {{< /details >}} {{< details title="How does Signet differ from traditional rollups?" >}} Signet differs in several key ways: - It doesn't use proving systems or state roots, which reduces computational overhead. - It uses market-based cross-chain transfers instead of complex bridging mechanisms. - It replaces block auctions and centralized rollup sequencing with a controlled block inclusion mechanism. - It introduces conditional transactions for secure, atomic cross-chain operations. {{< /details >}} {{< details title="How does Signet handle cross-chain transfers?" >}} Signet uses market-based mechanisms and conditional transactions for cross-chain transfers. This allows for secure, instant transfers between Ethereum and Signet without the need for lockup periods. See [Cross-chain Transfers]({{< relref "/docs/learn-about-signet/cross-chain-transfers/" >}}). {{< /details >}} {{< details title="Is Signet suitable for all use cases?" >}} While Signet offers significant benefits for most users, it may not be suitable for all situations. For example, it's not ideal for users who require light client functionality or certain types of cross-chain interactions that rely on cryptographic proofs. {{< /details >}} {{< details title="How does Signet ensure fair block production?" >}} Instead of using auctions, Signet uses a central sequencer that assigns block production rights in a round-robin style to block builders. This prevents domination by a small number of wealthy builders and promotes fair participation. {{< /details >}} {{< details title="What tokens are supported for bridging?" >}} Signet supports **ETH**, **USDC**, **USDT**, and **WBTC** for bridging between Ethereum and Signet. Custom assets may be created within Signet but cannot be bridged from Ethereum without coordination with the Signet team. See [Moving Assets to Signet]({{< relref "/docs/build-on-signet/ethereum-to-signet/passage/" >}}) for details. {{< /details >}} {{< details title="What is Pecorino?" >}} Pecorino is a private Ethereum testnet for rollup and application experimentation, available to the public for testing and validation. It includes RPC endpoints, faucet, explorer, and transaction cache infrastructure for development. See [Pecorino Quickstart]({{< relref "/docs/build-on-signet/pecorino/" >}}) for network configuration and contract addresses. {{< /details >}} {{< details title="How does Signet guarantee atomic cross-chain execution?" >}} Signet requires cross-chain transfers to be fully executed in the same block on both chains. If the transfer is not fully executed, the transaction is invalid and has no effect on Signet's state—as if the transaction never existed. See [Cross-chain Transfers]({{< relref "/docs/learn-about-signet/cross-chain-transfers/" >}}) for more details. {{< /details >}} {{< details title="Do I need to run my own Ethereum or Signet node?" >}} No. You can use public RPC endpoints. For Pecorino testnet, see the [Pecorino Quickstart]({{< relref "/docs/build-on-signet/pecorino/" >}}) for endpoints. For block builders, RPC access can be configured via environment variables—running your own nodes is optional infrastructure. See [Environment Variables]({{< relref "/docs/bb-3f7d9e2a/run-a-builder/environment-variables/" >}}) for builder configuration. {{< /details >}} {{< details title="What do block builders do in the Signet ecosystem?" >}} Block Builders collect user transactions, build blocks, and post those blocks to Ethereum. Some user transactions create swap orders. These orders may trade between Signet and Ethereum, or within Signet. Block builders can chose to fill any number of orders as part of constructing the block. {{< /details >}} -------------------------------------------------------------------------------- ### Getting started with Signet URL: https://signet.sh/docs/build-on-signet/getting-started/ -------------------------------------------------------------------------------- # Getting Started with Signet {{< callout type="info" >}}Already familiar with the Signet system contracts? [Check out the Pecorino quickstart!]({{< relref "./pecorino/" >}}){{< /callout >}} Signet is a reimagining of the EVM rollup stack, built on Ethereum. Signet offers features that other rollups can't, including: {{< branded-list >}} - Instant bridging of assets from Ethereum - Native support for Ethereum transactions - Full EVM compatibility - Instant cross-chain transactions with Ethereum {{< /branded-list >}} Signet is designed to be easy to use, easy to integrate with, and easy to build on. System actions are exposed as smart contracts, so developers can build on Signet using familiar tools and languages. ## Quickstart Resources - [Move assets to Signet instantly]({{< relref "./ethereum-to-signet/passage/" >}}) - [Make a Signet Transaction from Ethereum]({{< relref "./ethereum-to-signet/transactor/" >}}) - [Build on-chain Orders in Solidity]({{< relref "./signet-to-ethereum/on-chain-orders/" >}}) - [Build off-chain Orders with Rust]({{< relref "./signet-to-ethereum/rust-orders/" >}}) - [Explore the Pecorino testnet]({{< relref "./pecorino/" >}}) -------------------------------------------------------------------------------- ### Pecorino Quickstart URL: https://signet.sh/docs/build-on-signet/pecorino/ Description: How to get started on developing with Signet on the Pecorino test network. -------------------------------------------------------------------------------- # Pecorino Quickstart Pecorino is a private Ethereum testnet for rollup and application experimentation, available to the public for testing and validation. This page contains key contract addresses and RPC endpoints for developers looking to quickly set up and interact with the Pecorino network. These constants are also available to rust code via the [`signet-constants`](https://docs.rs/signet-constants/latest/signet_constants/) crate. If you need to test applications or software that interacts with both host and rollup chains, [please reach out](mailto:hello@init4.technology)! ## Network Configuration | Key | Value | | ------------------------------ | --------------------------------------- | | Host Chain ID | 3151908 | | Rollup Chain ID | 14174 | | Deploy Height | 366 | | Native Gas Token | USD | | RPC Endpoint | https://rpc.pecorino.signet.sh | | Faucet | https://faucet.pecorino.signet.sh | | Rollup Explorer | https://explorer.pecorino.signet.sh | | Host Explorer | https://explorer-host.pecorino.signet.sh| | Transaction Cache API Endpoint | https://transactions.pecorino.signet.sh | ## Host System Contracts | Contract | Address | | -------------- | ------------------------------------------ | | [Zenith] | {{< copycode-inline >}}0xf17E98baF73F7C78a42D73DF4064de5B7A20EcA6{{< /copycode-inline >}} | | [HostOrders] | {{< copycode-inline >}}0x0A4f505364De0Aa46c66b15aBae44eBa12ab0380{{< /copycode-inline >}} | | [Passage] | {{< copycode-inline >}}0x12585352AA1057443D6163B539EfD4487f023182{{< /copycode-inline >}} | | [Transactor] | {{< copycode-inline >}}0x3903279B59D3F5194053dA8d1f0C7081C8892Ce4{{< /copycode-inline >}} | ## Rollup System Contracts | Contract | Address | | --------------- | ------------------------------------------ | | [RollupOrders] | {{< copycode-inline >}}0x000000000000007369676e65742d6f7264657273{{< /copycode-inline >}} | | [RollupPassage] | {{< copycode-inline >}}0x0000000000007369676e65742d70617373616765{{< /copycode-inline >}} | | WETH | {{< copycode-inline >}}0x0000000000000000007369676e65742d77657468{{< /copycode-inline >}} | | WBTC | {{< copycode-inline >}}0x0000000000000000007369676e65742d77627463{{< /copycode-inline >}} | ## Rollup Utility Contracts | Contract | Address | | ----------------------------------- | ------------------------------------------ | | [WUSD (Wrapped Native) Asset] | {{< copycode-inline >}}0x0000000000000000007369676e65742d77757364{{< /copycode-inline >}} | | [Permit2] | {{< copycode-inline >}}0x000000000022D473030F116dDEE9F6B43aC78BA3{{< /copycode-inline >}} | | [Gnosis Safe Factory] | {{< copycode-inline >}}0x8ff5C1D5233CA055cD536b2b87294d17f9160801{{< /copycode-inline >}} | | [Gnosis SafeL2] | {{< copycode-inline >}}0x2f2965efaCFc64Fb85dF1902260eB25C0c996195{{< /copycode-inline >}} | | [Safe CompatibilityFallbackHandler] | {{< copycode-inline >}}0xe59838EB7f251489b50940BD640326215420B936{{< /copycode-inline >}} | | [Deterministic Deployer] | {{< copycode-inline >}}0x4e59b44847b379578588920cA78FbF26c0B4956C{{< /copycode-inline >}} | [Zenith]: https://github.com/init4tech/zenith/blob/main/src/Zenith.sol [HostOrders]: https://github.com/init4tech/zenith/blob/main/src/orders/HostOrders.sol [Passage]: https://github.com/init4tech/zenith/blob/main/src/passage/Passage.sol [RollupOrders]: https://github.com/init4tech/zenith/blob/main/src/orders/RollupOrders.sol [RollupPassage]: https://github.com/init4tech/zenith/blob/main/src/passage/RollupPassage.sol [Transactor]: https://github.com/init4tech/zenith/blob/main/src/Transactor.sol [Permit2]: https://docs.uniswap.org/contracts/permit2/overview [WUSD (Wrapped Native) Asset]: https://github.com/islishude/uniswapv2-solc0.8/blob/main/contracts/test/WETH9.sol [Gnosis Safe Factory]: https://github.com/safe-global/safe-smart-account/blob/main/contracts/proxies/SafeProxyFactory.sol [Gnosis SafeL2]: https://github.com/safe-global/safe-smart-account/blob/main/contracts/Safe.sol [Safe CompatibilityFallbackHandler]: https://github.com/safe-global/safe-smart-account/blob/main/contracts/handler/CompatibilityFallbackHandler.sol [Deterministic Deployer]: https://github.com/Arachnid/deterministic-deployment-proxy -------------------------------------------------------------------------------- ### Simplifying the Rollup URL: https://signet.sh/docs/learn-about-signet/simplifying-the-rollup/ Description: An introduction to Signet, init4, and the Signet ecosystem. -------------------------------------------------------------------------------- # Simplifying the Rollup Signet is a pragmatic Ethereum rollup with sustainable economic incentives. It offers a new set of ideas, aiming to radically modernize and streamline rollups. {{< branded-list >}} - No proving systems or state roots, drastically reducing computational overhead - Market-based cross-chain transfers for instant asset movement - Removes block auctions in favor of a controlled block inclusion mechanism - Introduces conditional transactions for secure, atomic cross-chain operations {{< /branded-list >}} Signet is built by [Init4](https://x.com/init4tech), a research collective building next-generation Ethereum. ## A Brief History of the Rollup Ethereum rollups are the intellectual descendants of a project called [Plasma](https://ethereum.org/en/developers/docs/scaling/plasma/). Plasmas were complex multi-layered chain systems that used intricate proofs to connect to Ethereum. The research community gradually abandoned Plasmas because their proving trade-offs turned out to be unsuitable to real applications. Around the time Plasma was falling out of favor, a transaction batching service for simple payments called [roll_up](https://github.com/barryWhiteHat/roll_up) was being developed. Plasma researchers co-opted the name _rollup_ and shifted their focus to the development of early rollups, while still focusing on the proving systems. Today, many more rollups have been created. All of these projects have carried forward the original Plasma architecture, placing a proving system at the center of the tech stack. Today rollups are mostly categorized by their proving system — zk or optimistic — but that doesn't have to be the case. ## Back to basics Ethereum rollups have always been complex. They have never had an era where they _weren't_ complex. They didn't start simple and evolve; they were born complex and stayed that way. Their core ideas have never been fundamentally challenged. **Signet's thesis is that the complexity isn't necessary.** > A rollup is an opt-in subset of another consensus, keeping a superset of state, via a custom state-transition function. — [Defining "rollup"](https://prestwich.substack.com/p/defining-rollup) ## Rollups are sandwiches Think of rollups as sandwiches. Current-generation rollups all have the same set of "mandatory ingredients" inherited from their common ancestry. To differentiate, they add more and more "toppings", resulting in increasingly massive sandwich-systems. Signet is the classic grilled cheese of rollups. Bread, butter, and cheese: simple, effective, and satisfying for most users. We're not saying complex rollups aren't for anyone, just that they're not for everyone. ## Signet is just a rollup We built Signet to be straightforward, fast, and affordable. - **Full EVM compatibility**: Deploy smart contracts, connect wallets, farm $YAMs. - **Simple deployment and ops**: Signet is a drop-in update to your existing Ethereum node. No more 4-node `docker-compose` setups to run a rollup. - **Massively higher gas limits**: Eliminating protocol and proving overhead frees up resources for users. -------------------------------------------------------------------------------- ### Working with Orders URL: https://signet.sh/docs/build-on-signet/signet-to-ethereum/orders/ Description: Move assets from Signet to Ethereum using Orders -------------------------------------------------------------------------------- # Working with Orders Signet Orders enable atomic, instant, cross-chain swaps between Signet and Ethereum. Orders specify assets in, assets out, and on what chain the assets out should be delivered. Orders can be created by smart contract execution via the [Orders Contract], or via an off-chain `SignedOrder` object. ## How Orders Work MEV Searchers (called Fillers) compete to fulfill each Order by providing the output tokens. Your input tokens are locked on Signet until a Filler completes the swap. **Orders are a form of direct interaction with the MEV ecosystem.** You can think of them as a way to express your intent to move assets across chains, while allowing the MEV market to find the best execution strategy. An Order has two main components: - **Inputs**: What you're providing on Signet - **Outputs**: The assets you want to receive, as well as the chain and address to which to deliver them. `Input` and `Output` structs are specified in the [`IOrders.sol`] interface. ## Implementation Paths Choose your implementation based on your stack: ### On-chain Orders in Solidity Build smart contracts that create, fill, or interact with Signet Orders on-chain. Perfect for: - Automated MEV capture - Flash loans across chains - Payment gating - Smart contract exits from Signet [Learn how to work with Solidity Orders]({{< relref "./on-chain-orders" >}}) ### Off-chain Orders in Rust Build applications that create and fill Signet Orders programmatically. Perfect for: - Market making bots - Order monitoring services - Cross-chain arbitrage - Custom filler strategies [Learn how to work with Rust Orders]({{< relref "./rust-orders/" >}}) ## Next Steps Start with the implementation path that matches your stack, or explore both to understand the full capabilities of Signet Orders. [Orders Contract]: https://github.com/init4tech/zenith/blob/main/src/orders/OrderOrigin.sol [`IOrders.sol`]: https://github.com/init4tech/zenith/blob/main/src/orders/IOrders.sol -------------------------------------------------------------------------------- ### EVM Behavior URL: https://signet.sh/docs/build-on-signet/evm-behavior/ Description: EVM modifications and differences between Signet and Mainnet EVM. -------------------------------------------------------------------------------- # EVM Behavior Signet is the most EVM-compatible rollup. This page describes the (very few) differences between Signet and Ethereum Mainnet EVM behavior. ## USD Native Asset The native asset on Signet is USD. USD has 18 decimals, like ETH on Ethereum Mainnet. See the [Passage]({{< relref "./ethereum-to-signet/passage/" >}}) contract for more information on how USD is minted. ## Inherited header values The following opcodes inherit the values of the Ethereum block: - `PREVRANDAO` — `block.difficulty` and `block.prevrandao` - `TIMESTAMP` — `block.timestamp` {{< callout type="info" >}}Signet blocks _always_ use the same timestamp as the current Ethereum block.{{< /callout >}} ## Disabled Opcodes The following opcodes are disabled in Signet: - `BLOBHASH` — EIP-4844 is not supported. - `BLOBBASEFEE` — EIP-4844 is not supported. ## Precompiles Signet supports the [same precompiles as ethereum], plus the following additional precompile: - secp256r1 signature verification as specified in [RIP-7212] at address `0x100`. ## Address Aliasing To conform to common rollup conventions, Signet uses address aliasing for L1-to-L2 messages. When a contract on L1 sends a message to Signet via the [`Transactor`] contract, the sender's address is modified by adding a constant offset to it. This ensures that contracts on Signet can distinguish between messages sent from L1 and those sent from the same address on the L2. The address aliasing offset is `0x1111000000000000000000000000000000001111`. Aliasing is performed by converting the address to a number, adding the offset, and then converting back to an address. Signet differs from other rollup behaviors in that the addresses of ephemeral contracts are NOT aliased. Signet treats ephemeral L1 contracts equivalently to EOAs. | Account Type | Address Aliased? | | ------------------- | ---------------- | | EOA | No | | EIP-7702 Delegation | No | | Ephemeral Contract | **No** | | Smart Contract | Yes | [same precompiles as ethereum]: https://www.evm.codes/precompiled [RIP-7212]: https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md [`Transactor`]: {{< relref "./ethereum-to-signet/transactor" >}} -------------------------------------------------------------------------------- ### Glossary URL: https://signet.sh/docs/more-info/glossary/ Description: Definitions of key terms and concepts in Signet -------------------------------------------------------------------------------- # Glossary {{< details title="Blind Signing" >}} Blind signing is a security feature where a party (in this case, the sequencer) signs a piece of information without knowing its full contents. It's like signing a sealed envelope without being able to see what's inside. Key points: 1. The signer only sees a hash (a unique digital fingerprint) of the content, not the actual content itself. 2. This prevents the signer from selectively censoring or manipulating the content based on what it contains. 3. It enhances privacy and reduces the potential for bias or censorship. In Signet's context: The sequencer blind signs blocks. It only sees the block's hash and the builder's identity, not the actual contents of the block. This ensures fair and unbiased block inclusion while preventing potential censorship. {{< /details >}} {{< details title="Block Builders" >}} Block builders are specialized participants in a blockchain network who assemble and propose new blocks to be added to the blockchain. They're like puzzle makers who gather and arrange transactions into a format that fits the blockchain's rules. Traditionally: 1. Block builders collect pending transactions from the network's mempool (a pool of unconfirmed transactions). 2. They organize these transactions in a way that maximizes their profit (through transaction fees) while adhering to the network's rules. 3. In some systems, block builders compete to have their blocks chosen by proposers or validators. 4. They often use sophisticated algorithms and infrastructure to optimize block composition. Signet takes a different approach to block building compared to traditional systems: 1. Instead of using auctions where wealthy builders can dominate, Signet uses a round-robin style system. 2. A central sequencer assigns block production rights to different block builders in turns. 3. This approach aims to prevent centralization and ensure fairer participation among block builders. 4. The sequencer uses blind signing (as we discussed earlier) to prevent censorship and ensure unbiased block inclusion. {{< /details >}} {{< details title="Conditional Transactions" >}} Conditional transactions are operations that only execute if certain predefined conditions are met. They're like "if-then" statements in programming, but for blockchain transactions. Key points: 1. The transaction is only processed and finalized if all specified conditions are satisfied. 2. If any condition is not met, the entire transaction is cancelled as if it never happened. 3. This feature enables more complex and secure interactions, especially between Signet and Ethereum. In Signet's context: Conditional transactions are used for cross-chain transfers. They ensure that the transfer is fully executed in the same block on both chains. If the conditions aren't met, the transaction is invalidated and has no effect on Signet's state. {{< /details >}} {{< details title="State Roots" >}} State roots are like a cryptographic snapshot of the entire state of a blockchain at a specific point in time. They serve as a compact way to represent and verify all the accounts, balances, and smart contract data on the blockchain without needing to store or process the entire history of transactions. To break it down further: 1. Think of the blockchain as a giant ledger or database. 2. This ledger contains information about every account, its balance, and all the data stored in smart contracts. 3. The state root is a single, unique hash (a fixed-length string of characters) that represents the entire contents of this ledger at a specific block. 4. Any change to any part of the ledger, no matter how small, will result in a completely different state root. {{< /details >}} {{< details title="Orders (Signet Orders)" >}} Atomic, instant, cross-chain swaps between Signet and Ethereum. Orders specify inputs (what you're providing on Signet) and outputs (the assets you want to receive, the chain, and address for delivery). Orders can be created on-chain via the [Orders Contract](https://github.com/init4tech/zenith/blob/main/src/orders/OrderOrigin.sol) or off-chain via SignedOrder objects. Cross-chain transfers must be fully executed in the same block on both chains; otherwise, the transaction is invalid and has no effect on Signet's state. See [Working with Orders]({{< relref "/docs/build-on-signet/signet-to-ethereum/orders/" >}}) for implementation details. {{< /details >}} {{< details title="Fillers" >}} MEV Searchers who compete to fulfill Orders by providing the output tokens. When a Filler provides the outputs specified in an Order, they receive the Order's inputs. See [How Orders Work]({{< relref "/docs/build-on-signet/signet-to-ethereum/orders/#how-orders-work" >}}) for more details. {{< /details >}} {{< details title="Bundles (Signet)" >}} Flashbots-style bundles of transactions wrapped with a `host_fills` field. Host fills must be atomically included with their corresponding rollup transactions. If a host fill is included without its corresponding rollup transaction, the bundle is considered invalid. Block builders must respect ordering (preserved), atomicity (all or nothing), and revertibility (no unexpected reverts) guarantees. See [Bundle Guarantees]({{< relref "/docs/bb-3f7d9e2a/customizing-a-builder/bundle-guarantees/" >}}) for details. {{< /details >}} {{< details title="Host Chain / Rollup Chain" >}} Terminology used in Signet configuration and APIs. Host Chain refers to Ethereum. Rollup Chain refers to Signet. On the Pecorino testnet, Host Chain ID is 3151908 and Rollup Chain ID is 14174. See [Pecorino Quickstart]({{< relref "/docs/build-on-signet/pecorino/" >}}) for network configuration. {{< /details >}} {{< details title="Sequencer" >}} Sequencers are special entities in rollup systems that are responsible for ordering and batching transactions. Think of a sequencer as a traffic controller for blockchain transactions. Most rollups use a single centralized Sequencer with near-total control over transaction ordering. Signet's sequencer doesn't actually order transactions. Instead, it delegates that to block builders, and then co-signs the blocks. 1. Round-robin assignment: Instead of using auctions, the sequencer assigns block production rights to different block builders in turns. 2. Blind signing: The sequencer only sees the block's hash and the builder's identity, not the actual contents of the block. This prevents selective censorship. 3. Simplicity: Signet's sequencer is designed to be simple, easy to maintain, and less prone to errors. {{< /details >}} -------------------------------------------------------------------------------- ### Moving Assets to Signet URL: https://signet.sh/docs/build-on-signet/ethereum-to-signet/passage/ Description: Move ETH and ERC-20 tokens from Ethereum to Signet -------------------------------------------------------------------------------- # Moving Assets to Signet {{< callout type="info" title="Supported Assets" >}} Signet currently supports bridging **ETH**, **USDC**, **USDT**, and **WBTC** from Ethereum. Custom assets can be created on Signet but cannot be bridged from Ethereum. Contact the Signet team to add support for additional assets. {{< /callout >}} The [Passage](https://github.com/init4tech/zenith/blob/main/src/passage/Passage.sol) contract helps move assets from Ethereum to Signet instantly. Signet nodes listen for `Passage` events, and mint tokens on Signet in the **same block**. Consult the [Pecorino Quickstart]({{< relref "../pecorino/" >}}) guide for contract addresses and RPC endpoints. ## Setup **Solidity (ABI):** Download the Passage ABI from [Passage ABI] ```bash curl -O https://signet.sh/docs/abis/Passage.abi.json ``` **Solidity (Source):** The Passage contract is open source ```bash forge install https://github.com/init4tech/zenith ``` **Rust:** Alloy bindings are available via the [signet-bindings](https://docs.rs/signet-bindings/latest/signet_bindings/) crate ```bash cargo add signet-bindings ``` ## Overview `Passage.sol` exposes a simple interface: **Move ETH to Signet:** ```solidity enter(address rollupRecipient) ``` The `fallback` and `receive` functions also move ETH to Signet, with `msg.sender` as recipient. **Move ERC-20 tokens to Signet:** ```solidity enterToken(address rollupRecipient, address token, uint256 amount) ``` Requires prior `approve` of Passage to spend tokens. Passage can be observed using the `Enter` and `EnterToken` events. The `Enter` event is fired whenever ETH is bridging to Signet, and `EnterToken` is fired when ERC-20 tokens are bridged. The Signet node listens for these events directly, so if the event fired, the tokens were bridged. ## Code Examples {{< details title="Solidity" >}} Passage is available as a Solidity contract or ABI. See the [Setup](#setup) section above. ```solidity contract YourContract { Passage public passage; IERC20 public token; constructor(address _passage, IERC20 _token) { passage = Passage(_passage); token = _token; token.approve(_passage, type(uint256).max); } // Enter on behalf of a user function bridgeETH() external payable { passage.enter{value: msg.value}(msg.sender); } // Move ERC-20 tokens to Signet function bridgeToken(uint256 amount) external { token.transferFrom(msg.sender, address(this), amount); passage.enterToken(address(token), msg.sender); } } ``` {{< /details >}} {{< details title="Cast" >}} To enter the rollup, Send ETH directly to the Passage contract: ```bash # Using cast cast send $PASSAGE_ADDRESS \ --value 1ether \ --rpc-url $HOST_CHAIN_RPC \ --private-key $PRIVATE_KEY ``` Entering with tokens requires multiple transactions: ```bash # 1. Approve Passage cast send $TOKEN_ADDRESS \ "approve(address,uint256)" \ $PASSAGE_ADDRESS, $AMOUNT \ --rpc-url $HOST_CHAIN_RPC \ --private-key $PRIVATE_KEY # 2. Call Passage to bridge tokens # See Passage.sol for the exact function name and parameters cast send $PASSAGE_ADDRESS \ "enterTokens(address,address,uint256)" \ $SIGNET_RECIPIENT, $TOKEN_ADDRESS, $AMOUNT \ --rpc-url $HOST_CHAIN_RPC \ --private-key $PRIVATE_KEY ``` {{< /details >}} {{< details title="Typescript" >}} ```jsx // Using ethers.js const tx = await signer.sendTransaction({ to: PASSAGE_ADDRESS, value: ethers.parseEther("1.0"), }); await tx.wait(); ``` Listen for events: ```jsx import { ethers } from "ethers"; const provider = new ethers.JsonRpcProvider("https://eth.llamarpc.com"); const passage = new ethers.Contract( PASSAGE_ADDRESS, PASSAGE_ABI, // Get ABI from contract source provider ); // Listen for events // Event names and signatures from Passage.sol passage.on("Enter", (...args) => { console.log("ETH bridged:", args); }); passage.on("EnterToken", (...args) => { console.log("Token bridged:", args); }); ``` {{< /details >}} {{< details title="Rust" >}} ```rust let passage = PassageContract::new( signet_constants::pecorino::HOST_PASSAGE, provider.clone(), ); // Enter the rollup from your EOA passage.enter().value(eth_in_wei).send(rollup_recipient).await?; ``` {{< /details >}} {{< callout type="info" >}}Check [Passage.sol](https://github.com/init4tech/zenith/blob/main/src/passage/Passage.sol) for the exact event signatures.{{< /callout >}} ## Next Steps Send a rollup transaction using the [Transactor]({{< relref "./transactor" >}}) contract. [Passage ABI]: /abis/Passage.abi.json -------------------------------------------------------------------------------- ### No Proofs or State Roots URL: https://signet.sh/docs/learn-about-signet/no-proofs-or-state-roots/ Description: How Signet eliminates proving overhead for better performance -------------------------------------------------------------------------------- # No Proofs or State Roots {{< callout type="info" title="Why this matters" >}} - No proving systems or state roots drastically reduces computational overhead - Conditional transactions provide secure, atomic cross-chain operations - Cross-chain transfers are market-based {{< /callout >}} Rollups extend Ethereum by allowing nodes to track additional data. Traditional rollups face significant complexity when communicating this data back to Ethereum, typically relying on proving systems. Signet takes a different approach. ## No proving system Most rollups use complex proving systems like optimistic or zero-knowledge proofs to communicate with Ethereum. These systems introduce significant overhead and complexity and are not necessary for most users. Instead of a proving system, Signet facilitates cross-chain transfers through markets. Assets are bought and sold between Signet and Ethereum, rather than being "proven" back onto Ethereum. This approach: * Reduces computational overhead, lowering transaction costs * Increases capacity for processing transactions * Simplifies the overall architecture, making it easier to maintain and upgrade ## No state roots [State roots]({{< relref "/docs/more-info/glossary/#state-roots" >}}) were designed for a world where everyone runs a full node. However, most users today interact with blockchains through intermediaries like wallet providers or node services, relying on these for state information rather than verifying the entire chain themselves. In this new paradigm, state roots are much less critical for day-to-day operations and consume significant computational resources. Signet removes state roots as part of our broader strategy to streamline rollup architecture. By eliminating the proving system, we've created an environment where state roots become redundant. This allows us to focus on what matters most to users: fast, cheap transactions and a simple, robust system. By removing state roots, Signet: * Drastically reduces computational overhead * Significantly increases transaction throughput * Lowers transaction costs for users {{< callout type="info" title="Tradeoffs of this Approach" >}} Signet prioritizes the happy path and the average user. While removing proving systems and state roots offers significant benefits to most people, it does not support the following: * Light clients * Cryptographic proofs of state {{< /callout >}} -------------------------------------------------------------------------------- ### On-chain Orders in Solidity URL: https://signet.sh/docs/build-on-signet/signet-to-ethereum/on-chain-orders/ Description: Build smart contracts that create and interact with Signet Orders -------------------------------------------------------------------------------- # On-chain Orders in Solidity Build smart contracts that create, fill, or interact with Signet Orders. These examples demonstrate practical patterns for capturing MEV, automating exits, and creating novel cross-chain primitives. ## Setup **Solidity (Source):** Install the Signet Orders contracts ```bash forge install https://github.com/init4tech/zenith ``` **Solidity (ABI):** Download the Orders ABI ```bash curl -O https://signet.sh/docs/abis/Orders.abi.json ``` **Examples:** View example contracts at [signet-sol](https://github.com/init4tech/signet-sol) The example repository demonstrates practical patterns for: - Flash loans - Quick exits with fees - Payment gating - MEV capture Study these examples to understand how to build with Signet Orders. ## Example Contracts All examples use the Signet Orders system to enable cross-chain, instant, atomic, and composable operations. {{< details title="SignetStd.sol - System Configuration" description="Auto-configure Signet system parameters based on chain ID. Use this as a base for contracts that need to interact with Signet." >}} **When to use:** - You're building a contract that creates or interacts with Orders - You need to reference Signet system contracts - You want chain-agnostic Signet integration ```solidity import {SignetStd} from "./SignetStd.sol"; contract YourContract is SignetStd { function createOrder() external { // Automatically has access to: // - rollupOrders: The Orders contract address // - permit2: The Permit2 contract address // - Other Signet system parameters } } ``` Source: [SignetStd.sol](https://github.com/init4tech/signet-sol/blob/main/src/SignetStd.sol) {{< /details >}} {{< details title="Flash.sol - Cross-Chain Flash Loans" description="Flash borrow any asset by using an Order where the Output becomes the Input to its own Order." >}} **When to use:** - You need temporary liquidity for a transaction - You want to perform cross-chain arbitrage - You need to borrow assets without upfront collateral **How it works:** 1. Request a flash loan of X tokens 2. Searchers provide the tokens (knowing they'll be repaid) 3. Your contract executes logic with the borrowed assets 4. The Order output repays the input, completing the cycle ```solidity // Example: Flash borrow WETH for arbitrage flashBorrow(wethAddress, amount, arbitrageCalldata); ``` Source: [Flash.sol](https://github.com/init4tech/signet-sol/blob/main/src/examples/Flash.sol) {{< /details >}} {{< details title="GetOut.sol - Quick Exit with Fee" description="Exit Signet by offering searchers a 50 basis point fee. The simplest way to move assets from Signet to Ethereum." >}} **When to use:** - You want a one-line function to exit Signet - You're willing to pay a small fee for immediate exit - You're building a UI that needs a simple exit mechanism ```solidity // Exit Signet with a 50bps fee getOut(tokenAddress, amount, recipient); ``` **How it works:** - Your contract locks tokens on Signet - Creates an Order offering 99.5% of tokens on Ethereum - Searchers fill the order for the 0.5% profit - You receive tokens on Ethereum instantly Source: [GetOut.sol](https://github.com/init4tech/signet-sol/blob/main/src/examples/GetOut.sol) {{< /details >}} {{< details title="PayMe.sol - Payment Gating" description="Gate contract execution behind a payment using an Order with no inputs. The calling contract doesn't need to manage cash flow--any third party can fill the payment order." >}} **When to use:** - You want users to pay for contract execution - You don't want your contract to handle payment logic - You want to allow third-party payment (gasless transactions) **How it works:** - Your contract creates an Order with only outputs (payment required) - Contract execution is invalid unless someone fills the Order - Unlike `msg.value` checks, the payer can be anyone - Greatly simplifies payment logic ```solidity function executeWithPayment() external { // Create payment order payMe(usdcAddress, 10e6); // Require 10 USDC payment // Your contract logic here // Only executes if payment Order is filled } ``` Source: [PayMe.sol](https://github.com/init4tech/signet-sol/blob/main/src/examples/PayMe.sol) {{< /details >}} {{< details title="PayYou.sol - MEV Capture and Bounties" description="Generate MEV by offering an Order with no outputs. This creates a bounty for calling your contract, functioning as an incentivized scheduling system." >}} **When to use:** - You want to incentivize someone to call your contract - You're creating an automated system that needs execution - You want to capture MEV produced by your protocol **How it works:** - Your contract creates an Order with only inputs (no outputs required) - Searchers compete to call your contract to claim the bounty - Functions as an incentivized scheduling/execution system ```solidity function executeAndPay() external { // Your contract logic that generates value performArbitrage(); // Pay searchers for executing payYou(wethAddress, 0.01 ether); // Offer 0.01 ETH bounty } ``` **Use cases:** - Liquidation systems - Automated rebalancing - Scheduled maintenance - MEV extraction from your protocol Source: [PayYou.sol](https://github.com/init4tech/signet-sol/blob/main/src/examples/PayYou.sol) {{< /details >}} {{< callout type="info" title="Building your own contract" >}} Use these patterns as building blocks: 1. **Inherit SignetStd** for automatic configuration 2. **Combine patterns** (e.g., PayMe + PayYou for payment flows) 3. **Test thoroughly** with `forge test` 4. **Deploy** to Signet testnet first {{< /callout >}} -------------------------------------------------------------------------------- ### Report a Vulnerability URL: https://signet.sh/docs/more-info/security/report/ Description: Template for filing a vulnerability for Signet. -------------------------------------------------------------------------------- # Report a Vulnerability Fill out the report template below and email it to . No NDA required. Your findings are your own. [Safe harbor]({{< relref "/docs/more-info/security/bug-bounty/#safe-harbor" >}}) for good-faith researchers. ```text # Report title: issue description and impact - Provide a succinct description the issue and its impact ## Affected asset(s) - List out contract address, endpoints, commits, etc... - Include version numbers and/or tags where known ## Impact summary + severity estimate - Use our [severity tiers]({{< relref "/docs/more-info/security/bug-bounty/" >}}#severity-tiers) for reference ## Reproduction steps & PoC - Add scripts, tx hashes, block data, screenshots, logs, etc... used to reproduce ## Suggested fix (if known) - Describe remediation and/or mitigation steps and strategies - If you've made a PR, link it here ``` Consult the [Severity Tiers]({{< relref "/docs/more-info/security/bug-bounty/" >}}#severity-tiers) for classifications. -------------------------------------------------------------------------------- ### Ethereum-driven Transactions URL: https://signet.sh/docs/build-on-signet/ethereum-to-signet/transactor/ Description: Execute transactions from Ethereum to Signet with guaranteed inclusion -------------------------------------------------------------------------------- # Ethereum-driven Transactions The [`Transactor`](https://github.com/init4tech/zenith/blob/main/src/Transactor.sol) contract creates transactions on Signet from Ethereum. Transactions made via the `Transactor` always execute on Signet at the end of the current block, bypassing any possibility of builder censorship. Consult the [Pecorino Quickstart]({{< relref "../pecorino/" >}}) guide for contract addresses and RPC endpoints. ## Setup **Solidity (ABI):** Download the Transactor ABI from [Transactor ABI](/abis/Transactor.abi.json) ```bash curl -O https://signet.sh/docs/abis/Transactor.abi.json ``` **Solidity (Source):** The Transactor contract is open source ```bash forge install https://github.com/init4tech/zenith ``` **Rust:** Alloy bindings are available via the [`signet-zenith`] crate ```bash cargo add signet-zenith ``` ## Overview `Transactor.sol` exposes a basic EVM transaction as a single function: ```solidity function transact( address to, bytes calldata data, uint256 value, uint256 gas, uint256 maxFeePerGas ) external payable ``` Calling the `transact` function results in a system transaction being issued on Signet **from the address of the caller**. This allows Ethereum contracts to own assets on Signet, and to trigger contract execution on Signet from Ethereum with native authentication. The `value` argument is the amount of USD in wei to send **on the rollup**. USD is the native asset of Signet. This amount will be attached to the Signet transaction. The balance of originating address on Signet must be sufficient to cover this value. {{< callout type="info" title="Note" >}} See the [Address Aliasing]({{< relref "../evm-behavior/#address-aliasing" >}}) section in the EVM Behavior docs for important information on how contract addresses are modified when using the Transactor. {{< /callout >}} Transact events are executed at the **end** of the Signet block. Contract creation via `Transactor` is not currently supported. The Transactor emits a `Transact` event that can be monitored. The Signet node listens for these events directly, so if the event fired, the transaction **was** included in Signet (although it may revert or be dropped by the [Signet Orders]({{< relref "../signet-to-ethereum/orders/" >}}) system). {{< callout type="success" title="Use Transactor when..." >}} - You need guaranteed transaction inclusion - You want to trigger Signet actions from Ethereum - You're building cross-chain workflows - You need censorship resistance {{< /callout >}} {{< callout type="danger" title="Don't use Transactor when..." >}} - You're just moving assets (use [Passage] instead) - Gas cost is a primary concern (direct Signet txs are cheaper) - You don't need L1-triggered execution {{< /callout >}} ## Code Examples {{< details title="Solidity" >}} ```solidity contract YourContract { Transactor public transactor; constructor(Transactor _transactor) { transactor = _transactor; } // Execute a function on Signet from Ethereum function executeOnSignet( address signetTarget, bytes calldata functionData ) external { transactor.transact( signetTarget, functionData, 0, // USD value on Signet 1_000_000, // gas limit on Signet 100 gwei // max fee per gas (in USD) on Signet ); } // Emergency action on Signet function emergencyAction(address signetContract) external onlyOwner { // Encode the emergency function call bytes memory data = abi.encodeWithSignature("emergencyPause()"); executeOnSignet(signetContract, data); } } ``` {{< /details >}} {{< details title="Monitoring Transactor activity in JavaScript/TypeScript" >}} Listen for Transactor events to track Host-driven transactions: ```jsx import { ethers } from "ethers"; const provider = new ethers.JsonRpcProvider("https://eth.llamarpc.com"); const transactor = new ethers.Contract( TRANSACTOR_ADDRESS, TRANSACTOR_ABI, // Get ABI from contract source provider ); // Listen for Host-driven transactions // Event name and signature from Transactor.sol transactor.on("Transact", (...args) => { console.log("Host-driven execution:", args); // Decode the calldata if needed const [from, to, data] = args; // Adjust based on actual event console.log(`${from} Host-driven execution on ${to}`); }); ``` {{< /details >}} ## Related Resources - [Address Aliasing]({{< relref "../evm-behavior/#address-aliasing" >}}) - [Signet Orders]({{< relref "../signet-to-ethereum/orders/" >}}) - [`signet-zenith`] crate - [Transactor ABI](/abis/Transactor.abi.json) - [`Transactor`](https://github.com/init4tech/zenith/blob/main/src/Transactor.sol) contract source - [Pecorino Quickstart]({{< relref "../pecorino/" >}}) [`signet-zenith`]: https://docs.rs/signet-zenith/latest/signet_zenith/ [Passage]: https://github.com/init4tech/zenith/blob/main/src/passage/Passage.sol -------------------------------------------------------------------------------- ### Hall of Fame URL: https://signet.sh/docs/more-info/security/hall-of-fame/ Description: A showcase of previously awarded bug bounties -------------------------------------------------------------------------------- # Hall of Fame | Investigator | Finding | Reward (USD) | Published | | ------------ | ------- | ------------ | --------- | | -- | -- | -- | -- | -------------------------------------------------------------------------------- ### Off-chain Orders in Rust URL: https://signet.sh/docs/build-on-signet/signet-to-ethereum/rust-orders/ Description: Create Signet Orders in Rust -------------------------------------------------------------------------------- # Off-chain Orders in Rust This page will walk you through creating and submitting off-chain Orders using Rust and the Signet SDK. The [Orders](https://github.com/init4tech/zenith/blob/main/src/orders/) contract enables trustless, cross-chain asset swaps between Signet and Ethereum. Signet nodes listen for Order and Filled events, and ensure that all transactions that emit Orders have corresponding Fills executed on the destination chain in the same block. Order events are emitted on Signet, while Filled events may be emitted on either Ethereum or Signet. Off-chain orders are pre-signed, using [Permit2](https://docs.uniswap.org/contracts/permit2/overview), and may be executed by a third-party filler, allowing users to perform gasless swaps. {{< callout type="warning" title="Set competitive prices on your orders" >}} Signet Orders guarantee that if their Outputs are not Filled, no transaction will be executed on Signet. However, there is no guarantee that any searcher will choose to Fill your Order. Make sure to set competitive prices on your orders to ensure they are filled! {{< /callout >}} ## Setup Set up your Rust project ```bash cargo new my_cool_app --bin ``` Install the required Signet crates ```bash cargo add signet-zenith cargo add signet-constants cargo add signet-types cargo add signet-tx-cache ``` Ensure your account has approved [Permit2](https://docs.uniswap.org/contracts/permit2/overview) to spend your input tokens. Consult the [Pecorino Quickstart]({{< relref "../pecorino/" >}}) guide for contract addresses and RPC endpoints. ## Creating an Order The [signet-types](http://docs.rs/signet-types/latest/signet_types/) crate provides a simple order builder via the [UnsignedOrder](https://docs.rs/signet-types/latest/signet_types/signing/order/struct.UnsignedOrder.html) struct, which can be used to build orders. We can start by creating a simple order that swaps 1 WETH on Signet for 1 WETH on Ethereum: ```rust use signet_types::signing::order::{UnsignedOrder}; use signet_constants::pecorino as constants; let mut order = UnsignedOrder::default() .with_input( constants::RU_WETH, U256::from(1e18), // 1 WETH ).with_output( constants::HOST_WETH, U256::from(1e18), your_address, 1, // Ethereum mainnet ); ``` The `UnsignedOrder` struct also provides methods to sign orders, using any alloy signer. The signer requires that you provide the `constants` object, so that the permit2 signer can correctly derive the domain separator. ```rust use signet_types::signing::order::{UnsignedOrder}; use signet_constants::pecorino as constants; let signed = UnsignedOrder::default() .with_input(token_address, amount) .with_output(token_address, amount, recipient, chain_id) .with_chain(constants) .with_nonce(permit2_nonce) .sign(&signer).await?; ``` ## Submitting an Order Once signed, the order can be submitted to the Signet network via the Signet tx cache. The tx cache makes the Order available to Searchers, who will include it in execution bundles. ```rust use signet_tx_cache::TxCache; let tx_cache = TxCache::pecorino(); tx_cache.forward_order(signed_order).await?; ``` For on-chain order creation, check out [Solidity Orders]({{< relref "./on-chain-orders/" >}}). -------------------------------------------------------------------------------- ### Permissioned Roles URL: https://signet.sh/docs/more-info/permissioned-roles/ Description: Overview of permissioned roles in Signet smart contracts -------------------------------------------------------------------------------- # Permissioned Roles Signet's smart contracts use a system of permissioned roles to manage access control. Each contract has specific roles that can perform certain administrative functions. ## Core Roles ### Sequencer Admin The `sequencerAdmin` role manages the list of authorized sequencers in the Zenith contract. This role can: - Add or remove sequencers - Update sequencer configuration - Pause sequencing if needed ### Sequencer The `sequencer` role is responsible for validating and co-signing blocks before they are submitted to the Zenith contract. Sequencers: - Validate blocks from builders - Co-sign valid blocks - Ensure blocks follow the protocol rules ### Gas Admin The `gasAdmin` role in the Transactor contract manages gas-related parameters for force-included transactions. This role can: - Update gas price limits - Adjust gas estimation parameters - Configure gas subsidies ### Token Admin The `tokenAdmin` role in the Passage contract manages which tokens can be bridged between chains. This role can: - Add new supported tokens - Update token configuration - Set bridge limits for specific tokens ## Role Management All permissioned roles are managed through a secure access control system. Role transitions are transparent and logged on-chain through events. This provides auditability while allowing the protocol to evolve over time. -------------------------------------------------------------------------------- ### Simple Sequencing URL: https://signet.sh/docs/learn-about-signet/simple-sequencing/ Description: Signet's approach to transaction ordering and inclusion -------------------------------------------------------------------------------- # Simple Sequencing {{< callout type="info" title="Why this matters" >}} - Ethereum block production is overwhelmingly centralized. Most blocks are built by just a few builders (see below) - To address this centralization, Signet assigns block production rights in a round-robin style to block builders - This round-robin model does away with proposer-builder auctions and therefore prevents the most wealthy block builders from dominating the market {{< /callout >}} ## Centralization of Sequencing Every blockchain needs a way to order transactions — that's sequencing. Ethereum uses auctions to determine who gets to build blocks and sequence transactions. There are a few problems with this: 1. Auctions mainly benefit the Ethereum block proposer, even though they do no valuable work. 2. Auctions centralize block building by favoring a small number of hyper-specialized builders who can out-compete smaller players. {{< callout type="warning" title="Ethereum's blocks are built by a small number of block builders" >}} Block building is a very high-sophistication activity, leading to a very competitive market. Marginal improvements in MEV extraction lead to significantly increased probability of winning a block auction. This means that the most aggressive builders tend to squeeze out smaller builders. This leads to aggregation of control in the hands of a small number of builders. {{< /callout >}} {{< image src="mevboost.png" alt="Block builder market share showing the majority of blocks built by two builders" caption="Block builder market share statistics from [MEVboost.pics](https://mevboost.pics/) show that Ethereum's blocks are built by just a handful of builders." >}} Even worse, rollup sequencing is centralized _by default._ The chain's order is set by a single entity, with little-to-no recourse. No rollup has credible plans to decentralize the sequencer. ## An alternative approach to sequencing Instead of auctions, Signet uses a central sequencer that _**assigns block production rights**_ to block builders in a round-robin fashion. Each Ethereum block, a specific builder may create a Signet block. That builder is responsible for creating a Signet block and for submitting that block to Ethereum. The Signet sequencer co-signs the builder's block _without seeing its contents_. ### Resistance to censorship by the Signet sequencer Once the assigned builder has produced a block, the Signet sequencer co-signs the block header without seeing the block contents. This means the sequencer only sees the block's hash and the builder's identity, not the transactions. By signing blocks without knowing their contents, the Signet sequencer can't selectively censor transactions, ensuring fair and unbiased block inclusion while maintaining its role in managing builder participation. {{< callout type="info" title="Tradeoffs of this approach" >}} This model represents a trade-off between _theoretical_ and _operational_ decentralization. While Ethereum's system is _theoretically_ decentralized, in that there is no single authority or administrator, it is _operationally centralized_ because a small number of block builders control sequencing. Signet's approach prioritizes _operational_ decentralization by increasing the number of builders, by introducing a centralized sequencer to permission and manage that builder set. We believe that active management is the best solution to emergent centralization. {{< /callout >}} -------------------------------------------------------------------------------- ### Cross-chain transfers URL: https://signet.sh/docs/learn-about-signet/cross-chain-transfers/ Description: How assets move seamlessly between chains -------------------------------------------------------------------------------- # Cross-chain transfers {{< callout type="info" title="Why this matters" >}} - Moving assets into and out of Signet is simple and instant - Conditional transactions require cross-chain transfers to be fully executed in the same block on both chains {{< /callout >}} ## Moving from Ethereum to Signet Because Signet produces blocks at the same time as Ethereum, assets and data can move freely from Ethereum to Signet in the same block. If you send Ether to Signet, entering Signet has **no time delay**. Signet does not require a multi-minute wait like centrally sequenced rollups. Users can also send transactions from Ethereum to Signet. These transactions correspond to the "forced inclusion" mechanisms on other rollups but have **no time delay.** They always execute immediately on Signet, at the end of the current block. Moving from Ethereum to Signet always occurs in the same block, and cannot be censored or delayed by anyone. {{< callout type="info" >}} At present, Signet supports **ETH**, **USDC**, **USDT**, and **WBTC**. Custom assets may be created within Signet, but not bridged from Ethereum. If you would like your asset to be bridged to Signet from Ethereum, please reach out. {{< /callout >}} {{< details title="Example: Moving assets from Ethereum to Signet" >}} The [Passage](https://github.com/init4tech/zenith/blob/main/src/passage/Passage.sol) contract facilitates asset transfers from Ethereum to Signet. A user wants to move 10 ETH from Ethereum to Signet: 1. User sends 10 ETH to the Signet/Passage contract on Ethereum. 2. The contract emits an `Enter` event. 3. Signet Rollup Node observes the event. 4. Rollup Node mints 10 ETH to the user's address on Signet. This process is permissionless and requires no action on Signet from the user. {{< /details >}} ## Moving from Signet to Ethereum Signet introduces [Conditional Transactions]({{< relref "/docs/more-info/glossary/#conditional-transactions" >}}) to enable both local trades, and cross-chain transfers. Conditional transactions succeed _if and only if_ some condition is met at the end of execution. This condition can look at state within the rollup, or in limited cases on Ethereum. This allows same-block interaction and trading with Ethereum. Transfers and trades are conditional on full execution. I.e. if the trade does not complete, it never occurs at all. The rollup erases failed trades and failed transfers from its history. Signet requires cross-chain transfers to be fully executed in the same block on both chains. Otherwise, the transaction is invalid and has no effect on Signet's state; it's as if the transaction never existed. This allows for secure, instant transfers between Ethereum and Signet, so long as there is a Filler willing to accept the user's order. {{< callout type="success" title="No Lockup Period" >}} Existing rollups introduce lockup periods for user withdrawals. With Signet, there is no lockup period for market-based transfers, allowing instant settlement. {{< /callout >}} {{< details title="Example: Moving assets from Signet to Ethereum" >}} A user wants to move 5 ETH from Signet to Ethereum. They create a conditional transaction to transfer 5 ETH. This transaction is only valid if the user receives 5 ETH on Ethereum in the same block. 1. Some Filler accepts this order by sending 5 ETH to the user on Ethereum. 2. The conditional transaction is now valid. 3. The Filler receives 5 ETH on Signet. The user's ETH on Signet moves _if and only if_ the ETH on Ethereum goes to the user. The user cannot lose their ETH, unless they also get ETH. {{< /details >}} {{< callout type="info" title="Tradeoffs of this approach" >}} Signet prioritizes the happy path and the average user. Conditional transactions provide same-block trades and interactions with Ethereum, however, they cannot provide the following: - Synchronous composability - Arbitrary message passing between smart contracts {{< /callout >}} -------------------------------------------------------------------------------- ### Senior Rust Engineer URL: https://signet.sh/docs/more-info/open-positions/senior-rust-engineer/ Description: Work on the Signet node, SDKs, and simulation tooling — deep systems work in Rust. -------------------------------------------------------------------------------- # Senior Rust Engineer Location: Remote (US / EU time zones) {{< callout type="info" title="About init4" >}} init4 tech is the labs entity behind **Signet**, a pragmatic Ethereum rollup. We're focused on building next-generation Ethereum; Signet is our first major release and introduces a radically different approach to rollup design. {{< /callout >}} ## Overview We're hiring a Senior Rust Engineer to work across the Signet stack: node execution, SDKs, simulation tooling, and the networking layers that glue everything together. You should be comfortable taking research prototypes to production and shipping high-quality, high-performance Rust code. ## Responsibilities - Design, build, and maintain Rust systems powering the Signet rollup and related infrastructure. - Implement memory-safe, high-performance code for networking, execution, and consensus-adjacent components. - Write tests, fuzzers, and simulations to validate complex system behavior. - Profile and optimize at the protocol and infrastructure layers. - Collaborate with cryptography, security, and DevOps teams to integrate low-level components. ## Required - 5+ years professional software engineering experience. - 3+ years hands-on Rust experience with production systems. - Strong background in distributed systems, P2P networking, or consensus algorithms. - Experience with asynchronous runtimes, concurrency, and low-level performance tradeoffs. - Clear communication and ability to work across research and product teams. ## Nice to have - Contributions to open-source Rust projects. - Familiarity with Ethereum, rollups, or other blockchain protocols. - Systems programming experience in Go/C/C++. ## What we offer - Competitive salary and meaningful equity. - Small, focused team. Experienced systems engineers. - Work on core rollup infrastructure for Ethereum. ## How to apply Send your resume to [jobs@init4.technology](mailto:jobs@init4.technology). ## Equal opportunity & privacy We are an equal opportunity employer. We welcome applicants from diverse backgrounds and will consider all qualified candidates. Submitted application materials will be handled in accordance with applicable privacy laws and retained only for a limited time. ================================================================================ ## RECENT UPDATES -------------------------------------------------------------------------------- ### Signet Orders URL: https://signet.sh/updates/signet-orders/ Published: 2025-08-28 -------------------------------------------------------------------------------- Market-driven cross-chain execution requires practical implementation patterns. This guide provides working code for placing and filling Orders on Signet, demonstrating how applications can leverage competitive fillers for instant cross-chain operations. Building on Signet's [simplified atomicity](https://signet.sh/updates/simplified-atomicity/) and [settlement system](https://signet.sh/updates/settlement-system/), these examples show how to implement the order flow that powers same-block cross-chain execution. ## Implementation Components Three core components enable Order-based applications: - **Order Creation**: Applications express user intent through signed Permit2 structures - **Order Filling**: Market participants compete to fulfill orders for profit opportunities - **Bundle Coordination**: Atomic execution ensures all-or-nothing settlement The [`signet-orders`](https://github.com/init4tech/signet-orders) repository provides reference implementations for each component using utilities from [`signet-sdk`](https://github.com/init4tech/signet-sdk). ## Filler Implementation **Code: [`src/filler.rs`](https://github.com/init4tech/signet-orders/blob/main/src/filler.rs)** The `Filler` struct demonstrates the steps required to fill Signet Orders competitively: ```rust impl Filler { pub async fn fill(&self, orders: Vec) -> Result<()> { // 1. Construct and sign Permit2 fills for destination chains let fills = self.construct_fills(&orders).await?; // 2. Build atomic bundle combining initiates and fills let bundle = self.build_signet_bundle(&orders, &fills).await?; // 3. Submit to Transaction Cache for builder inclusion self.tx_cache.submit_bundle(bundle).await } } ``` Production fillers extend this pattern with custom business logic: - **Profitability**: Calculate spread opportunities across order sets - **Inventory**: Source liquidity through swaps when needed - **Competition**: Evaluate win probability against other fillers ## Filling Strategies The implementation demonstrates two complementary approaches: ### Aggregate Execution (`fill`) ```rust pub async fn fill(&self, orders: Vec) -> Result<()> { // Submit all Orders/Fills in single Bundle // Atomic execution: all succeed or none do } ``` **Benefits:** - **Gas efficiency**: Batched execution reduces transaction costs - **Capital optimization**: Reuse inputs from one order to fill another - **Complex strategies**: Enable sophisticated cross-order arbitrage **Trade-offs:** - **All-or-nothing**: Single order failure breaks entire bundle - **Complexity**: Requires pre-validation of order state ### Individual Execution (`fill_individually`) ```rust pub async fn fill_individually(&self, orders: Vec) -> Result<()> { // Submit each Order/Fill in separate Bundle // Independent execution: orders succeed or fail separately } ``` **Benefits:** - **Simplicity**: Rely on builder simulation instead of pre-checking - **Resilience**: Failed orders don't affect successful ones - **Parallel processing**: Multiple strategies can run simultaneously **Trade-offs:** - **Higher gas costs**: Individual transaction overhead per order - **Limited optimization**: Cannot reuse capital across orders ## Order Creation **Code: [`src/order.rs`](https://github.com/init4tech/signet-orders/blob/main/src/order.rs)** The `SendOrder` struct provides the application-side implementation for initiating orders: ```rust impl SendOrder { pub async fn initiate_order(&self, order: OrderSpec) -> Result<()> { // 1. Construct Permit2 authorization for inputs let permit = self.build_permit2(&order.inputs).await?; // 2. Sign order with user's key let signed_order = self.sign_order(permit, &order.outputs).await?; // 3. Submit to Transaction Cache for filler discovery self.tx_cache.submit_order(signed_order).await } } ``` Applications integrate this pattern to offer users instant cross-chain operations without managing bridge infrastructure or withdrawal periods. ## Complete Roundtrip Example **Code: [`bin/roundtrip.rs`](https://github.com/init4tech/signet-orders/blob/main/bin/roundtrip.rs)** The roundtrip example demonstrates end-to-end order flow: 1. **Construct Order**: Define input/output tokens and amounts 2. **Submit Order**: Send signed order to Transaction Cache 3. **Fill Order**: Compete with other fillers to execute 4. **Verify Settlement**: Confirm atomic cross-chain execution ```bash # Configure environment export CHAIN_NAME=pecorino export RU_RPC_URL=https://rpc.pecorino.signet.sh/ export SIGNER_KEY=[AWS KMS key ID or local private key] export SIGNER_CHAIN_ID=14174 # Run rollup-to-host swap cargo run --bin order-roundtrip-example # Run rollup-to-rollup swap cargo run --bin order-roundtrip-example -- --rollup ``` The example handles both AWS KMS and local private key signing, demonstrating production-ready key management patterns. ## Setup Requirements **Fund Your Key** The signing key must hold: - **Input tokens**: Assets being swapped from (rollup) - **Output tokens**: Assets being provided to user (host and/or rollup) - **Gas tokens**: ETH (Host) or USD (Rollup) for transaction fees **Configure Permit2 Approvals** Enable Permit2 to spend relevant tokens: ```bash cast send [TOKEN_ADDRESS] "approve(address,uint256)" \\ 0x000000000022D473030F116dDEE9F6B43aC78BA3 \\ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff \\ --rpc-url $RPC_URL ``` Permit2 uses consistent addresses across Pecorino and Ethereum mainnet, simplifying multi-chain applications. ## Bundle Execution Model Orders execute through Signet's atomic bundle system: **Block-Specific Execution**: Bundles target specific blocks for deterministic inclusion **Retry Pattern**: Failed bundles can be resubmitted for subsequent blocks **Atomic Guarantees**: All transactions in bundle succeed or none do ```rust // Bundle construction with host fills let bundle = SignetEthBundle { host_fills: Some(permit2_fills), // Ethereum-side actions bundle: EthSendBundle { txs: signet_transactions, // Signet-side transactions block_number: target_block, reverting_tx_hashes: vec![], // No partial execution allowed } }; ``` This model enables applications to offer users the same UX as centralized services while maintaining decentralized execution. ## Market Dynamics Order-based execution creates competitive markets that benefit users: - **Filler Competition**: Multiple parties compete to fill orders, driving efficient pricing - **Capital Efficiency**: Fillers optimize inventory across chains rather than maintaining idle liquidity pools - **Execution Incentives**: Better filling strategies capture more volume and profit Applications benefit from this competition without building internal market-making infrastructure. ## Production Considerations - **Business Logic**: Implement custom profitability analysis for your specific use case - **Key Management**: Use hardware security modules or key management services for production **Monitoring**: Track order fill rates and competitive positioning - **Capital Strategy**: Plan inventory management across supported chains - **Error Handling**: Implement retry logic for failed bundles and network interruptions - **Gas Optimization**: Consider aggregate vs individual filling strategies based on order patterns ## Integration Patterns - **Cross-chain DeFi**: Enable instant cross-chain positions without bridge delays - **Payment Systems**: Route payments optimally across chains based on liquidity - **Arbitrage Bots**: Capture price differences while providing user services - **Wallet Interfaces**: Offer seamless cross-chain swaps through order abstraction ## Build with Orders The order system transforms cross-chain operations from complex infrastructure challenges into simple market interactions. Applications post orders, competitive fillers provide execution, users get instant settlement. **Resources:** - [`signet-orders`](https://github.com/init4tech/signet-orders) - Complete example implementations - [`signet-sdk`](https://github.com/init4tech/signet-sdk) - Core types and utilities **Get Started:** - [Testnet Faucet](https://faucet.pecorino.signet.sh/) - Fund your development keys - [Pecorino Explorer](https://explorer.pecorino.signet.sh/) - Monitor order execution Start building applications that leverage competitive execution rather than fighting it. Orders enable market-driven cross-chain operations that scale with demand. **Questions about implementation patterns?** [Reach out](mailto:hello@init4.technology) to discuss specific integration approaches. -------------------------------------------------------------------------------- ### Settlement System URL: https://signet.sh/updates/settlement-system/ Published: 2025-06-04 -------------------------------------------------------------------------------- Traditional rollups lock capital and introduce: - **Multi-step withdrawal processes**: Initiate → Wait → Release - **Multi-day fraud proof windows**: Capital remains locked and unproductive This design creates a poor experience for users, builders, and solvers. ## Market-Based Settlement Signet eliminates the complicated withdrawal process and unnecessary delays through swaps by: **1. Synchronized Block Production** - Identical timestamps ensure deterministic ordering - Fork-choice rule maintains consensus alignment **2. Atomic Cross-Chain Execution** - Same-block finality - Conditional transaction enforcement **3. Market-Driven Price Discovery** - Competitive filler ecosystem - Real-time liquidity provision Signet is the only chain to achieve same-block cross chain settlement and it starts with our synchronized block architecture. ### Concurrent Block Production ![concurrent-block-production.png](concurrent-block-production.png) This 1:1 coupling enables deterministic state transitions. Every Signet block corresponds to exactly one Ethereum block, eliminating timing discrepancies. ### Order System Architecture Orders express atomic intent through Permit2, enabling gasless authorization: ```rust pub struct SignedOrder { pub permit: Permit2Batch, // Single signature authorization pub outputs: Vec, // Desired assets and destinations } pub struct Output { pub token: Address, // Asset identifier pub amount: Uint<256, 4>, // Precise amount pub recipient: Address, // Destination address pub chainId: u32, // Target chain } ``` **Order Lifecycle:** 1. **Creation**: User signs intent with ~10 minute validity window 2. **Discovery**: Broadcast to transaction cache for filler evaluation 3. **Execution**: Atomic settlement within single block 4. **Finalization**: Immediate availability on destination chain ### Settlement Mechanics: Inverted Execution Signet’s approach to atomicity is in transaction ordering enforcement: ![settlement-mechanics.png](settlement-mechanics.png) The `OrderDetector` enforces atomicity by validating that every order has corresponding fills before allowing transaction execution. This prevents partial settlements through deterministic state validation: ```rust impl OrderDetector { fn validate_transaction(&self, tx: &Transaction) -> Result<(), Error> { // Check if transaction emits Order event if let Some(order) = self.detect_order(tx) { // Verify all outputs have corresponding fills for output in order.outputs { if !self.has_sufficient_fill(output) { return Err(Error::InsufficientFill); } } // Consume fill amounts to prevent double-spending self.consume_fills(order.outputs); } Ok(()) } } ``` **Key Benefits:** - Fill transactions must mine before Initiate transactions - Failed fills result in automatic Initiate rejection - No intermediate states or partial executions ### Capital Efficiency Traditional rollups lock capital for extended periods. Signet enables continuous deployment: ![capital-velocity.png](capital-velocity.png) {{< callout type="info" >}} While traditional rollups process transactions continuously, settlement requires days. Signet settles every transaction in seconds. {{< /callout >}} This enables strategies previously impossible on other chains: **1. Intra-Block Arbitrage** - Execute multiple trades within single 12-second block - Compound returns through circular trading paths - Eliminate sequential execution risk **2. Dynamic Inventory Management** - Real-time cross-chain balance optimization - Just-in-time liquidity provision - Zero idle capital **3. Multi-Order Aggregation** - Net positions across multiple orders - Reduce transaction costs through batching - Maximize capital efficiency per block ### Bundle Construction Fillers aggregate multiple orders into atomic execution bundles: ```rust async fn construct_bundle(&self, orders: &[SignedOrder]) -> Result { // Aggregate orders by destination chain let aggregated = self.aggregate_by_chain(orders); // Sign fills for each destination let signed_fills = self.sign_fills(&aggregated).await?; // Build transaction sequence with proper ordering let txs = self.sequence_transactions(&signed_fills, orders).await?; // Extract cross-chain coordination data let host_fills = signed_fills.get(ÐEREUM_CHAIN_ID); // Atomic bundle with deterministic execution Ok(SignetEthBundle { host_fills, // Ethereum-side actions bundle: EthSendBundle { txs, // Signet-side transactions block_number: self.target_block(), reverting_tx_hashes: vec![], // No reverts allowed }, }) } ``` **Error Handling:** - Invalid signatures → Bundle rejected pre-execution - Insufficient liquidity → Fill transaction reverts - Gas exhaustion → Entire bundle fails atomically ### Market Efficiencies: Multiple fillers evaluate each order simultaneously, creating competitive pricing: ![price-discovery.png](price-discovery.png) - Multiple fillers evaluate each order simultaneously - Competition drives spreads toward equilibrium - Price discovery occurs every 12 seconds - No single filler controls market pricing - Capital availability across chains ### Filler Infrastructure Implement custom market-making strategies using the Signet SDK: ```rust // Custom filler implementation impl FillerStrategy for MyFiller { async fn evaluate_order(&self, order: &SignedOrder) -> Option { // Implement custom pricing logic let profit_margin = self.calculate_margin(order)?; // Check inventory across chains let has_liquidity = self.check_inventory(order).await?; // Evaluate competition let competitive = self.estimate_win_probability(order); if profit_margin > self.min_margin && has_liquidity && competitive > 0.3 { Some(FillDecision::Accept) } else { None } } } ``` - Gas cost optimization - Inventory rebalancing costs - Competition assessment - Risk-adjusted profit margins ## Protocol-Level Markets Signet's architecture embeds market mechanics at the protocol level: ![protocol-level-markets.png](protocol-level-markets.png) Every application built on Signet is enabled with instant cross-chain settlement. ## Cross-Chain Settlement Opportunities Whether it’s building user applications, providing liquidity, or executing orders, every builder benefits from the speed of settlement to Ethereum: - No asynchronous state risks between chain operations - No wrapped token complexity or liquidity fragmentation - No artificial constraints on capital deployment - No settlement uncertainty affecting execution ## Build with us The best way to get started is with our [docs]({{< relref "/docs/learn-about-signet/simplifying-the-rollup/" >}}) or [getting in touch](http://t.me/anthspezzano) if you have any questions. **Get Involved:** - [Developer interest form](https://forms.gle/abc123) - [Documentation feedback](https://forms.gle/xyz789) **Market Participants:** - [Filler examples](https://github.com/init4tech/signet-sdk/tree/main/crates/rpc/examples): Complete implementation patterns **Order System:** - [Orders in Signet]({{< relref "/docs/build-on-signet/signet-to-ethereum/orders/" >}}): Permit2 orders in Signet - [SDK primitives](https://github.com/init4tech/signet-sdk/tree/main/crates/types): Type-safe order handling **Bundle Construction:** - [Atomic execution](https://github.com/init4tech/signet-sdk/tree/main/crates/bundle): Transaction sequencing tools - [Simulation framework](https://github.com/init4tech/signet-sdk/tree/main/crates/sim): Pre-execution validation -------------------------------------------------------------------------------- ### Execution Engine URL: https://signet.sh/updates/execution-engine/ Published: 2025-04-30 -------------------------------------------------------------------------------- Signet uses a straightforward order system for cross-chain transactions. We remove unnecessary verification layers to deliver faster settlements with lower costs. Our architecture focuses on reliable asset transfers between networks without technical complexity. The order system uses _signed orders_ to describe a user's intent and _bundles_ to coordinate execution of these intents across chains. ## Conditional transactions via signed orders Signed orders use the Permit2 standard, allowing users to authorize token transfers with a single signature. This intent mechanism powers Signet's swaps, allowing users to express intents like: > "I want to swap 1 ETH on Signet for 1800 USDC on Ethereum" Nothing happens if the exact conditions you specify are not met. ```rust // Signed orders pub struct SignedOrder { /// The permit batch. #[serde(flatten)] pub permit: Permit2Batch, /// The desired outputs. pub outputs: Vec, } // Permit2 batches pub struct Permit2Batch { pub permit: ::RustType, pub owner: Address, pub signature: Bytes, } ``` Permit2 batches contain individually signed transactions, allowing multiple inputs (what the user provides) to map to desired outputs (what the user receives). These Permit2 transactions then go to an orders cache for matching. ## Cross-chain transfers Signet's approach to cross-chain transfers separates mechanisms based on direction. This separation creates predictable pathways that optimize for each direction's unique requirements. ### Entering Signet: Passage For asset transfers from Ethereum to Signet, users will interact with the Passage contract, which follows a simple event-based approach: 1. User deposits assets to the Passage contract on Ethereum 2. The contract emits an Enter event 3. Signet observes this event and mints corresponding tokens ### Exiting Signet: Signed Orders For asset transfers from Signet to Ethereum, users will use signed orders (swaps). 1. Signed orders express user intent to move assets from Signet to Ethereum 2. Market participants fulfill these orders with corresponding assets 3. Execution happens atomically in the same block on both chains {{< image src="cross-chain-swap.png" alt="Cross-chain swap diagram showing token flow between chains" >}} ## Market Participants Our market-based approach eliminates the need for verification periods or complex bridging. Users move assets instantly between chains. {{< image src="signet-architecture.png" alt="Signet architecture diagram showing system components" >}} ### Searchers Searchers connect orders with liquidity and are essential for creating efficient markets. They: - Scan orders cache - Build matching permits into bundles - Submit these bundles to block builders - Drive efficiency by connecting orders with liquidity ### Fillers Fillers provide liquidity to the system. They: - Fulfill open orders with their own assets - Enable cross-chain transfers without traditional bridges - Make instant withdrawals possible ### Block Builders Block builders assemble transactions into Signet blocks. They process two primitive types -- _bundles_ and _signed orders_. 1. Bundles are standard collections of transactions to be included in blocks. 4844 transactions are excluded from the rollup by design. 2. Signed Orders are permit2 transactions expressing user intents. These connect cross-chain activity via `hostFills`. ## Bundles coordinate cross-chain actions We extend [Flashbots bundles](https://docs.flashbots.net/flashbots-auction/advanced/understanding-bundles) with a single field: `hostFills`. This connects Signet transactions with Ethereum actions: ```json { "txs": ["0xabc...", "0xdef..."], "blockNumber": "0x123", "hostFills": { "outputs": [...], "permit": { } } } ``` This extension enables atomic cross-chain execution --- the Signet transactions and the necessary host chain actions either all succeed together or the entire bundle fails. A Signet bundle includes: - An array of transactions (`txs`) - Block targeting information (`blockNumber`, `minTimestamp`, `maxTimestamp`) - Optional `revertingTxHashes` identifying Signet transactions allowed to revert without failing the whole bundle. - Optional `replacementUuid` for identifying updated bundles - The `hostFills` field containing required host chain actions (if any). Bundles come in two forms: 1. Bundles _with_ host fills contain signed orders requiring validation. The bundle builder tracks and validates these orders. Host fills are processed alongside bundle transactions. 2. Bundles _without_ host fills handle standard in-network activity. These contain regular Signet transactions and are processed like standard transaction lists. When building systems that handle real value, reliability isn't optional. That's why we've adopted flashbots-style bundle standards: 1. Transactions execute exactly as specified 2. All operations succeed or none happen 3. Transactions only revert when explicitly marked as revertible ## Build with us We're building the simplest and most pragmatic rollup. If you're interested or have feedback, please reach out: - [Developer interest form](https://www.notion.so/1bb3e1cd453981829c41cfc0a005aecf?pvs=21) - [Documentation feedback form](https://www.notion.so/1b33e1cd453981a88fabf6fb6c89f052?pvs=21) -------------------------------------------------------------------------------- ### Optimizing Discovery URL: https://signet.sh/updates/optimizing-discovery/ Published: 2025-10-30 -------------------------------------------------------------------------------- How many network requests should it take to navigate to a page? In the simplest case, navigation resolves in a single network transaction. The browser requests the HTML content for the URL and displays the response. There's no further network activity or processing because everything necessary to render that page is embedded within the HTML itself: ```html

Optimizing Discovery

How many network requests should it take...

``` In practice, a modern page will also display images, load some JavaScript, add some styling, and so on. To do this, the browser will make a bunch of additional requests. Some of these requests will be _render-blocking_, requiring the browser to defer display until they resolve. The rest are nice to have, but the browser can display the page while they load. These additional network requests exchange slower load times for better styling and interactivity. Many tools and frameworks have been built that offer developers a multitude of tradeoffs to choose from. Most of this tooling aims to optimize the _human_ experience of visiting a page. However, most developers now discover content with the help of _robots_ like search and LLMs. These robots present our content directly to the user in a setting largely outside of our control. We want to be certain that the information presented to our users by these robots is correct, relevant, and up-to-date. Optimizing for _humans_ now also requires optimizing for _robots_. This substantially changes the value proposition of our tools. Robots [prefer traditionally structured websites](https://arxiv.org/abs/2505.17125) and don't care about styling or interactivity. They want content, and they want it [as quickly as possible](https://developers.google.com/search/docs/crawling-indexing/large-site-managing-crawl-budget). ## What robots want The needs of search engines are well-documented and understood. For example, Google [only indexes mobile versions](https://developers.google.com/search/docs/crawling-indexing/mobile/mobile-sites-mobile-first-indexing) and uses [Core Web Vitals](https://developers.google.com/search/docs/appearance/core-web-vitals) to determine page rankings. Their [crawl budget documentation](https://developers.google.com/search/docs/crawling-indexing/large-site-managing-crawl-budget) is explicit: > If the site responds quickly for a while, the limit goes up...If the site slows down or responds with server errors, the limit goes down and Googlebot crawls less. Other search engines have similar requirements. Bing determines [crawl frequency from content freshness](https://blogs.bing.com/webmaster/october-2018/bingbot-Series-Optimizing-Crawl-Frequency). Yandex's [2023 source code leak](https://searchengineland.com/yandex-search-ranking-factors-leak-392323) showed page speed directly impacts ranking. Broadly speaking, faster sites get crawled more often and rank higher. The needs of LLMs are opaque. There are two pathways to consider: proactive crawling (for building internal knowledgebases) and reactive searching (for on-demand user requests). Through observation we've learned that they [don't execute JavaScript](https://vercel.com/blog/the-rise-of-the-ai-crawler). If our content requires JS to render, it's invisible to LLMs. Research has found that structured data [reduces hallucinations](https://arxiv.org/abs/2502.13247) and semantic HTML [improves extraction accuracy](https://arxiv.org/abs/2505.17125). Tool-augmented LLM use, like Claude's `web_search`, relies on external search APIs that use traditional search infrastructure. For example, [ChatGPT uses Bing](https://help.openai.com/en/articles/10093903-chatgpt-search-for-enterprise-and-edu) and [Claude uses Brave](https://techcrunch.com/2025/03/21/anthropic-appears-to-be-using-brave-to-power-web-searches-for-its-claude-chatbot/). Others, like Perplexity, have developed their own tools and infrastructure. **Our content needs to be fast, semantic HTML that renders without JavaScript.** ## How fast is fast enough? When optimizing for speed, there's a point beyond which a _human_ can't perceive improvements. _Robots_ have no such diminishing returns. Recall our traditional network transaction: one request, one response. So why not just inline all of our scripts, styles, and so on inside of our HTML? Because of how TCP works. When a browser opens a new connection to a server, the server can't immediately blast data as fast as the network can handle. TCP uses a mechanism called [slow start](https://hpbn.co/building-blocks-of-tcp/) to ramp up gradually, preventing network congestion. [RFC 6928](https://www.rfc-editor.org/rfc/rfc6928.html) defines the initial "congestion window" as 10 segments of 1460 bytes each, so about 14.6KB. If the server tries to send more than that in the first burst, it has to wait for an acknowledgment before continuing. {{< ascii >}} TCP Initial Window First roundtrip capacity: ┌──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┐ │ 1460 │ 1460 │ 1460 │ 1460 │ 1460 │ 1460 │ 1460 │ 1460 │ 1460 │ 1460 │ bytes └──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┘ = 14,600 bytes (14.6KB) Exceed this: Server waits for ACK before sending more {{< /ascii >}} A "roundtrip" is one message _to_ and _from_ the server. Each roundtrip incurs some network overhead. Desktop connections typically see [50-70ms](https://hpbn.co/building-blocks-of-tcp/#measuring-the-speed-of-light) per round trip. Mobile networks are worse, often [100-300ms](https://hpbn.co/mobile-networks/). A 14KB page loads in one round trip. A 50KB page needs four. {{< ascii >}} Impact of Multiple Roundtrips (200ms mobile latency) 14KB page (1 roundtrip): request chunk ░░░░░░░░████████ └────────────────┘ 0 200ms 50KB page (4 roundtrips): request chunk ACK chunk ACK chunk ACK chunk ░░░░░░░░████████ ░░░░░░░░████████ ░░░░░░░░████████ ░░░░░░░░████████ └────────────────┴────────────────┴────────────────┴────────────────┘ 0 200ms 400ms 600ms 800ms {{< /ascii >}} A page under 14.6KB arrives in a single burst: 200ms total. A 50KB page needs four round trips: 800ms of waiting before the browser can start parsing the full response. If we keep every page under 14.6KB (compressed), content will arrive to the browser in a single round trip. From a networking perspective, this is about as fast as we can get and maximizes the time crawlers spend with our content, rather than waiting. ## No Frameworks Fitting within a single roundtrip is a very tight constraint. React and React DOM alone weigh [about 42KB gzipped](https://bundlephobia.com/package/react-dom@18.2.0), almost three times our budget. Many frameworks also need JavaScript to render content, which means LLM crawlers can't read it. We could explore a framework that offers server-side rendering, but for static pages the complexity of SSR and hydration seemed like the wrong tradeoff. Just like like with Signet, our hypothesis is that the complexity of a framework isn't necessary. We opted for plain HTML, CSS, and vanilla JavaScript. ## Getting semantic Sites are commonly built with `
` elements, like this: ```html
Getting Started
Welcome to our documentation...
``` This renders fine in a browser, but neither the browser nor crawlers know what any of it means. Semantic HTML uses elements that describe their purpose. A `