TESTNET ONLINE: PECORINO PECORINO

Solidity Orders

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.

Quick Start

Clone the examples repository:

1git clone https://github.com/init4tech/signet-sol
2cd signet-sol
3forge build
4forge test

Example Contracts

All examples use the Signet Orders system to enable cross-chain, instant, atomic, and composable operations.

SignetStd.sol - System Configuration

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
 1import {SignetStd} from "./SignetStd.sol";
 2
 3contract YourContract is SignetStd {
 4    function createOrder() external {
 5        // Automatically has access to:
 6        // - rollupOrders: The Orders contract address
 7        // - permit2: The Permit2 contract address
 8        // - Other Signet system parameters
 9    }
10}

Flash.sol - Cross-Chain Flash Loans

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
1// Example: Flash borrow WETH for arbitrage
2flashBorrow(wethAddress, amount, arbitrageCalldata);

Source: Flash.sol

GetOut.sol - Quick Exit with Fee

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
1// Exit Signet with a 50bps fee
2getOut(tokenAddress, amount, recipient);

What happens:

  • 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

PayMe.sol - Payment Gating

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
1function executeWithPayment() external {
2    // Create payment order
3    payMe(usdcAddress, 10e6); // Require 10 USDC payment
4
5    // Your contract logic here
6    // Only executes if payment Order is filled
7}

Source: PayMe.sol

PayYou.sol - MEV Capture & Bounties

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
1function executeAndPay() external {
2    // Your contract logic that generates value
3    performArbitrage();
4
5    // Pay searchers for executing
6    payYou(wethAddress, 0.01 ether); // Offer 0.01 ETH bounty
7}

Use cases:

  • Liquidation systems
  • Automated rebalancing
  • Scheduled maintenance
  • MEV extraction from your protocol

Source: PayYou.sol

Building Your Own

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

Testing

Run the test suite:

1forge test
2forge test -vvv  # Verbose output

Format your code:

1forge fmt

Best Practices

Approve Permit2

Before your contract can create Orders, approve Permit2:

1IERC20(token).approve(permit2Address, type(uint256).max);

Handle Order Failures

Orders can fail if no Filler accepts them. Build fallback logic:

1if (!orderFilled) {
2    // Fallback logic
3    revert("Order not filled");
4}

Set Reasonable Outputs

Make sure output amounts are attractive to Fillers:

  • Too greedy: No one will fill your order
  • Too generous: You lose value unnecessarily
  • Just right: Quick fills at fair prices

Gas Optimization

Orders add gas costs. Optimize by:

  • Batching multiple orders when possible
  • Using appropriate deadlines
  • Minimizing output complexity

Next Steps

  1. Clone the signet-sol repository
  2. Read through the example contracts
  3. Modify an example to fit your use case
  4. Test on Pecorino testnet
  5. Deploy to production

For programmatic order creation and filling, check out Rust Orders.