Only this pageAll pages
Powered by GitBook
1 of 49

Sonic

Loading...

Sonic

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Funding

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Technology

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Overview

Sonic is the highest-performing EVM L1, combining speed, incentives, and world-class infrastructure for DeFi. The chain provides 400,000 TPS and sub-second finality.

Developers and users on Sonic are supported by several incentive programs, including:

Sonic delivers exceptional performance, enabling developers to scale their applications without limits while ensuring smooth user experiences.

  • 400,000 Transactions per Second

  • Sub-Second Finality

  • EVM Compatible

  • Solidity/Vyper Support

The of Sonic is S, which is used for transaction fees, staking, running validators, and participating in governance.

Furthermore, the provides developers and users with seamless access to vast liquidity through a secure bridge connected to Ethereum. With a unique fail-safe mechanism, it ensures user assets are protected in all circumstances.

Fee Monetization

Developers earn 90% of the network fees their apps generate.

Innovator Fund

Up to 200 million S to onboard apps to Sonic and support new ventures.

Airdrop

~200 million S to incentivize users of Sonic via an innovative points program.

native token
Sonic Gateway

Introduction

Sonic is the highest-performing EVM layer-1 blockchain, combining speed, incentives, and world-class infrastructure, powering the next generation of DeFi applications. The chain provides 400,000 TPS and sub-second finality.

By combining a novel consensus mechanism with full EVM compatibility, Sonic delivers unparalleled speed, security, and scalability. The is Sonic's native token, used for paying transaction fees, staking, running validators, and participating in governance.

Key Features:

  • Sub-Second Finality Transactions are confirmed and irreversible in under a second.

  • Full EVM Compatibility Deploy your existing Ethereum app on Sonic without changing your code.

Fee Monetization Developers earn 90% of the network fees generated by their applications.

Network Information

  • Network name: Sonic

  • RPC URL: https://rpc.soniclabs.com

  • Explorer URL: https://sonicscan.org

  • Chain ID: 146

  • Currency symbol: S

S token

S Token

The S token is the native token of Sonic. It has multiple roles within the network, such as paying for transaction fees, staking, running validators, and participating in governance.

— Staking — Supply and Tokenomics ‎‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎— Institutional Expansion ‎‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎— Airdrop ‎‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎— Ongoing Funding ‎‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎— Block Rewards ‎‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎— Token Burn — Validator Rewards — Ecosystem Vault

Staking

You can help secure the network and earn rewards by staking your S tokens.

  1. Visit .

  2. Connect your wallet.

  3. Choose a reputable validator and delegate your stake.

Staking your S involves a 14-day waiting period if you choose to withdraw. When staking your S, choose a reputable validator carefully. If your validator is penalized for misconduct or errors in their setup, it could impact your delegated S stake as well.


Supply and Tokenomics

The current total supply of S is approximately 3.8 billion. As decided by multiple governance proposals, the following adjustments have been or will gradually be integrated into the tokenomics of S.

Institutional Expansion

A approved the issuance of $50M in S for the pursuit of an ETF, $100M in S for the pursuit of a Nasdaq DAT, and 150M S tokens for the newly established Sonic USA entity, as part of our institutional expansion into the U.S. capital markets.

The first issuance of 472,372,662.8 S . This covered the full allocation for our Nasdaq DAT and Sonic USA entity. An additional $50 million in S may also be issued to support our pursuit of an S ETF.

The following transactions provide transparency into how the issued funds have been used to date, mainly involving .

  • to old SonicStrategy DAT Multisig

  • to new SonicStrategy DAT Multisig for validator setup

  • to new SonicStrategy DAT Multisig from the old SonicStrategy DAT Multisig

Importantly, if a Nasdaq DAT is not achieved during SonicStrategy’s pursuit, all funds will be returned to the Sonic Foundation to be leveraged for an alternative DAT or burned.

Airdrop

190.5 million S will be issued in phases exclusively used for the . The airdrop features an that rewards active participation and gradually reduces the total supply of S tokens.

The first issuance of 89,778,181.9 S occurred on and .

Ongoing Funding

To fund ongoing growth and expansion, the Sonic network could to:

  • Increase S adoption and global presence

  • Grow the team and scale operations to drive increased adoption

  • Implement robust marketing initiatives and DeFi onboarding campaigns

To fund this program, 47,625,000 tokens will be issued annually for six years, starting six months after Sonic's mainnet launch. Issued tokens will be sent to . The first issuance of 47,625,000 S .

However, to guard against inflation, the network will burn newly issued tokens not used during the year, ensuring that 100% of all newly issued tokens from this initiative are allocated toward network growth rather than being held by the treasury for later use.

For example, if Sonic Labs uses only 5,000,000 tokens in the first year, the network will burn the remaining 42,625,000 tokens.

Block Rewards

were migrated Fantom Opera to Sonic. As validators and stakers moved to Sonic, Opera's block rewards were reduced to zero, and the saved funds are used to reward Sonic validators. The Sonic Foundation will maintain Opera validators for now.

To achieve a 3.5% APR for Sonic without causing further inflation in the first four years, we're reallocating the remaining block rewards from Opera to Sonic, comprising around 70 million tokens per year, which will be distributed as validator rewards over the first four years, avoiding the need to issue new S tokens during this period for block rewards.

As a result, Opera's APR dropped to zero upon Sonic's launch. To preserve value and avoid new inflationary rewards at Sonic's inception, we will not issue new tokens for block rewards during the initial four years, as stated. After that period, S block rewards will resume by issuing new tokens at a rate of 1.75% per year to reward validators.

Token Burn

We have two burn mechanisms in place that will decrease the emission of new S tokens.


Validator Rewards

To help secure the Sonic network by running a validator and staking a certain amount of S, you can earn block rewards as well as transaction fees paid by users on Sonic.

Block Rewards

The target reward rate for validators on Sonic is 3.5% when 50% of the network is staked. The network issues tokens each epoch to provide this, except during Sonic's first four years when rewards stem from block rewards migrated from Opera, .

The reward rate adjusts proportionally, e.g. if all S tokens are staked, the annual reward is 1.75%. Conversely, if only 25% of S tokens are staked, the annual reward is 7%.

Network Fees

Network fees are generated when users pay gas to interact with the network. Validators earn a percentage of these fees, which are distributed equally among all staked S tokens. For a detailed breakdown of how much a validator earns from gas fees, .

Users

  • Bridge to Sonic

  • Earn Airdrop Points

  • Explore Apps

Developers

  • Deploy App

  • Fee Monetization

  • Earn Airdrop Gems

Cover
Cover

Build on Sonic

Sonic offers developers robust infrastructure with 400,000 transactions per second and sub-second finality, ensuring your apps are both fast and scalable.

With full EVM compatibility and support for Solidity and Vyper, Sonic seamlessly integrates with common developer tools such as Chainlink, Safe, Pyth, Alchemy, and more. Additionally, Sonic provides the incentives, such as Fee Monetization, necessary to innovate and thrive in the ecosystem.

Test your contracts on the Sonic testnet first, then deploy to the mainnet when ready. Dive in and explore how you can leverage Sonic's powerful features to bring your ideas to life.

To meet other builders and receive support, join the official Sonic builders group.

Proof of Stake

The Sonic chain is secured using a proof-of-stake (PoS) mechanism.

In PoS on Sonic, validators must lock their S (Sonic's native token); if they act maliciously in the network, they lose their tokens. Validators are incentivized to act in the network's best interest as their own funds are at stake. Since validators do not need to perform computations, this approach is a much more energy-efficient alternative to proof-of-work for achieving resistance to Sybil attacks.

A Sybil attack is an attack where a malicious actor runs a large number of validators to allow them an unsafe amount of influence over the network. PoS makes it costly to set up these validators and allows the network to punish validators for malicious behavior, increasing the costs of attacks.

Sonic requires nodes to lock up at least 500,000 S to validate transactions and produce blocks.

MySonic
governance proposal
occurred on September 4, 2025
SonicStrategy
126,622,348.845 S transfer
500,000 S transfer
126,122,433.845 S transfer
airdrop program
innovative burn mechanism
July 17, 2025
July 31, 2025
issue additional S tokens
this wallet
occurred on June 18, 2025
Block rewards
as outlined above
see here

Users who choose not to wait for the full 270-day maturation period for 75% of their airdrop will lose a portion of their S tokens, which will be burned.

From the 47,625,000 S tokens issued annually in the first six years of Sonic to fund growth, the network will burn any of the tokens not used during the year.

Overview

The Sonic chain provides developers with exceptional scalability and storage capabilities while delivering a fast and seamless user experience.

Sonic achieves 10,000 transactions per second with sub-second finality for immediate, irreversible transactions. There is zero risk of rollbacks or reorganizations, making every transaction final and tamper-proof. Sonic's cutting-edge storage system ensures efficient data management.

Learn more about the Sonic technology stack:

  • Consensus

  • Database Storage

Dispute

If a contract is already registered under a different app in Fee Monetization, your registration attempt will fail with ContractAlreadyRegistered(contract, projectID).

If you believe the contract rightfully belongs to you, file a dispute using the steps below.

  1. Visit the Fee Monetization dashboard and connect your admin wallet

  2. Click My FeeM in the menu and then Create Dispute

  3. Enter your dispute contact email address and the contracts you wish to dispute

  4. Click Submit and pay the 50 S fee, which will be refunded if the dispute is accepted

Once submitted, we will process your dispute as quickly as possible and notify you via email. If resolved in your favor, the dispute fee is refunded and the disputed contracts are moved to your app.

To manually dispute a contract, use the to open a dispute. Attach a refundable dispute fee and call openDispute() providing all the details required to resolve the issue. If resolved in your favor, the dispute fee is refunded back to you and the disputed contracts are moved to your app.

Claim (Season 1)

Claims for the airdrop's first season are now live. Users earned S through Sonic Points and Sonic Gems.

Earned directly by users holding and using whitelisted assets across apps on Sonic.

Earned by apps that drove user activity, based on their performance across key metrics.

Sonic Points

Node Deployment

Nodes are interconnected devices, usually software run on servers, that maintain the Sonic network by storing a full or partial copy of the chain, validating transactions, and ensuring consensus to keep the system secure and decentralized.

Visit the pages below to learn how to deploy archive and validator nodes on Sonic.

Deploy Contracts

At the software level, deploying to Sonic is the same as deploying to any other EVM network.

The only difference is which network you connect to. Use as the connection endpoint for the Sonic testnet or for the mainnet.

For the Sonic testnet, you can use the to obtain an initial amount of S to execute transactions on the testnet.

Here are example configurations for Hardhat to deploy on the Sonic mainnet or testnet:

To deploy, execute npx hardhat run scripts/deploy.js --network sonic.

Fee Subsidies

Objective

Fee subsidies enable users to interact with an app without paying gas fees themselves. Users do not need to hold any native tokens to execute transactions with the app’s contracts. Instead, gas costs are covered by a third party, typically the app’s developers.

Solution

Getting Started

Sonic offers developers two distinct networks to build and deploy their apps. First, the serves as a dedicated environment where you can rigorously test your smart contract code and deployments, ensuring everything functions correctly using faucet tokens.

Once your contracts are thoroughly vetted on the testnet, you can confidently deploy your live apps to the Sonic mainnet, the production environment where end users will interact with your apps.

The following are the network details:

  • Network name: Sonic

  • RPC URL:

Alternative Fee Payments

Objective

Alternative fee payments enable users to interact with an app without holding the network’s primary token (S) to cover gas fees. Instead, gas costs are paid using an alternative method, such as ERC-20 tokens (e.g. stablecoins) or even off-chain settlement. This removes the requirement for users to maintain a balance of the native token.

Database Storage

Sonic uses database storage to store its world state, which includes account information, virtual machine bytecode, smart contract storage, etc. This database has a feature called live pruning, which removes historical data automatically, reducing storage needs for validators as the blockchain grows.

Previously, pruning required validator nodes to go offline, risking financial and operational issues for them. Now, validators can use live pruning without going offline, ensuring continuous operation and saving on disk space and costs by discarding historical data in real-time.

Live pruning works by splitting the database into two types: LiveDB and ArchiveDB. The LiveDB contains the world state of the current block only, whereas the ArchiveDB contains the world states of all historical blocks. Validators use only LiveDB, while have both LiveDB and ArchiveDB to handle historical data requests through the RPC interface.

Sonic's database storage uses efficient tree-like or hierarchical structures, which simplifies data retrieval. Importantly, it still provides cryptographic signatures for a world state and archive capabilities using an incremental version of a prefix algorithm. Additionally, it utilizes a native disk format instead of storing the world state indirectly through key-value stores like LevelDB or PebbleDB.

Integrating Staking

You can build apps on top of Sonic's staking system, such as liquid staking tokens or vaults. All staking operations are managed by the SFC (Special Fee Contract).

  • SFC Address: 0xFC00FACE00000000000000000000000000000000

  • Key Functions:

EVM Compatibility

Sonic is fully compatible with the Ethereum Virtual Machine (EVM). Any smart contract that runs on Ethereum can be deployed on Sonic without modification.

  • Supported Languages Solidity and Vyper

  • Supported EIPs Sonic supports Ethereum's Cancun hard fork features, including PUSH0 opcode (EIP-3855), with the exception of EIP-4844 data blobs. All transactions must have a Chain ID (EIP-155 is enforced).

delegate(validatorID)
: Delegate stake to a validator.
  • undelegate(validatorID, wrID, amount): Begin the withdrawal process.

  • withdraw(validatorID, wrID): Claim unlocked stake after the withdrawal period.

  • pendingRewards(delegator, validatorID): Check claimable rewards.

  • claimRewards(validatorID): Claim pending rewards.

  • Constants Economic parameters like withdrawal period and reward rates are available by calling the constsAddress() on the SFC to get the ConstantsManager contract address.

  • See the API & SDK Reference for the full SFC ABI.

  • Note on PUSH0 Opcode: Sonic's EVM supports the PUSH0 opcode. RPC tests that fail with eth_call are often missing the required block parameter (e.g., "latest"). A correctly formatted call like eth_call with params [{"to": null, "data": "0x5f"}, "latest"] will succeed.

    Proof of Stake
    DisputeResolver
    Airdrop Burn
    Ongoing Funding Burn
    Claim now

    25% of your allocation is claimable now, with the remaining 75% vesting over nine months as an NFT.

    You can trade this NFT on the official Airdrop Order Book by Paintswap.

    Sonic Gems

    There are two ways users can receive S from Gems.

    Tokenized Gems If you used apps that tokenized Gems for their users, head to MySonic to deposit your tokenized Gems and claim wS. 50% is available now, with the rest vesting over 3 months. No minimum claim.

    Non-Tokenized Gems If you used apps that did not tokenize Gems, we will send S directly to them.

    They will handle distribution to their users, with 50% available to apps immediately and the rest vesting over 3 months via LlamaPay. No minimum claim.

    Gems are distributed entirely by developers, not by Sonic Labs.

    Sonic Points
    Sonic Gems

    Archive Node

    Stores the entire history of the chain since the genesis block but does not validate transactions or create new blocks.

    Validator Node Validates transactions and creates new blocks to securely power and maintain the integrity of the network.

    archive nodes

    Please note that the Sonic testnet is a testing playground designed to showcase technology capabilities. The data stored on the network might eventually be deleted, with or without notice.

    https://rpc.testnet.soniclabs.com
    https://rpc.soniclabs.com
    Sonic testnet dashboard
    require("@nomicfoundation/hardhat-toolbox");
    
    // Replace this private key with your Sonic account private key
    const SONIC_PRIVATE_KEY = "YOUR SONIC TEST ACCOUNT PRIVATE KEY";
    
    module.exports = {
      solidity: "0.8.26",
      networks: {
        sonic: {
          url: "https://rpc.soniclabs.com",
          accounts: [SONIC_PRIVATE_KEY]
        }
      }
    };
    require("@nomicfoundation/hardhat-toolbox");
    
    // Replace this private key with your Sonic account private key
    const SONIC_PRIVATE_KEY = "YOUR SONIC TEST ACCOUNT PRIVATE KEY";
    
    module.exports = {
      solidity: "0.8.26",
      networks: {
        sonic: {
          url: "https://rpc.testnet.soniclabs.com",
          accounts: [SONIC_PRIVATE_KEY]
        }
      }
    };
    Fee subsidies can be built on ERC-4337 account abstraction. Rather than broadcasting transactions directly to the blockchain, users submit UserOperations to a bundler. The bundler aggregates these operations into a single transaction and sends it on-chain.

    Within each UserOperation, the user specifies a paymaster contract. This paymaster (not the sender) pays the bundler for the gas used by the UserOperation.

    The paymaster’s primary function is to determine whether a UserOperation qualifies for sponsorship, typically by checking if the operation interacts with the subsidized app. This verification is non-trivial, since users can deploy arbitrary smart account implementations. To prevent abuse, the paymaster must:

    1. Inspect the UserOperation’s calldata to confirm it targets the sponsored contract(s).

    2. Verify that the user’s account is running a pre-approved smart account implementation.

    An example paymaster for sponsoring a single-contract app might look like this:

    contract MyPaymaster is IPaymaster {
    
    
       function validatePaymasterUserOp(
           PackedUserOperation calldata userOp,
           bytes32 userOpHash,
           uint256 maxCost
       ) external view override returns (bytes memory context, uint256 validationData) {
           if (msg.sender != address(entryPoint)) {
               revert InvalidEntryPoint();
           }
           // check if the sender use a whitelisted account implementation
           if (userOp.sender.codehash != keccak256(abi.encodePacked(bytes3(0xef0100), allowedSmartAccountImpl))) {
               revert InvalidAccountCodeHash();
           }
    
    
           // check if userOp.callData targets the whitelisted contract
           checkUserOpCallData(userOp.callData);
    
    
           // check if userOp.gasFees are within limits
           checkUserOpGasFees(userOp.gasFees);
    
    
           return ("", _packValidationData(false, 0, 0)); // accept paying gas
       }
    }
    Solution

    An alternative fee payment system can be built on the same ERC-4337 account abstraction principles used in the fee subsidies mechanism.

    As with subsidies, users submit UserOperations to a bundler rather than sending transactions directly on-chain. The paymaster contract specified in the UserOperation determines whether to cover the gas cost, typically by interacting with the user’s credit source, most commonly an ERC-20 token.

    The paymaster:

    1. Verifies the user has sufficient available credit to cover the estimated gas cost.

    2. Deducts or reserves the required amount from the user’s credit source.

    For ERC-20 token payments, the user must first approve an allowance for the paymaster. When assessing a UserOperation, the paymaster transfers the maximum token amount needed to cover gas fees. Once execution is complete and the actual gas usage is known, the paymaster refunds any unused portion to the user.

    For popular stablecoins (e.g. USDC), a paymaster is already provided by the token issuer. For other ERC-20 tokens, developers can implement a custom paymaster by extending, for example, PaymasterERC20 from OpenZeppelin community-contracts:

    A guide for creating similar paymasters can be found in the OpenZeppelin documentation.

    import "@openzeppelin/community-contracts/account/paymaster/PaymasterERC20.sol";
    
    contract MyERC20Paymaster is PaymasterERC20, Ownable {
       function _fetchDetails(
           PackedUserOperation calldata userOp,
           bytes32 /* userOpHash */
       ) internal view virtual override returns (uint256 validationData, IERC20 token, uint256 tokenPrice) {
           // oversimplified example - real-live paymaster should check liveness and sanity of the price
           uint256 price = oracle.getLatestTokenPrice();
           return (
               ERC4337Utils.SIG_VALIDATION_SUCCESS,
               USDC,
               price
           );
       }
    
       function _authorizeWithdraw() internal virtual override onlyOwner {}
    }

    Explorer URL: https://sonicscan.org

  • Explorer API: https://api.etherscan.io/v2/api?chainid=146

  • Chain ID: 146

  • Currency symbol: S

    • Network name: Sonic Testnet

    • RPC URL: https://rpc.testnet.soniclabs.com

    • Explorer URL: https://testnet.sonicscan.org

    • Explorer API: https://api.etherscan.io/v2/api?chainid=14601

    • Chain ID: 14601

    • Currency symbol: S

    • Faucet:

    • Network name: Sonic Blaze Testnet

    • RPC URL: https://rpc.blaze.soniclabs.com

    • Explorer URL: https://blaze.soniclabs.com/

    • Chain ID: 57054

    • Currency symbol: S

    • Faucet:

    The Sonic Blaze testnet (2.0) will be depreciated soon.

    To meet other builders and receive support, join the official Sonic builders group.

    Sonic testnet
    https://rpc.soniclabs.com

    Pectra Compatibility

    With the Ethereum Pectra upgrade supported in Sonic release 2.1, the network gains full compatibility with ERC-4337, a transformative framework originally introduced on Ethereum.

    ERC-4337 replaces traditional externally owned accounts (EOAs) with smart contract wallets that have programmable authorization logic. This enables advanced features such as:

    • Social Recovery Restore access with help from trusted guardians.

    • Multi-Signature Security Require multiple approvals before executing transactions.

    • Spending Limits Enforce daily/weekly caps on outgoing funds.

    • Token-Based Gas Payments Pay fees in ERC-20 tokens instead of the native token.

    Unlike protocol-level changes, ERC-4337 operates entirely on top of the blockchain. No network hard fork is required, making it immediately compatible with Sonic post-Pectra. It works through a specialized flow involving UserOperations, an alternative mempool, bundlers, and optional paymasters for gas fee handling.

    This upgrade fundamentally improves the Sonic user experience, unlocking customizable, secure, and user-friendly wallets without sacrificing decentralization or performance.


    Core Concepts

    Smart Wallet An ERC-4337 smart wallet extends the functionality of a standard EOA by delegating control to a smart contract. This enables transaction batching, gas sponsorship, and custom permission logic while still functioning like a traditional wallet.

    EntryPoint The EntryPoint contract is the core of ERC-4337. It validates signatures, nonces, and logical rules defined by each wallet. It can also enforce custom conditions such as balance checks, restricted contract calls, or app-specific rules.

    UserOperation A UserOperation is a generalized transaction format for ERC-4337. It contains standard fields like sender, recipient, calldata, maxFeePerGas, maxPriorityFeePerGas, signature, and nonce, along with additional fields such as callGasLimit, verificationGasLimit, and paymasterAndData to support advanced execution logic.

    Bundler A bundler collects UserOperations from the alternative mempool, simulates them for validity, and packages them into a single transaction sent to the EntryPoint. Bundlers may also forward standard transactions to a full node for normal blockchain processing.

    Paymaster A paymaster is a smart contract that sponsors gas fees on behalf of users, allowing them to transact without holding the network’s native token. During validation, the paymaster checks if the operation qualifies for sponsorship and covers the gas cost. To prevent abuse, paymasters stake collateral with the EntryPoint and must maintain a sufficient deposit.


    Related Topics

    • Customize transaction authorization logic with smart contract wallets.

    • Let users interact with an app without paying gas themselves.

    • Monetize app usage via increased gas consumption.

    • Accept ERC-20 tokens or off-chain settlement for gas fees.

    Learn Solidity

    Sonic Labs has partnered with HackQuest to offer a learning track for anyone who is eager to learn Solidity on Sonic, whether they are a beginner or advanced. Start learning now.

    Upon completing the course outlined below, graduates will receive a Sonic Developer Certificate.

    1

    Phase 1

    Web3 Basics.

    2

    Phase 2

    Ecosystem Overview

    3

    Phase 3

    Basic Solidity Syntax

    4

    Phase 4

    Advanced Solidity Syntax

    5

    Phase 5

    Build With Guided Projects

    6

    Phase 6

    Practical Frameworks — Foundry

    7

    Phase 7

    Smart Contract Security

    8

    Phase 8

    Explore More Resources on Sonic

    Account Abstraction

    Objective

    Account abstraction enables users to customize how transactions from their account are authorized. This flexibility supports alternative signing methods, multi-signature requirements, and account recovery mechanisms. Examples include:

    • Alternative Signing Methods Passkey, YubiKey, or TouchID to sign transactions directly in the browser without extensions like MetaMask.

    • Multi-Signature Wallets Requiring multiple signatures before a transaction can be executed.

    • Social Recovery Allowing a group of trusted contacts to override or replace the account’s controlling key.

    Solution

    ERC-4337 introduces a framework where user wallets are implemented as smart contracts. This allows the wallet’s transaction authorization logic to be fully customizable. Transactions are sent as UserOperations and processed according to the smart account’s rules.

    EIP-7702 extends this flexibility by allowing a regular externally owned account (EOA) with a standard ECDSA private key to deploy a smart contract directly into its account. Once a smart account implementation is deployed, the user can send transactions in two ways:

    1. Regular Transactions Signed with their private key.

    2. UserOperations Authorized according to the custom logic defined in their smart account.

    Example Authorization Logic Options

    1. Passkey / YubiKey / TouchID []

      • Signs UserOperations directly in the browser, without extensions like MetaMask.

      • Currently a research project—experimental and not recommended for production.

    2. Google OAuth JWT signing []

    FeeM Vault

    The FeeM Vault is a multisig operated by Sonic Labs. It accumulates 90% of transaction fees generated by core token contracts on Sonic:

    • wS

    • USDC

    • USDT

    • EURC

    • WETH

    • WBTC

    Funds in the FeeM Vault will be strategically deployed to strengthen the Sonic ecosystem, provide targeted support where apps need it most, and enhance asset incentives.

    The tokens that generate the revenue for the FeeM Vault will also shape how it is spent. Apps that integrate and optimize for the tokens above will be first in line to benefit.

    Key areas of deployment include:

    More information about the distribution of funds from the FeeM Vault will be available soon.

    FeeM Vault Flywheel

    The FeeM Vault is designed to compound growth across Sonic apps. As activity around key tokens increases, the Vault fills, and a self-reinforcing flywheel begins to spin:

    1. More usage of key tokens increases the transaction fees redirected to the FeeM Vault.

    2. More revenue in the FeeM Vault means more funding available for apps on Sonic.

    3. More funding for apps leads to more integrations and incentives involving key tokens, attracting more users.

    4. More users drive more activity and usage of those same tokens.

    FAQ

    Check out the most frequently asked questions about Sonic and its S token.

    S Token

    Where can I buy or sell S?

    You can acquire S on decentralized exchanges (DEXs) on Sonic and most centralized exchanges (CEXs).

    Will the S token have any inflation?

    The S token will not experience inflation during the first six months after Sonic's launch. Following that period, per previously approved governance votes to enable an airdrop, ecosystem growth, and validator rewards. To ensure efficient use of any additional tokens, a number of new burn mechanisms and improvements are also outlined in the votes.

    Is there an S airdrop?

    Yes. We're planning an to incentivize users of Sonic.

    Sonic Chain

    Is Sonic EVM compatible?

    Yes. The Sonic chain is fully EVM compatible, allowing any app developed for other EVM chains to be deployed on Sonic without changes in their code.

    Can apps on Sonic be coded with Solidity and Vyper?

    Yes. Since Sonic is EVM compatible, apps can be coded with both Solidity and Vyper.

    How many transactions per second (TPS) can Sonic handle?

    Sonic can process around 400,000 TPS with complete 1-block finality.

    Is there a Sonic testnet?

    Yes. You can immediately access to deploy your apps and experience the speed of Sonic.

    Is there an incentive program for developers to build on Sonic?

    Yes. Sonic Labs is running a massive incentive program, which includes the program that rewards developers with up to 90% of the fees their apps generate, and the that offers up to 200,000,000 S to expedite the immediate adoption of apps to Sonic and support new ventures.

    What are the tooling/infrastructure apps available on Sonic?

    Check out all the tooling and infrastructure in our on MySonic.

    I’m a developer who wants to launch on Sonic, how do I start?

    .

    Audits

    Sonic has undergone extensive security audits across its core components to ensure the highest level of security for our users and developers.

    Sonic Gateway

    The Sonic Gateway is our native bridge between Ethereum and Sonic.

    • OpenZeppelin

    FTM to S Bridge

    The FTM to S bridge enables users to upgrade their FTM on Fantom Opera to S on Sonic.

    Special Fee Contract (SFC)

    The SFC manages staking and validator operations on Sonic.


    Please report bugs to [email protected].

    Wallets

    Sonic supports a range of popular wallets, both for users and institutions. Use the network information below to add Sonic to your wallet.

    • Network name: Sonic

    • RPC URL: https://rpc.soniclabs.com

    • Explorer URL: https://sonicscan.org

    • Chain ID: 146

    • Currency symbol: S

    User Wallets

    Institutional Wallets

    Innovator Fund

    Apply for funding from the Innovator Fund.

    The Sonic Labs Innovator Fund offers up to 200,000,000 S from the Sonic Foundation treasury to expedite the immediate adoption of apps to the Sonic chain and support new innovative ventures.

    Allocations

    Funding from the Innovator Fund is being used to secure the best infrastructure and applications for Sonic, ensuring builders have the tools and capabilities to thrive within today’s ever-challenging marketplace.

    We’re actively engaging with dozens of apps across the industry and top-tier infrastructure providers across on-chain tooling, compliance, native assets, cross-chain technology, wallets, indexes, strategic Web2 partnerships, and more.

    To do so, we’ll work closely with strategic angel investors such as (Curve), (Aave), (Compound), (Gauntlet), and (FRAX), as well as our venture partners , , and .

    Sonic & Sodas

    Apply to Sonic & Sodas with your event.

    The Sonic & Sodas program empowers our community to host developer-focused networking events around the world, funded by Sonic Labs.

    Think of Sonic & Sodas events as grassroots gatherings where collaboration, networking, and innovation thrive, all within the Sonic ecosystem. You host the event, and we provide the funding. Our aim is to cultivate local communities, particularly in tech hubs and around major conferences.

    How It Works

    The process for organizing a Sonic & Sodas event is detailed below.

    1

    Submit Event Proposal

    Got an idea for an event? Awesome! Just or drop into our first for any questions. Tell us how many people you’re expecting, where it’s happening, and any specific support you need.

    2

    Got questions? .

    Network Parameters

    The active network parameter set can be obtained directly from an RPC interface:

    Game Gems

    The second season of the airdrop and Kaito program are ending on November 1, 2025. Future incentive programs will be announced at a later stage.

    Game Gems mark the beginning of a new chapter on Sonic, where blockchain games are not just part of the ecosystem, but central to its growth.

    Just like DeFi apps earn , eligible games on Sonic earn Game Gems, unlocking a share of the S token airdrop. Similar to the existing Sonic Gems, these allocations are designed to be distributed to players, helping bootstrap in-game activity and drive lasting engagement.

    https://testnet.soniclabs.com/account
    https://blaze.soniclabs.com/account
    Account Abstraction
    Fee Subsidies
    Dynamic Fees
    Alternative Fee Payments
  • Signs UserOperations in the browser without MetaMask.

  • Requires publishing the user’s email and account name as part of the JWT on-chain.

  • Relies on an on-chain oracle to provide Google’s current public key (JWKS, rotated every 48 hours).

  • Gas-expensive; suitable for social recovery but not optimal for everyday use.

  • n-of-m signature requirements via Web3Auth

    • Supports conventional social login (e.g. Google account plus additional factors).

    • Depends on the trustworthiness of the third-party service (Web3Auth servers).

  • Social Recovery (ERC-7093)

    • Allows the account owner to designate “guardians” who can replace the owner key.

    • ERC-7093 is currently a proposal without a reference implementation.

    • For EIP-7702 smart accounts, the ability to send regular transactions signed with the account’s private key remains unaffected.

  • account-abstraction-webauthn
    solidity-based-social-auth
    the network will mint S tokens
    airdrop of 190,500,000 S
    the Sonic testnet
    Fee Monetization
    Innovator Fund
    app explorer
    Get started here
    Quantstamp
    Certora
    OpenZeppelin
    Quantstamp
    Michael
    Stani
    Robert
    Tarun
    Sam
    Hashed
    Signum Capital
    UOB Venture Management
    Plan Event

    Once your proposal is approved, start planning. Choose a time that works best — whether it’s breakfast, lunch, or dinner. Select a venue that’s easily accessible and fosters a welcoming atmosphere for networking.

    3

    Get Support

    We’re all in to make your Sonic & Sodas a hit. We’ll boost your event with marketing support, provide promotional materials, and offer educational content tailored to our ecosystem. We’ll also send stickers and swag whenever we can.

    4

    Be Reimbursed

    Once your event’s over, submit your reimbursement request through Request Finance. We’ll get your payment to you in crypto within a week.

    5

    Be Consistent

    Hosting Sonic & Sodas regularly can significantly strengthen the developer community as consistent meetups enable ongoing collaboration and innovation. As your events grow, you may be able to become a community ambassador.

    submit an application
    Telegram chat
    Join our Telegram chat
    Game Gems Calculation

    1. Growth Score

    The growth score uses a transaction-weighted Quick Ratio to evaluate a game’s player dynamics. Specifically, it measures how many new and returning players a game attracts compared to how many users it’s losing or failing to retain.

    This formula is designed to reward both new and established games fairly. To prevent manipulation, the score is capped, and scores cannot fall below zero. The metric is dynamic, with flexibility to adjust time windows, weighting, and inputs as new games join the program.

    Growth Score=min⁡(cap, QuickRatio−1)\text{Growth Score} = \min\left(\text{cap},\ \text{QuickRatio} - 1\right) Growth Score=min(cap, QuickRatio−1)

    QuickRatio=(New Players+Resurrected Players)×Their Transactions(Inactive Players)×Their Transactions \text{QuickRatio} = \frac{(\text{New Players} + \text{Resurrected Players}) \times \text{Their Transactions}}{(\text{Inactive Players}) \times \text{Their Transactions}} QuickRatio=(Inactive Players)×Their Transactions(New Players+Resurrected Players)×Their Transactions​

    2. Activity Score

    The activity score tracks relative player engagement across the ecosystem. It rewards games that command a larger share of total active users in the Game Gems program.

    This helps ensure the reward distribution reflects real-time network activity and user interest.

    Activity Score=Unique Players (Game g)Unique Players (All Games) \text{Activity Score} = \frac{\text{Unique Players (Game } g\text{)}}{\text{Unique Players (All Games)}} Activity Score=Unique Players (All Games)Unique Players (Game g)​

    3. Score and Final Allocation

    Each game (denoted as g) will receive an overall score, calculated as a weighted blend of the growth and activity scores. These weights (wg and wa) are chosen by Sonic Labs to reflect strategic goals and may evolve over time.

    Score(g)=max⁡(0, wg×Growth Score(g)+wa×Activity Score(g))\text{Score}(g) = \max\left(0,\ w_g \times \text{Growth Score}(g) + w_a \times \text{Activity Score}(g)\right) Score(g)=max(0, wg​×Growth Score(g)+wa​×Activity Score(g))

    Final Allocation(g)=(Score(g)/∑g′GScore(g′))×Total Tokens Allocated to Games \text{Final Allocation}(g) = \left( \text{Score}(g) \bigg/ \sum\limits_{g'}^{G} \text{Score}(g') \right) \times \text{Total Tokens Allocated to Games} Final Allocation(g)=(Score(g)/g′∑G​Score(g′))×Total Tokens Allocated to Games

    Game Gems are separate from Sonic Gems and come from a separate prize pool as part of the airdrop.

    Sonic Gems

    And the cycle continues.

    Liquidity Incentives Directing FeeM Vault revenue toward strategic pools to deepen liquidity and reduce borrowing costs.

    Protocol Integrations Funding integrations of core assets like USDC.e, WETH, and wS into apps.

    Cover

    Rabby Wallet

    Cover

    MetaMask

    Cover

    OKX Wallet

    Cover

    Trust Wallet

    Cover

    Bitget Wallet

    Cover

    1inch Wallet

    Cover

    Safe

    Cover

    Safe (Backup)

    Cover

    Fordefi

    Cover

    Fireblocks

    curl -sX POST -H "Content-type: application/json" -d '{"id":1,"jsonrpc":"2.0","method":"eth_getRules","params": ["latest"]}' https://rpc.sonic.soniclabs.com | jq
    {
      "jsonrpc": "2.0",
      "id": 1,
      "result": {
        "Name": "sonic",
        "NetworkID": 146,
        "Dag": {
          "MaxParents": 12,
          "MaxFreeParents": 6,
          "MaxExtraData": 128
        },
        "Emitter": {
          "Interval": 200000000,
          "StallThreshold": 30000000000,
          "StalledInterval": 60000000000
        },
        "Epochs": {
          "MaxEpochGas": 15000000000,
          "MaxEpochDuration": 600000000000
        },
        "Blocks": {
          "MaxBlockGas": 5000000000,
          "MaxEmptyBlockSkipPeriod": 4000000000
        },
        "Economy": {
          "BlockMissedSlack": 50,
          "Gas": {
            "MaxEventGas": 30000000,
            "EventGas": 28000,
            "ParentGas": 2400,
            "ExtraDataGas": 25,
            "BlockVotesBaseGas": 1024,
            "BlockVoteGas": 512,
            "EpochVoteGas": 1536,
            "MisbehaviourProofGas": 71536
          },
          "MinGasPrice": 0,
          "MinBaseFee": 50000000000,
          "ShortGasPower": {
            "AllocPerSec": 1000000000,
            "MaxAllocPeriod": 5000000000,
            "StartupAllocPeriod": 1000000000,
            "MinStartupGas": 560000
          },
          "LongGasPower": {
            "AllocPerSec": 1000000000,
            "MaxAllocPeriod": 5000000000,
            "StartupAllocPeriod": 1000000000,
            "MinStartupGas": 560000
          }
        },
        "Upgrades": {
          "Berlin": true,
          "London": true,
          "Llr": false,
          "Sonic": true,
          "Allegro": true,
          "Brio": false,
          "SingleProposerBlockFormation": false,
          "GasSubsidies": true
        }
      }
    }

    Consensus

    Consensus in a decentralized system is not just a process but a cornerstone of the system. Its mechanism guarantees a consistent and secure blockchain among all participants and ensures the system's integrity and reliability. Consensus ensures that transactions are consistently and securely validated and added to the blockchain.

    It's a critical element for effectively thwarting attempts by malicious actors to manipulate the network or its data. Sonic uses Asynchronous Byzantine Fault Tolerance in combination with directed acyclic graphs to achieve consensus.

    Practical Byzantine Fault Tolerance

    Practical Byzantine Fault Tolerance (PBFT) is a consensus mechanism designed to enable decentralized systems to function correctly in the presence of malicious or faulty nodes. It is named after the Byzantine generals’ problem, which is an idea that illustrates the difficulties of achieving consensus in a decentralized system when some of the participants may be acting in bad faith.

    In a PBFT system, nodes in a network communicate with each other to reach a consensus on the system's state, even when malicious actors are involved. To achieve this, they send messages back and forth that contain information about the system's state and the actions they propose.

    Each node verifies the message it receives, and if it determines the message is valid, it sends a message to all the other nodes to indicate its agreement. In the context of cryptocurrencies, the message with which all nodes must agree is the blockchain, a ledger that stores a history of transactions.

    Before the invention of cryptocurrencies, the major flaw with PBFT systems was their susceptibility to Sybil attacks. If an attacker controlled a sufficient number of nodes, they could control the entire system; there needed to be a deterrent to launch many nodes. Bitcoin first solved this problem with proof-of-work, forcing nodes to invest considerable energy to partake in the consensus.

    Since then, many new solutions have been developed, such as , which forces nodes to deposit tokens with monetary value, which Sonic uses.

    Hence, Practical Byzantine Fault Tolerance (PBFT) is a mechanism to achieve consensus. It forms a functioning decentralized system when coupled with proof-of-work or proof-of-stake to deter participants from messing with the network. However, Sonic has decided to innovate on this mechanism by using Asynchronous Byzantine Fault Tolerance.

    Asynchronous Byzantine Fault Tolerance

    With Asynchronous Byzantine Fault Tolerance (ABFT), nodes can reach consensus independently and are not required to exchange final blocks sequentially to confirm transactions. At the same time, they exchange blocks, which is required to achieve consensus, and this is done asynchronously. Each node verifies transactions independently and is not required to incorporate blocks created by other miners or validators in sequential order.

    This is opposed to PBFT systems, such as Bitcoin, in which the majority of nodes must agree to a block before it becomes final, which they must then sequentially order into their blockchain record. This slows down the network during high traffic; more on this in the consensus mechanism section further below.

    Now that we have a basic understanding of Byzantine fault tolerance, let’s delve into the second part of Sonic’s consensus mechanism, directed acyclic graphs.

    Directed Acyclic Graphs

    A graph is a non-linear data structure used to represent objects, called vertices, and the connections between them, called edges. A directed graph dictates that all its edges, the connections between objects, only flow in a certain direction. An acyclic graph does not contain any cycles, which makes it impossible to follow a sequence of edges and return to the starting point. As such, a directed acyclic graph (DAG) only flows in a certain direction and never repeats or cycles.

    The diagram below is an example of a directed acyclic graph. Each oval is a vertex, and the lines connecting them are edges. The vertices only connect in one direction, downwards, and never repeat.

    In our consensus algorithm, an event containing transactions is represented by a vertex in a DAG, and edges represent the relationships between the events. The edges may represent the dependencies between events indicating the order in which they were added to the DAG.

    Events can be created and added to the DAG concurrently. The blocks do not need to be added in a specific order, which enables the system to achieve faster transaction times. It is not limited by the requirement to incorporate blocks sequentially, as is the case with many of the biggest blockchains currently available.

    Sonic's Consensus Mechanism

    Sonic uses a proof-of-stake, DAG-based, ABFT consensus mechanism. In this mechanism, each validator has its own local block DAG and batches incoming transactions into event blocks, which they add to their DAG as vertices — each event block is a vertex in the validator’s DAG that is full of transactions.

    Before creating a new event block, a validator must first validate all transactions in its current event block and part of the ones it has received from other nodes; these are the event blocks it has received during the asynchronous exchange of event blocks explained in the section above. The new event block then is communicated with other nodes through the same asynchronous event communication.

    During this communication, nodes share their own event blocks, and the ones they received from other nodes, with other validators that incorporate them in their own local DAGs. Consequently, this spreads all information through the network. The process is asynchronous as the event blocks shared between validators are not required to be sequential.

    Unlike most blockchains, this DAG-based approach does not force validators to work on the current block that is being produced, which places restrictions on transaction speed and finality. Validators are free to create their own event blocks that contain transactions and share these with other validators on the network asynchronously, creating a non-linear record of transactions. This increases transaction speed and efficiency.

    As an event block is sent and propagated across validators, it becomes a root event block once the majority of validators have received and agreed upon it. This root event block will eventually be ordered and included in the main chain, which is a blockchain that contains the final consensus among all event blocks that have become root event blocks.

    Every validator stores and updates a copy of the main chain, which provides quick access to previous transaction history to process new event blocks more efficiently. As such, Sonic's consensus mechanism combines a DAG-based approach that allows validators to confirm transactions asynchronously, which greatly increases speed, with a final blockchain that orders and stores all final transactions immutably and indefinitely.

    Currently, the process of submitting a transaction and having it added to the Sonic main chain through the consensus mechanism takes approximately 1-2 seconds. This involves the following steps:

    1. A user submits a transaction

    2. A validator node batches the transaction into a new event block

    3. The event block becomes a root event block once the majority of nodes have received it

    4. The root event block is ordered and finalized into the main chain as a block

    When a user explores Sonic through a , they view the final blocks on the Sonic main chain. Event block generation and exchange in validators' DAGs is an internal process only and is not visible to end users.

    To better understand the technical aspects of Sonic's consensus mechanism, review the paper on Fantom Opera's consensus mechanism, as Sonic's design is a continuation of it:

    .

    Verify Contracts

    Verifying your smart contract makes its source code publicly visible and auditable on the block explorer, creating transparency and trust. Here are the recommended methods to verify contracts on the and the .

    — — — — —

    Method 1. Hardhat Verification (Recommended)

    The most streamlined way to verify contracts is using Hardhat with hardhat-toolbox:

    Gas Pricing

    Gas and Fees

    • Fee Model Sonic uses a Base Fee + Priority Fee model similar to Ethereum's EIP-1559.

    • Fee Distribution Unlike Ethereum, the Base Fee is not burned

    Upgrade Instructions (2.1.2)

    This guide describes the steps for upgrading a Sonic mainnet node to the latest 2.1.2 version, which introduces the to the Sonic network.

    Once upgraded, your nodes will continue to operate on the current mainnet until the full transition. The upgrade is backward compatible, meaning you can upgrade now without any interruption.

    The guide covers the following steps:

    Version History

    The following version history documents the Sonic client (the node software that powers the Sonic mainnet) including its virtual machine, database storage, and consensus mechanism.

    Version
    End of Development
    Release Date
    Change Logs
    Commits
    . Instead, 90% of all transaction fees are sent to the FeeM treasury for developers and 10% are distributed to validators.
  • Gas Power Each validator has a "gas power" budget that refills over time, based on their stake. This prevents any single validator from congesting the network. If a validator runs out of gas power, they may temporarily be unable to emit events containing large transactions, resulting in a Not enough gas power to emit event warning.

  • Gas Estimation (eth_estimateGas)

    While eth_estimateGas is fully supported, its estimates can sometimes be inaccurate for complex transactions whose gas usage depends on the current on-chain state.

    • The Problem The state of the chain can change between the time of gas estimation and the time of transaction execution. For contracts like a UniswapV3Pool, a change in the pool's state can alter the execution path and, consequently, the gas required.

    • The Symptom This can lead to random out of gas transaction reversions.

    • The Solution For transactions with state-dependent gas costs, it is best practice to add a buffer (e.g., 20-30%) to the estimated gas limit to ensure successful execution. Unused gas is refunded.

    Frequently Asked Questions

    Why does eth_maxPriorityFeePerGas sometimes return 0x1 (1 wei) while other times it returns larger values?

    This is expected behavior on Sonic. The value 0x1 (1 wei) is the correct minimum gas tip estimation. Unlike Ethereum where users compete for block space, Sonic has much higher throughput, so there's usually no competition. The method returns the minimum tip needed for inclusion in a block. It only returns higher values when the network experiences higher load, which is rare on Sonic.

    Isn't 1 wei too low? Gas tips are usually in GWei magnitude on other chains.

    While it may seem unusually low compared to Ethereum, 1 wei is sufficient on Sonic because:

    • Sonic has significantly higher throughput than Ethereum

    • There's rarely competition for block space

    • Transactions are included so quickly that tipping for priority is usually irrelevant

    • The method name is somewhat misleading - it returns an estimate for inclusion, not a maximum you can set

    What's the difference between the block base fee and the fee returned by eth_feeHistory?
    • Block base fee: Usually at it’s current minimum of 50 GWei (0xbebc200 in hex) on Sonic

    • eth_feeHistory and/or eth_gasPrice: Returns 55 GWei (0xcce416600 in hex), which is base fee + 10% buffer

    • The 10% buffer is added to prevent transaction rejection due to potential price fluctuations

    • This buffer ensures transactions won't be rejected as "underpriced"

    Why are my transactions being rejected as "underpriced"?

    This typically happens when you use the raw block base fee (50 GWei) without adding a buffer. To avoid this:

    • Use eth_feeHistory which already includes a 10% buffer (55 GWei)

    • Or use eth_gasPrice which also returns the buffered value

    • If calculating the gas fee cap manually, add at least 6% to 10% buffer to the base fee

    • The transaction pool requires at least 5% buffer above the base fee to accept transactions

    How should I calculate gas fees for Sonic transactions?

    For Type 1 transactions:

    • Gas Price = Base Fee + >5% Buffer (10% recommended) + Priority Fee

    • Example: 55,000,000,000 + 1 = 55,000,000,001 wei (0xcce416601)

    For Type 2 (EIP-1559) transactions:

    • maxFeePerGas (GasFeeCap) = Base Fee + Priority Fee = 55 GWei + 1 wei

    • maxPriorityFeePerGas (GasTipCap) = 1 wei

    Why doesn't the base fee change dynamically on Sonic?

    The base fee on Sonic is configured with a minimum of 50 GWei and doesn't change because:

    • Network bandwidth is nowhere near saturated

    • The algorithm only increases fees when network gas budget spendage exceeds 50%

    • Sonic has a much larger gas budget to spend

    • The minimum prevents the price from dropping to dust levels, which could enable attacks

    Why does gasUsedRatio show 99% if the network isn't congested?

    This is due to how Sonic builds blocks:

    • Blocks are fitted to transactions, not pre-allocated

    • Unlike Ethereum's EIP-1559 premise, this doesn't indicate congestion

    • The high ratio doesn't trigger base fee increases because the network has ample capacity

    • This is a quirk of Sonic's block construction method, not an indicator of network load

    What's the recommended approach for gas pricing on Sonic?
    1. Use RPC suggestions directly:

      • eth_gasPrice or eth_feeHistory for base fee (includes 10% buffer)

      • eth_maxPriorityFeePerGas for priority fee (usually 1 wei)

    2. Optional adjustments:

      • Some projects add 2% additional slippage for extra safety

      • This is generally not necessary on Sonic

    3. Key points to remember:

      • All RPC values are in wei, not GWei

      • Don't convert or modify the hex values returned by RPC

      • The suggested values already include appropriate buffers

    Why does Sonic add a 10% buffer to gas price suggestions?

    The buffer exists because:

    • Validators reject transactions with less than 2% buffer above the previous block's base price

    • The transaction pool requires 5% buffer to accept and advertise transactions

    • Sonic's asynchronous consensus creates a pipeline of potential blocks 3 frames wide

    • The buffer ensures transactions won't be rejected during this multi-block resolution process

    • It's safer to suggest a fee cap with buffer than to require clients to calculate adjustments

    • Remember that maxFeePerGas is the maximal gas fee you accept, not the fee you pay

    Common Troubleshooting Tips

    1. Hex Conversion Issues Ensure proper hex to decimal conversion (0xcce416600 = 55,000,000,000 wei, not 54,816,600,000)

    2. Use Suggested Values Don't use raw block base fee; use RPC-suggested values that include buffers

    3. Minimum Tip Is Fine Don't increase priority fee unless you specifically need priority during high load

    4. Check Transaction Type Ensure you're setting the correct fields for Type 1 vs Type 2 transactions

    proof-of-stake
    block explorer
    Lachesis: Scalable Asynchronous BFT on DAG Streams
    A validator’s block DAG
    Source: Central Blockchain Council of America

    Install Hardhat toolbox:

    1. Configure hardhat.config.js:

    1. Store your SonicScan API key in a .env file:

    1. Verify your contract:

    Method 2: Programmatic Verification

    For automated deployments, you can verify contracts programmatically in your deployment scripts:

    Method 3: Manual Verification

    If automated methods fail, you can verify manually through the explorer interface:

    1. Go to the Sonic explorer (or the testnet explorer)

    2. Navigate to your contract address

    3. Click the Contract tab and Verify & Publish

    4. Fill in the verification details:

      • Contract address

      • Compiler type (single file recommended)

      • Compiler version (must match deployment)

      • Open-source license

      • Optimization settings (if used during deployment)

    5. If your contract has constructor arguments:

      • Generate ABI-encoded arguments at e.g.

      • Paste them in the Constructor Arguments field

    6. Complete the captcha and submit

    Method 4: Flattened Source

    For contracts with complex dependencies that fail standard verification:

    1. Install Hardhat flattener:

    1. Flatten your contract:

    1. Clean up the flattened file:

      • Keep only one SPDX license identifier

      • Keep only one pragma statement

      • Use this file for manual verification

    Troubleshooting

    Common verification issues to check:

    • Compiler version must match deployment exactly

    • Optimization settings must match deployment

    • Constructor arguments must be correctly ABI-encoded

    • Library addresses must be provided if used

    • Source code must match deployed bytecode exactly

    • Flattened files should not have duplicate SPDX/pragma statements

    Sonic mainnet explorer
    Sonic testnet explorer
    Method 1: Hardhat Verification
    Method 2: Programmatic Verification
    Method 3: Manual Verification
    Method 4: Flattened Source
    Troubleshooting
    Restart Sonic Node With New Version and Synchronize

    Reach out to Seg on Telegram for support.

    Upgrade Steps Overview

    1. Update your operating system.

    2. Verify the version and upgrade the Golang version to v1.24 or newer as needed.

    3. Obtain the new Sonic release v2.1.2 source code from GitHub.

    4. Build the source code into a binary client.

    5. Update the active Sonic binary to the new one, and verify the proper version is used.

    6. Stop the currently running client gracefully.

    7. Verify the client is not running.

    8. Validators, pay attention to your node being recognized as by the network before you proceed.

    9. Start the node with the new Sonic client version.

    10. Verify the new version is up and running.

    1. Build Sonic Client and Tooling

    Building the Sonic client binary requires the essential software compilation tools and the Go language version 1.24 or newer to be available. Please refer to your Linux distribution manuals to obtain the development tools on your system.

    Make sure you use a clean copy of the Sonic client source code from the official GitHub repository. A modified client may lead to an inconsistent state, which will disconnect your node from the network.

    Build the Sonic client:

    1. Download the latest Sonic client source code from the official GitHub repository. git clone https://github.com/0xsoniclabs/sonic.git

    2. Switch to the most recent Sonic release. cd sonic && git fetch --tags && git checkout -b v2.1.2 tags/v2.1.2

    3. (Optional) Verify your source code consistency. git status && git log -n1

      On branch v2.1.2 nothing to commit, working tree clean

      commit 7f4da1db9c7b12b17fbeaf874bde7f2aff6b1192 (HEAD -> v2.1.2, tag: v2.1.2)

    4. Build the Sonic binary using the provided configuration. make all

    5. Check the Sonic binary version (the most recent version is v2.1.2). build/sonicd version

    6. (Optional, root) Transfer the new binaries to the bin folder for system-wide access. sudo mv build/sonic* /usr/local/bin/

    If you are reusing your existing Sonic client source code clone with a patch applied, this patch may prevent you from properly switching to the latest release.

    We recommend either deleting the old source code repository and downloading the latest one or cleaning up your local copy using: git checkout -- .

    2. Prime Sonic State DB From Genesis File (Optional)

    This step applies only if you did not run the client before or you want to launch with a new, clean copy of the Sonic database.

    Note that the database of the Sonic client versions 2.0.1 to 2.0.7 is fully compatible with the new Sonic client version v2.1.2. If your node has been running one of the versions v2.0.1 to v2.0.7, and the node has been shut down gracefully, your database can be reused, and you can skip this step.

    Download the most recent Sonic network genesis file. Based on your node designated feature set, you need to choose between “pruned” and “full” versions of the genesis file. The pruned one is used by validators so that the database footprint is minimal. The full version contains all the network history and is used for the archive node.

    The genesis file will be used to prime your database and will allow you to join the network and synchronize with it after priming. Please double-check the downloaded genesis file using the provided checksum.

    You can obtain the selected genesis file here:

    • https://genesis.soniclabs.com/latest-sonic-full.g

    • https://genesis.soniclabs.com/latest-sonic-pruned.g

    1. Download the genesis file. wget https://genesis.soniclabs.com/sonic-mainnet/genesis/sonic-38000-full.g

    2. (Optional) Download the genesis checksum file. wget https://genesis.soniclabs.com/sonic-mainnet/genesis/sonic-38000-full.g.md5

    3. (Optional) Validate the genesis file consistency. md5sum --check sonic-38000-full.g.md Expected output is: sonic-38000-full.g: OK

    Prime Sonic Database From Downloaded Genesis

    Use the sonictool app (created during the building process as build/sonictool) to prime a validated archive state database for the Sonic client.

    • Start the genesis expansion for archive mode. GOMEMLIMIT=50GiB sonictool --datadir --cache 12000 genesis --mode rpc

    • Start the genesis expansion for validator mode. GOMEMLIMIT=50GiB sonictool --datadir --cache 12000 genesis --mode validator

    The last step of the genesis processing is the state validation. Please check that the output log contains a message with the correct root hash:

    StateDB imported successfully, stateRoot matches module=gossip-store index=42999003 root="6ee505...b8e7c0"

    3. Restart Sonic Node With New Version and Synchronize

    With the Sonic node binary created and the state database available, you are ready to start the node on the new version and synchronize its state with the network.

    1. Stop Current Node

    Stop the running instance gracefully. If you use Systemd manager to handle the Sonic node control, execute the stop procedure: systemctl stop sonicd

    Other management systems may require different shutdown procedures. You may also use the general OS termination signal via pkill sonicd. But in this case, you need to make sure the client was terminated, and the control system did not attempt to restart it automatically.

    Your Sonic node may need up to several minutes to close gracefully based on your system, configuration, and load. Please make sure your node is not closed forcefully. Your database would become corrupted otherwise.

    Wait until the node terminates gracefully. Make sure the node is not running: ps aux|grep sonicd.

    This step is extremely important for validators. If you run more than one client instance with the same validator key unlocked, your nodes may unintentionally violate the network rules, and your stake may be lost.

    2. Start New Node

    Use the node database path (<datadir>) from the previous installation or the new expansion created in the previous step.

    Start the node using the new client version. systemctl start sonicd

    Runtime Settings

    Use ≈90% of the RAM as the GOMEMLIMIT value. The limit should always be set. If not done correctly, your node may experience random crashes and subsequent state database corruption. Use ≈12 GiB of the RAM as the --cache value.

    Replace the <datadir> with the correct path to the database. We recommend that validators use the --mode validator flag to obtain a smaller database footprint. Different starting flags may need to be added to start an archive node with Web3 RPC and WebSocket interfaces on the node.

    Please obtain and explicitly specify the external IP address of your node as a starting flag to help with the inter-node peer-to-peer connectivity.

    GOMEMLIMIT=50GiB sonicd --datadir <datadir> --cache 12000 --nat extip:<public external IP address>

    Ethereum Prague feature set
    Build Sonic Client and Tooling
    Prime Sonic State DB From Genesis File (Optional)

    May 26, 2025

    • Synchronized access to cached block hashes to prevent rare incorrect RPC returns

    • Added NoArchiveError check before sending block notifications

    • Updated Tosca dependency

    • e44b0188 – Update Tosca dependency

    • 00c1f2af – Synchronize cached block hash access (#209)

    • 124dc66e – Add NoArchiveError check for notifications (#214)

    • a4e31329 – Update to v2.0.6-dev (#217)

    v2.0.5

    April 11, 2025

    April 28, 2025

    • Verified archive block height before sending subscriber notifications

    • Switched eth_call simulation to GETH for large code handling in state override

    • Fixed test infrastructure and updated Go to v1.24

    • ea9e3631 – Add missing dependency

    • 2d9284a8 – Use GETH for eth_call with large code (#189)

    • 135b69cc – Fix BlockInArchiveTest infra & Go 1.24

    • e95926e4 – Update indirect dependencies (#121)

    v2.0.4

    March 15, 2025

    March 26, 2025

    • Enabled transaction replay on empty blocks

    • Added block overrides for RPC calls

    • Updated NoBaseFee VM parameter for transaction replay

    • #26 – Replay transactions on empty blocks

    • #30 – Add block overrides for RPC

    • #104 – Update NoBaseFee VM config

    v2.0.3

    Feb 6, 2025

    Feb 19, 2025

    • Updated go-ethereum dependency to add on-curve check for unmarshaled public keys

    • Improved intrinsic gas error detection

    • Added SetStorage on Carmen adapter

    • Allowed profiler/tracer stop calls even if never started

    • ecc88ecd – Fix version commit/date (#15)

    • 2340cc37 – Accept profiler/tracer stop calls (#17)

    • 325fb5ea – Implement SetStorage on Carmen adapter (#2)

    • 8cc06953 – Update go-ethereum for on-curve check (#5)

    v2.0.2

    Jan 23, 2025

    Jan 31, 2025

    • Enhanced RPC gas capping

    • Added getAccount RPC method

    • Improved finalized/safe block tag handling

    • Reduced event payload fetching during streaming

    • 19dc2691 – Remove dev from meta version (#394)

    • 3f86ba1c – RPC gas capping (#391)

    • b9545c63 – Implement getAccount RPC (#370)

    • 1a233d03 – Update version to v2.0.2 (#387)

    v2.0.1

    -

    Dec 2, 2024

    -

    -

    v2.0.0

    -

    Nov 29, 2024

    -

    -

    v2.0.7

    June 26, 2025

    TBA

    • Improved error handling in debug_traceBlock — now uses error field and supports empty blob cases

    • 252c9ee0 – Fix error handling in debug_traceBlock (#307)

    v2.0.6

    May 6, 2025

    Sonic Airdrop

    Claims are live for season one. Learn more.

    The second season of the airdrop and Kaito program are ending on November 1, 2025. Future incentive programs will be announced at a later stage.

    The S airdrop will distribute 190,500,000 S tokens to incentivize users of Sonic. The airdrop will be distributed using Sonic Points, Sonic Gems, and Game Gems.

    The S airdrop spans multiple seasons, with an undisclosed amount of the total airdrop allocated to each season. The first season ended on June 18, 2025, and the second season began immediately after.

    Visit the to track your points.

    For historical information about previous seasons of the airdrop, find the relevant pages here:

    The airdrop will also reward historical activity on Opera, participation on Sonic Arcade, and minters of the exclusive Shard NFT.

    Distribution

    For season 1 of the airdrop, 25% of your allocation is immediately available, while the remaining 75% vests over 270 days as NFT positions that are tradable on the by Paintswap.

    A linear decay mechanism applies to the vested portion, allowing you to claim early at the cost of a penalty that burns a portion of your tokens. This approach prevents sudden surges in circulating supply by burning tokens from users who choose to claim early. It also incentivizes recipients to stay active on-chain while waiting for an optimal time to claim the remainder of their allocation.

    The chart below illustrates how many tokens will be burned based on when users choose to claim their vested airdrop allocation.

    The above structure currently applies only to season 1, and the distribution for season 2 may differ as we evaluate the impact of the distribution model and optimize the reward structure accordingly.

    Burn Amount and Examples

    Day
    Burn Amount

    Andrew earns 1,000 S in the Sonic airdrop. Andrew can claim his 25% liquid allocation immediately and receive 250 S in his wallet. 90 days pass and Andrew returns to the claim portal, deciding he would like the rest of his airdrop. As 90 days have passed by, he can claim 249.75 S tokens (33.3 of the remaining 750 token allocation) but must burn 500.25 S (66.7% of his locked allocation).

    Bob earns 10,000 S in the Sonic airdrop. Bob can claim his 25% liquid allocation immediately and receive 2,500 S. Bob is excited to use his S in the ecosystem and decides he would like all of his eligible airdrop allocation after day 30. Bob claims again (the final 75% portion), receiving 1,110 S and burning 6,667.5 S (88.9% of the final portion).

    Data Collection

    We are working with and to manage and oversee our points and airdrop designs through data-backed decision-making.

    OpenBlock’s data-driven incentive modeling platform powers over $2B in annual incentive spend and has been a leading provider of rewards design and efficacy analysis for leading protocols in the space including EigenLayer, Lido, Linea, Mode, Arbitrum, Solana, Sui, and many others. To initiate and sustain its ecosystem, Sonic will utilize OpenBlock’s incentive modeling frameworks, ensuring continuous and balanced growth for all actors in the system.

    Sentio is an industry-leading indexing service that aids in streamlining continuous point tracking, helping retrieve historical states of all user positions to update user points upon every interaction. With its high-performance database infrastructure, engineered to handle queries at unprecedented speeds, Sentio enables the onboarding of tens of thousands of new users easily and efficiently.

    Legal Provisions

    As part of the Sonic Foundation’s research and commitment to this airdrop, we have sought legal opinions to ensure its success.

    The program will likely need to exclude any sanctioned country or person including all those who are citizens or residents of or residing in (the “Restricted Countries”): Belarus, Burundi, Central African Republic, Congo, Cuba, DPRK (North Korea), Guinea, Guinea-Bissau, Iran, Iraq, Lebanon, Libya, Mali, Myanmar (Burma), Republic of South Sudan, Russia, Somalia, Sudan, Syria, Ukraine, the Crimea, Donetsk, and Luhansk regions of Ukraine, Venezuela, Yemen, or Zimbabwe.

    These potential provisions may include:

    • Geoblocking: Implementing geo-blocking measures for all restricted countries

    • Self-declaration: Requiring participants to say they are not from one of the restricted countries

    • Discretionary exclusion: The Sonic Foundation reserves the right to exclude any wallet address at its sole discretion

    There will be a comprehensive set of terms and conditions provided at the program’s launch.

    Tooling and Infra

    Explore the tooling and infrastructure platforms currently available on Sonic below. This list is regularly updated as new projects integrate the Sonic chain.


    Automation/VRF
    • Gelato

    Data Indexers
    Development Tools
    Explorers
    Interoperability
    Oracles
    RPCs

    Official RPC by Sonic Labs.

    • wss://rpc.soniclabs.com


    On-Ramps

    Sonic Gateway

    — Quick Overview — Introduction — Fail-Safe Mechanism — Fast Lane — Looking Into the Future — Frequently Asked Questions

    Quick Overview

    The Sonic Gateway is our native bridge that facilitates token transfers between Ethereum and Sonic. The bridging process consists of three steps:

    1. Deposit Deposit your assets into the bridge, which takes ~15 minutes on Ethereum to achieve finalization and only ~1 second on Sonic.

    2. Heartbeat After your deposit is confirmed, your assets will be bridged at the next heartbeat, which are intervals that bridge user assets in batches to ensure gas efficiency. A heartbeat occurs every ~10 minutes from Ethereum to Sonic and ~1 hour the other way. You can pay a Fast Lane fee to trigger an immediate heartbeat.

    3. Claim Claim your bridged assets on the destination chain. That’s it! You’re now free to explore the Sonic ecosystem with your new assets.

    Sonic Gateway uses for USDC transfers.

    Introduction

    In today’s evolving blockchain landscape, a native, secure bridge is critical for ecosystem health, ensuring true interoperability and preventing network isolation. Yet, many current solutions on both layer 1S and layer 2S compromise security and speed —resulting in over to bridge hacks.

    The Sonic Gateway is a revolutionary, secure bridge between Ethereum and Sonic that offers:

    • Security: The Gateway includes a fail-safe mechanism that safeguards user assets. If the Gateway experiences prolonged failure (14 consecutive days), users can recover their bridged funds on Ethereum.

    • Speed: Asset bridging is processed in intervals called "heartbeats" to ensure gas efficiency — every 10 minutes from Ethereum to Sonic and hourly in reverse.

    Additionally, the Gateway makes Sonic an active participant on Ethereum as it spends ETH through its contracts.

    Fail-Safe Mechanism

    The Sonic Gateway includes a fail-safe mechanism that allows users to retrieve bridged assets on the original chain if the Gateway experiences a failure. In the highly unlikely event that the Gateway or the Sonic chain is down for 14 consecutive days, users are able to reclaim their bridged assets on Ethereum.

    The 14-day period is immutable and cannot be altered by Sonic Labs or any third party after deployment. Importantly, this period is not intended as a contest period but rather as an essential feature that ensures users retain custody of their bridged funds on the originating chain.

    Fast Lane

    Assets bridged through the Sonic Gateway are processed in intervals called "heartbeats", ensuring gas efficiency by bundling bridging transactions together. For assets moving from Ethereum to Sonic, these heartbeats occur every 10 minutes, while Sonic to Ethereum heartbeats occur every hour.

    During each interval, all queued transactions are processed simultaneously. While this system reduces costs, it may introduce waiting periods for users needing their assets bridged immediately. To address this, Fast Lane allows users to bypass the wait for a small fee and have their bridge transaction processed instantly.

    Fast Lane works by adding an additional heartbeat to the Gateway. This means all other queued assets waiting to be bridged are also processed immediately, effectively accelerating the entire network. By using Fast Lane, users not only avoid delays and seize timely opportunities but also contribute to the broader ecosystem's efficiency, ensuring faster bridging for everyone involved.

    Looking Into the Future

    By enabling canonical access to native assets from other layer-1 platforms, the Gateway fosters a secure and thriving economy on the Sonic network.

    Users can directly access these canonical assets on Sonic while maintaining asset security. The Sonic Gateway thus provides safe access to high-demand assets that natively exist outside the Sonic network.

    Frequently Asked Questions

    Does the Sonic Gateway also secure third-party bridges?

    No, only assets bridged through the Sonic Gateway are secured by the fail-safe mechanism. Additionally, if a user spends the tokens bridged through the Sonic Gateway, e.g. by swapping to another token, these tokens may not be recoverable. In the future, Sonic Labs may provide specific recovery mechanisms for some financial protocols on Sonic.

    Does Sonic rely on the state of Ethereum?

    No, Sonic operates independently as its own layer-1 platform and does not rely on Ethereum’s state. Instead, the Sonic Gateway uses Merkle proofs on both Ethereum and Sonic to verify the rightful owners of bridged assets. These assets can be redeemed on Ethereum by their rightful ownership regardless of the Sonic Gateway’s status.

    Does Sonic store data on Ethereum?

    L2 platforms store their transactions on Ethereum, using methods like blobs, which allow these transactions to be reconstructed and contested. This is crucial for resolving any security issues that may arise after the transaction is submitted by the user (e.g. if a transaction is challenged during the 7-day period). However, this approach leads to substantial storage demands on Ethereum, costing millions annually.

    Our approach is more efficient as we store only a Merkle root hash (256-bit) and the block heights of both blockchains (2x64-bit) at regular intervals (e.g. hourly) through the Sonic Gateway, which uses Sonic’s own trusted validator set. This significantly reduces data storage, requiring only about 1 KB per day (or 407 KB per year).

    Note: We do not retain previous hashes; each new update through the Sonic Gateway overwrites the existing hash and block heights in the Gateway’s smart contracts. The full historical states and transactions remain accessible via an untrusted channel as an archive node.

    Troubleshooting

    • Transaction Stuck in Heartbeat The relay service that processes heartbeats may occasionally experience downtime. If your transaction appears stuck for more than an hour, please check our official channels for status updates. The service is monitored and will be brought back online promptly.

    • Claiming From a Multisig While possible, it requires careful proof generation. For the smoothest experience, we recommend using a standard EOA wallet with our Gateway UI.

    Fee Monetization

    Apply to Fee Monetization.

    Fee Monetization (FeeM) on Sonic lets builders earn 90% of the network fees their apps generate — creating a sustainable revenue stream without relying on fundraising. Inspired by Web2 models like YouTube, FeeM rewards developers for the traffic they drive.

    FeeM also challenges the extractive "app chain" model by allowing builders to earn 90% of their app's network fees without the need to launch a separate chain. This approach removes the high costs, infrastructure overhead, and interoperability challenges typically associated with app chains.

    By integrating monetization directly into the network layer, FeeM simplifies revenue capture and supports scalable, efficient app development within a unified, developer-friendly ecosystem.

    Flow of Fees

    1

    Transaction Submitted

    A user initiates a transaction on an app and pays a gas fee in S tokens.

    2

    Double-Spend Dilemma

    In Fee Monetization, double counting is prevented by accurately tracking gas consumption within the virtual machine. The system traces all internal calls in a transaction and splits the reward based on the gas each sub-operation consumes.

    This ensures that the sum of rewards across different projects never exceeds the total transaction fee. An example is given below.

    • A trade consumes 100,000 units of gas with a total FeeM reward of 0.017 S.

    • Inside this transaction, there are operations related to two projects: Project A and Project B.

    • Project A, the DEX aggregator, is responsible for consuming 37,000 units of gas, while Project B, the liquidity pool on the DEX with which the aggregator interacts, uses 63,000 units of gas.

    • The total reward is split based on the gas consumption:

    The chart below illustrates how the FeeM oracle infrastructure traces each sub-operation and distributes the transaction fee spent on the calls based on gas consumed.

    Frequently Asked Questions

    My app uses an upgradeable (proxy) contract. Should I register the implementation too?

    Typically, you only need to register the proxy. Gas consumed by the implementation via delegate-call will be attributed to the proxy address.

    What if my app deploys many user-specific contracts?

    If those user contracts act as proxies calling a small set of implementations, you only need to register the main implementation proxies. You’ll receive rewards for all the gas consumed within them.

    How do I claim my rewards?

    You initiate a claim transaction on the FeeM contract. The oracles confirm your gas usage, and after enough confirmations, your share is transferred to your rewards recipient. You may want to check the for a user-friendly claim UX.

    What if I don’t claim my rewards immediately?

    There is no deadline. Unclaimed rewards stay in the FeeM contract until the rightful project claims them.

    Why do my rewards stay the same over a longer time period?

    FeeM processes rewards similarly to the staking rewards via the SFC contract. The accumulated rewards are updated after the active epoch is sealed and confirmed.

    Questions? Join on Telegram.

    Sonic Points

    This page is specific to season 2 of the airdrop.

    The second season of the airdrop and Kaito program are ending on November 1, 2025. Future incentive programs will be announced at a later stage.

    Sonic Points are user-focused airdrop points that can be earned as part of the ~200 million S airdrop. Designed to boost liquidity on Sonic and strengthen its ecosystem, our points program positions Sonic as a premier hub for DeFi enthusiasts and users seeking to maximize the potential of their assets.

    To earn Sonic Points, deploy whitelisted assets across various DeFi apps. These points will be distributed over multiple seasons as NFT positions, ensuring long-term sustainability and preventing sudden supply shifts.

    — How To Earn Points — User Points — App Gems — Loyalty Multiplier — Whitelisted Assets — Airdrop Points Dashboard — Terms and Conditions

    How To Earn Points

    1. User Points — Deploy Assets on Apps

    By deploying as liquidity on participating apps, users will earn points. A list of is available on the points dashboard.

    To earn points for providing liquidity (LPs), both tokens in the pair must be whitelisted. If only one or neither token is whitelisted, no points will be earned. Points are calculated as the average of the two asset multipliers. For example, an S/USDC LP would earn 10x points (average of 12x and 8x).

    2. App Gems — Earn Further Allocation

    The S airdrop includes a developer-focused portion, where apps compete for an airdrop allocation known as . Apps can redeem these Gems for S tokens, which they can then distribute to their users however they want.

    To decide how these S tokens are distributed to their users, each app will run its own independent points program, entirely at its discretion. The app may consider various things, such as the amount of liquidity a user has deployed, the duration of deployment, and the specific pools to which a user has added liquidity.

    As a user, you will be earning points regardless if you've deployed your assets on an app. Your goal is to identify which app has the points program that will offer the highest return for your liquidity. The challenge lies in maximizing your overall rewards by combining the yield earned from providing liquidity with the points earned from the app's points program.

    Loyalty Multiplier

    To encourage consistency and prevent farming or drop-off cycles, a loyalty multiplier is in place.

    Your season 1 performance sets your initial multiplier (from 1.0–2.0x), and your ongoing activity in season 2 can increase or decrease that value, up to a maximum of 3.0x and a minimum of 1.0x.

    The multiplier applies to EOAs only (for now) and updates automatically based on your activity. It will be visible in MySonic once available (not immediately at launch). This loyalty program will carry forward into future seasons.

    Whitelisted Assets

    To qualify for the S airdrop, you must deploy the whitelisted assets listed in the table below as liquidity on participating apps. The multipliers are applied to the points you earn.

    Asset
    Multiplier

    The multipliers for each asset above are decided by which category the fall under in the table below.

    Token Type
    Multiplier

    Sonic reserves the right to determine the appropriate category for any app.

    Whitelisted assets and their multipliers are subject to change. S tokens staked through MySonic are not eligible for points. Users who wish to stake can instead use liquid staking tokens.

    . Sonic Labs makes no guarantee to the safety or peg of third-party assets, such as Rings. Use them at your own risk.

    Airdrop Points Dashboard

    The is a comprehensive platform where users can:

    • Check earned points

    • Check the list of participating apps

    • Get whitelisted assets through a simple interface

    • Generate a referral code and share with friends to earn extra points


    Terms and Conditions

    View the for the Sonic points program.

    Archive Node

    Archive nodes store the entire history of the Sonic chain, including all historical states, transactions, and blocks since the genesis block.

    These nodes handle historical data requests, useful for chain explorers or apps that require historical chain information. However, they do not validate transactions or create new blocks, which is the role of validator nodes.

    To run an archive node on the Sonic mainnet or testnet, follow the steps below.

    1. Build Sonic Client and Tooling

    The minimal configuration for a Sonic archive node is a Linux server with 4 vCPU, 32 GB of RAM, and local SSD storage. We recommend at least 8 vCPU and 64 GB of RAM, but 128GB of RAM is generally preferable for high-demand nodes.

    You will need ≈1TB of free local SSD space to achieve good performance and speed. The configuration details depend on your specific use case.

    The IOPS throughput and random access latency of the state DB persistent storage determine the performance of Sonic. For a smooth installation and fast response time, we recommend a local NVMe or a local SSD drive.

    A remote block device, e.g. AWS Elastic Block Store (EBS), does not provide the required latency and IOPS performance.

    The system firewall must allow TCP and UDP connections from/to port 5050.

    Building the Sonic binary requires the essential software compilation tools and the language version 1.22 or newer to be available. Please refer to your Linux distribution manuals to obtain the development tools installed on your system.

    Build Sonic Client

    Download the Sonic source code from the following GitHub repository.

    Switch to the most recent .

    Build the Sonic binary using the provided configuration.

    Transfer the new binaries to the bin folder for system-wide access (optional).

    2. Prime Sonic State DB

    Download the most recent network archive genesis file for the .

    The genesis file will be used to prime your local state database and will allow you to join the network and synchronize with it. Please check the downloaded genesis file using the provided checksum.

    The expected output is sonic.g: OK.

    Prime Sonic Database

    Use the sonictool app (created during the building process as build/sonictool) to prime a validated archive state database for the Sonic client. Start the genesis expansion.

    The last step of the genesis processing is the state validation. Please double-check that the output log contains the following messages with details about the verified state:

    3. Synchronize Sonic Node With Network

    With the Sonic app created and the database primed in the previous step, you are ready to start the node and synchronize its state with the network.

    • Use the node database path (<datadir>) from the previous step.

    • Use ≈90% of the RAM as the GOMEMLIMIT value.

    • Use ≈12 GiB of the RAM as the --cache value.

    Additional starting flags may need to be added to start Web3 RPC and WebSocket interfaces on the node. Add the following flags to enable the Web3 HTTP interface. Adjust your listening IP address, port, CORS, and list of enabled APIs for your specific needs.

    Add the following flags to enable the WebSockets interface. Adjust your listening IP address, port, origin, and list of enabled APIs for your specific needs.

    Please obtain and explicitly specify the external IP address of your node as a starting flag to help with the inter-node peer-to-peer connectivity.

    Now, start your node with the sonicd application.

    Apply

    All apps on Sonic are eligible to participate in Fee Monetization. To apply, visit the and click Apply for FeeM.

    The application process consists of registering your app to participate in FeeM, followed by registering your app's associated contracts to verify ownership.

    Step 1 — App Registration

    Visit the , connect your admin wallet, and click Apply for FeeM. The registration form will request several details from you.

    Contract Addresses

    Below is a list of all important contract addresses relevant to the Sonic network.

    Tokens:

      • 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38

    npm install --save-dev @nomicfoundation/hardhat-toolbox
    require("@nomicfoundation/hardhat-toolbox");
    
    module.exports = {
      solidity: "0.8.26",
      networks: {
        sonic: {
          url: "https://rpc.soniclabs.com",
          chainId: 146,
          accounts: [SONIC_PRIVATE_KEY]
        },
        sonicTestnet: {
          url: "https://rpc.testnet.soniclabs.com",
          chainId: 57054,
          accounts: [SONIC_PRIVATE_KEY]
        }
      },
      etherscan: {
        apiKey: {
          sonic: "YOUR_SONICSCAN_API_KEY",
          sonicTestnet: "YOUR_SONICSCAN_TESTNET_API_KEY" 
        },
        customChains: [
          {
            network: "sonic",
            chainId: 146,
            urls: {
              apiURL: "https://api.sonicscan.org/api",
              browserURL: "https://sonicscan.org"
            }
          },
          {
            network: "sonicTestnet",
            chainId: 57054,
            urls: {
              apiURL: "https://api-testnet.sonicscan.org/api",
              browserURL: "https://testnet.sonicscan.org"
            }
          }
        ]
      }
    };
    API_KEY=your_sonicscan_api_key
    # For mainnet
    npx hardhat verify --network sonic DEPLOYED_CONTRACT_ADDRESS [CONSTRUCTOR_ARGUMENTS]
    
    # For testnet
    npx hardhat verify --network sonicTestnet DEPLOYED_CONTRACT_ADDRESS [CONSTRUCTOR_ARGUMENTS]
    async function main() {
      // Deploy contract
      const Contract = await ethers.getContractFactory("YourContract");
      const contract = await Contract.deploy(constructorArg1, constructorArg2);
      await contract.waitForDeployment();
      
      console.log("Contract deployed to:", await contract.getAddress());
      
      // Wait for some block confirmations
      await new Promise(resolve => setTimeout(resolve, 30000));
      
      // Verify the contract
      await hre.run("verify:verify", {
        address: await contract.getAddress(),
        constructorArguments: [constructorArg1, constructorArg2]
      });
    }
    npm install --save-dev hardhat-flattener
    npx hardhat flatten contracts/YourContract.sol > flattened.sol

    4551d1fc – Prepare v2.0.5 release (#201)

    e3f7b4c8 – Check archive height before notifications (#149)

  • 48cdac00 – Update to v2.0.5-dev (#171)

  • f9eb911a – Fix intrinsic gas error recognition (#4)

  • 46908a5c – Update module name to 0xsoniclabs/sonic (#1)

  • Minor bug fixes

    79519713 – Fix error propagation (#389)

  • cda79533 – Handle finalized/safe block tags (#388)

  • 0e1599a6 – Skip event payload fetch in streaming (#372)

  • 7265d537 – Use data from proof (#371)

  • HashEx
    in maintenance

    OnFinality

  • QuickNode

  • SubQuery

  • SQD

  • Chainlink (Data Feeds)

  • Pyth Network (Price Feed)

  • RedStone

  • Stork Network

  • Supra

  • Ankr

  • Alchemy

  • Chainstack

  • dRPC

  • OnFinality

  • QuickNode

  • thirdweb

  • Changelly

  • Guardarian

  • Mt Pelerin

  • Onramp Money

  • Onramper

  • Topper

  • TransFi

  • Wirex

  • Pyth Network (Entropy)
    Alchemy
    Sentio
    The Graph
    Sentio Explorer
    Tenderly
    thirdweb
    Arkham
    CoinStats API
    SonicScan
    Chainlink
    LayerZero
    Reactive Network
    API3
    Band Protocol
    Chainlink (Data Streams)
    https://rpc.soniclabs.com
    Alchemy Pay
    Banxa
    ChangeNOW

    View a leaderboard that displays the points and Gems earned by users and apps

    S, wS, stS, beS, anS, wanS, OS, wOS, vS, Origin ARM

    12x

    aSonUSDC, bUSDC.e-20, stkscUSD, wstkscUSD, vgUSDC, aprUSDC, sonicUSD, ghUSDC, SHADOW, x33, METRO, SWPX, BEETS, xSILO, BRUSH, EQUAL, FLY

    10x

    scUSD, USDC, USDT

    8x

    WETH, scETH, stkscETH, wstkscETH, WBTC, scBTC, stkscBTC, wstkscBTC

    4x

    Sonic Tokens

    12x

    Ecosystem Tokens

    10x

    Yield Bearing Stablecoins

    10x

    Pegged Stablecoins

    8x

    ETH/BTC

    4x

    Yield Bearing ETH/BTC

    4x

    whitelisted assets
    participating apps
    Sonic Gems
    Learn more about scUSD/scETH by Rings
    Sonic points dashboard
    terms and conditions
    Circle’s CCTP V2
    $2.5 billion lost
    Credit: Pavel Paramonov
    Credit: Pavel Paramonov
    Validator Allocation

    Sonic automatically allocates 10% of this fee to the network validators.

    3

    FeeM Allocation

    The remaining 90% is sent to the specialized Fee Monetization (FeeM) contract (sometimes referred to as the fee treasury).

    4

    Off-Chain Oracle Tracking

    Multiple off-chain servers (oracles) monitor every transaction on-chain, tracing gas consumption for each registered contract (including sub-calls).

    5

    Rewards Distribution

    When an app claims rewards, the FeeM oracles confirm the gas usage on-chain. Once a quorum of oracles confirms, the FeeM contract releases the app’s accumulated rewards.

  • Project A receives 37% of the reward (0.00629 S).

  • Project B receives 63% of the reward (0.01071 S).

  • The total reward still adds up to 100% of the 0.017 S FeeM reward, ensuring no over-distribution.

  • Fee Monetization dashboard
    Sonic Builders

    33.4%–22.3%

    211–240

    22.3%–11.2%

    241–270

    11.2%–0%

    0–30

    100%–88.9%

    31–60

    88.9%–77.8%

    61–90

    77.8%–66.7%

    91–120

    66.7%–55.6%

    121–150

    55.6%–44.4%

    151–180

    44.4%–33.4%

    points dashboard
    Sonic Points (Season 1)
    Sonic Gems (Season 1)
    Airdrop Order Book
    OpenBlock
    Sentio

    Sonic Points

    User-focused airdrop points, earned by deploying assets as liquidity across apps on Sonic.

    Sonic Gems

    DeFi-focused airdrop points, earned by apps driving user engagement on Sonic.

    Game Gems

    Game-focused airdrop points, earned by games driving player engagement and retention.

    Burn amount of the vested airdrop allocation if claimed early

    180–210

    Go
    Sonic release
    Sonic mainnet or testnet
    git clone https://github.com/0xsoniclabs/Sonic.git
    git fetch --tags && git checkout -b v2.1.2 tags/v2.1.2
    make all
    sudo cp build/sonic* /usr/local/bin/
    wget https://genesis.soniclabs.com/sonic-mainnet/genesis/sonic.g
    wget https://genesis.soniclabs.com/sonic-mainnet/genesis/sonic.g.md5
    md5sum --check sonic.g.md5
    GOMEMLIMIT=50GiB sonictool --datadir <datadir> --cache 12000 genesis <genesis path>
    StateDB imported successfully, stateRoot matches module=gossip-store index=1 root="1ccba39...9ea2be"
    StateDB imported successfully, stateRoot matches module=gossip-store index=1 root="9601e5...c3d639"
    --http --http.addr=0.0.0.0 --http.port=18545
    --http.corsdomain=* --http.vhosts=*
    --http.api=eth,web3,net,ftm,txpool,abft,dag,trace,debug
    --ws --ws.addr=0.0.0.0 --ws.port=18546 --ws.origins=*
    --ws.api=eth,web3,net,ftm,txpool,abft,dag,trace,debug
    GOMEMLIMIT=50GiB sonicd --datadir <datadir> --cache 12000 --nat extip:<public external IP address>

    Owner address Wallet that will manage your FeeM registration.

  • Rewards recipient address Address that will receive FeeM revenue when claimed.

  • Dispute contact Email to be used for communication if you dispute a contract.

  • Metadata Information about your app, such as logo, name, and website.

  • After completing this step, the UI will guide you through registering your app's associated contracts to verify ownership.

    The 25 S registration fee will be refunded once your app has been added to FeeM.

    Step 2 — Contract Registration

    To verify ownership of the contracts you want to include in your FeeM application, you’ll need to add a small code snippet to them.

    1. Choose the Auto-verify option

    2. Copy and paste the code snippet into your contract

    3. Deploy your contract and run the new registerMe function

    Your contracts are now verified and included in FeeM, and you can proceed to the next step.

    If your contract is not upgradable or you're unable to interact with them from an EOA or through other means, please choose the Manual verification option and follow the steps.

    Step 3 — Claim Revenue

    Once your app is approved to FeeM, you will start earning 90% of the network fees it generates.

    To claim, visit the Fee Monetization dashboard, connect with your admin wallet, and claim your rewards. These will be sent to the recipient address you provided during the initial application step.

    For assistance, join Sonic Builders on Telegram.


    Manual Registration

    If you prefer to register your app and its contracts manually instead of using the UI described above, follow the instructions below. However, we recommend using the Fee Monetization dashboard to register.

    1. Create a metadata config file in JSON format with the following parameters:

    1. Host the file in a publicly accessible location. Ensure that anyone can download the JSON file via a browser and that the hosting site supports HTTPS. A 200×200px PNG logo, no larger than 32 KiB, is sufficient.

    2. Go to the FeeM ProjectsRegistrar smart contract and execute the register function providing all the required information. A unique Project ID will be assigned to your registration in response. Use this ID to identify your project in subsequent calls.

    3. Include the code snippet below directly in your contract and run the new function. Replace the <Your FeeM Project ID> placeholder with your actual FeeM Project ID.

    Your app and its contracts are now integrated into FeeM. Proceed to Step 3 above to learn how to claim your rewards.

    If your contract is not upgradable or you're unable to interact with them from an EOA or through other means, please contact Sam Harcourt on Telegram for manual contract verification.


    Contracts to Interact With

    • The FeeM Core: 0x0b5f073135df3f5671710f08b08c0c9258aecc35

    • Projects Registrar: 0x897d37f040Ec8DEFFD0ae1De743e1b1a14cf221f

    • Projects' Contracts Registrar: 0xDC2B0D2Dd2b7759D97D50db4eabDC36973110830

    • Dispute Resolver: 0xF2169D8A17aA40cc31e1b43E4FbB2d19CA099310


    Frequently Asked Questions

    My app uses an upgradeable (proxy) contract. Should I register the implementation too?

    Typically, you only need to register the proxy. Gas consumed by the implementation via delegate-call will be attributed to the proxy address.

    What if my app deploys many user-specific contracts?

    If those user contracts act as proxies calling a small set of implementations, you only need to register the main implementation proxies. You’ll receive rewards for all the gas consumed within them.

    How do I claim my rewards?

    You initiate a claim transaction on the FeeM contract. The oracles confirm your gas usage, and after enough confirmations, your share is transferred to your rewards recipient. You may want to check the Fee Monetization dashboard for a user-friendly claim UX.

    What if I don’t claim my rewards immediately?

    There is no deadline. Unclaimed rewards stay in the FeeM contract until the rightful project claims them.

    Why do my rewards stay the same over a longer time period?

    FeeM processes rewards similarly to the staking rewards via the SFC contract. The accumulated rewards are updated after the active epoch is sealed and confirmed.

    FeeM dashboard
    Fee Monetization dashboard
    Wrapped Ether (WETH)
    • 0x50c42dEAcD8Fc9773493ED674b675bE577f2634b

  • USDC

    • 0x29219dd400f2Bf60E5a23d13Be72B486D4038894

  • EURC (Bridged)

    • 0xe715cba7b5ccb33790cebff1436809d36cb17e57

  • USDT (Bridged)

    • 0x6047828dc181963ba44974801ff68e538da5eaf9

  • Core Contracts:

    • SFC

      • 0xFC00FACE00000000000000000000000000000000

    • Multicall3

      • 0xcA11bde05977b3631167028862bE2a173976CA11

      • 0x3561607590e28e0848ba3B67074C676D6D1C9953

      • 0x3561607590e28e0848ba3B67074C676D6D1C9953

    Gateway Infrastructure (on Sonic):

    • MPTProofVerifier

      • 0xD2f1e904dAf7446686F8057b7dfeb068c75D29A9

    • StateOracle

      • 0x836664B0c0CB29B7877bCcF94159CC996528F2C3

      • 0x12727D4169a42A9b5E3ECB11A6d2c95553d3f447

      • 0xB5B371B75f9850dDD6CCB6C436DB54972a925308

      • 0x134E4c207aD5A13549DE1eBF8D43c1f49b00ba94

      • : 0xE34e6851a4a3763e1d27aa7ac5980d2D33C2d315

      • 0x9Ef7629F9B930168b76283AdD7120777b3c895b3

      • : 0x0B3fe0c10C050270a9bc34271987989B6CF2107C

      • 0x1D3c99DA3CEF5C26f02a86dC7D685efa40176bb7

      • : 0x1071405A4736535C545580064039A235827ee6D4

    Gateway Infrastructure (on Ethereum):

    • MPTProofVerifier

      • 0x921B147a90Ef738BBb7c2c89D88ea9d8Af3e9306

    • StateOracle

      • 0xB7e8CC3F5FeA12443136f0cc13D81F109B2dEd7f

      • 0x72965045A6691E5A74299D1e878f303264D4D910

      • 0xf2b1510c2709072C88C5b14db90Ec3b6297193e4

      • : 0x0c40Ae1c82401EA741953D3f026ADc07BE9e7943

      • 0xa1E2481a9CD0Cb0447EeB1cbc26F1b3fff3bec20

      • : 0x4cbd824685F1E21B119F230B54d65C5a7D2a5330

      • 0x7390251Bf35AA7eA7C196fc4750bd5d6c5918329

      • 0xB0bECf0fBfE431D42bA0FbD8dFBFbB0DCFd62Da4

      • : 0x13bd43A6BE5795D4A4E3Efc4baC21Cd36Ae9e68A

    Tokens:

    • Wrapped S (wS)

      • 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38

    • USDC

      • 0x0BA304580ee7c9a980CF72e55f5Ed2E9fd30Bc51

    Contracts:

      • 0xcA11bde05977b3631167028862bE2a173976CA11

    Tokens:

    • Wrapped S (wS)

      • 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38

    • USDC

      • 0xA4879Fed32Ecbef99399e5cbC247E533421C4eC6

    Contracts:

      • 0xcA11bde05977b3631167028862bE2a173976CA11

    The Sonic Blaze testnet (2.0) will be depreciated soon.

    Wrapped S (wS)

    Sonic Gems

    This page is specific to season 2 of the airdrop.

    The second season of the airdrop and Kaito program are ending on November 1, 2025. Future incentive programs will be announced at a later stage.

    Sonic Gems are developer-focused airdrop points designed to reward apps for driving user engagement and innovation. These Gems can be redeemed for S tokens, which apps can then distribute as rewards to their users.

    This system helps apps grow by driving consistent user activity and maintaining long-term engagement.

    — What are Sonic Gems? ‎‎‎‏— Distribution of Gems — Gems Revocation Policy

    What are Sonic Gems?

    Sonic Gems are airdrop points exclusively designed for apps. Each season, a fixed supply of Gems is allocated to apps based on performance metrics. Apps can track their progress through the .

    To distribute the S tokens earned through Gems to their users, apps must manage the process independently. For example, an app could:

    • Run their own internal points programs

    • Claim Gems and distribute S to users in season 3

    • Join on Telegram for further support

    While there’s no strict requirement for apps to share a specific percentage of their claimed S tokens with their users, the design of Gems incentivizes generosity. Apps that share a larger portion of their claimed S with their communities are rewarded more favorably compared to those that do not.

    Tokenizing Gems is strictly prohibited. Any app that does so will be instantly disqualified from the entire season.

    Distribution of Gems

    Sonic Gems are distributed by considering factors such as category type, Sonic exclusivity, revenue generation, and effective reward distribution, promoting fairness and incentivizing active participation.

    The competitive PvP nature and fixed supply of Gems mean that an app's Gem balance may fluctuate daily, influenced by the performance of other apps on the platform.

    Below are the key criteria that will determine an app's share of Gems in season 1.

    Apps are assessed across several weighted categories, with each app assigned a weight based on its primary category. For season 1, the specific weights are detailed below. If an app falls into multiple categories, the weight of its dominant category will be applied.

    Category
    Weight

    Final Gems Calculation

    Apps will receive a pro-rata share of Sonic Gems based on their final weights, determined by the calculations below.

    Step A — Gem Score

    Step B — Point Score

    Step C — Revenue Score

    Step D — Final Score

    Step E — Share of Gems

    In the calculations above, the Total Gem Score is the sum of the App Gem Scores for all apps, and the same applies to the Total Final Score.

    Gems Revocation Policy

    The following actions by the app can cause their Sonic Gems to be revoked.

    1. Incentivizing Project Tokens or NFTs with Gems Allocating Gems as rewards for activities like holding, staking, or providing liquidity (LPing) for a project’s token or NFT. For apps that have a voting mechanism to direct emissions, Gems can be used as vote incentives for any pool other than those that contain the project's token.

    2. Suspicious Distribution Practices Distributing large quantities of Gems non-transparently, such as allocating them disproportionately to insiders or KOLs without clear disclosure.

    3. Misrepresenting Gem Redistribution Providing false information about the amount of claimed S being distributed to users during any season.

    Users are encouraged to report any suspicious activity or malpractice to Sonic Labs.

    Node Recovery

    Sonic nodes are generally stable and can run for extended periods without operator intervention. However, in rare cases, the software may encounter failures.

    This page outlines the most common causes of such failures, suggests configuration adjustments to prevent them, and provides recovery steps to help you get your node back online as quickly as possible.

    1. Recognizing a Failed Node

    Regardless of the reason, the outcome of a failure is always the same. The node uses a database to track the state of all accounts, smart contracts, transactions, and the consensus data.

    Parts of the database is kept in memory during normal operation. Pre-calculated and updated data is eventually pushed into the persistent storage. If the update cannot finish properly, the persistent copy of the database is in an inconsistent state and can be corrupted.

    {
      "name": "MySuperCoolProject",
      "image_url": "https://mysupercoolproject.com/icons/icon.png",
      "website": "https://mysupercoolproject.com/"
    }
    /// @dev Register my contract on Sonic FeeM
    function registerMe() external {
            (bool _success,) = address(0xDC2B0D2Dd2b7759D97D50db4eabDC36973110830).call(
                abi.encodeWithSignature("selfRegister(uint256)", <Your FeeM Project ID>)
            );
            require(_success, "FeeM registration failed");
    }
    FTM to S Upgrade Portal (Opera)
    FTM to S Upgrade Portal (Sonic)
    ValidatorsRegistry
    MessageBus
    TokenPairs
    Implementation
    Bridge
    Implementation
    UpdateManager
    Implementation
    ValidatorsRegistry
    TokenPairs
    Implementation
    TokenDeposit
    Implementation
    DirectExitAdministrator
    UpdateManager
    Implementation
    Multicall3
    Multicall3

    3

    Options / Derivatives

    2

    Yield Aggregators

    2

    GambleFi

    2

    Bridges

    2

    Apps are assigned different weights depending on their level of exclusivity to Sonic:

    • Weight 2: Exclusively available on Sonic

    • Weight 1: Primarily on Sonic but accessible elsewhere

    • Weight 0.5: Available across multiple chains

    Note: An app's Sonic-native weight cannot be upgraded during a season. However, if an app takes actions that reduce its Sonic nativeness, its weight will be reduced immediately and remain in effect for the following season as well.

    This assesses how effectively an app distributes its claimed S to its users. An app's incentive weight is determined by the percentage of its claimed S that was distributed to its users during the previous season.

    Incentive Weight=S Distributed to UsersS Claimed\text{Incentive Weight} = \frac{\text{S Distributed to Users}}{\text{S Claimed}}Incentive Weight=S ClaimedS Distributed to Users​

    For example, if an app distributed 100% of its claimed S from season 1 to its users, it’ll receive a weight of 1 in season 2, while distributing only 80% would give it a weight of 0.8.

    While there’s no requirement for apps to distribute a specific amount of their claimed S to users, it’s mandatory for all apps to publicly disclose the percentage they intend to share with their communities.

    This transparency allows users to make informed decisions about allocating their capital. Any instances of false communication or misuse of claimed S will result in blacklisting for subsequent seasons.

    Point score is determined by calculating the total amount of Sonic Points that an app has generated for its users. This score is then divided by the total points generated across all eligible apps.

    Point Score=Sonic Points Generated By AppTotal Sonic Points Generated \text{Point Score} = \frac{\text{Sonic Points Generated By App}}{\text{Total Sonic Points Generated}}Point Score=Total Sonic Points GeneratedSonic Points Generated By App​

    Revenue score rewards apps that drive real, sustainable usage.

    Revenue Score=Cumulative Revenue Generated by App\text{Revenue Score} = \text{Cumulative Revenue Generated by App} Revenue Score=Cumulative Revenue Generated by App

    Only fees from whitelisted assets count toward the revenue score. Revenue-generating apps are beneficial to the network as they:

    • Contribute directly to network fees and long-term value for S holders

    • Signal stronger product-market fit and user demand

    • Encourage more efficient use of incentives across the ecosystem

    If your app creates real volume and generates real fees, you’ll earn more Gems.

    Failure to Integrate OpenBlock Failing to integrate with OpenBlock or adhere to its guidelines.
  • Tokenization Tokenizing Gems in any way.

  • Yield Tokenization

    4

    Isolated / Modular Lending

    4

    Spot / CLOB DEX

    3

    Pooled Lending / CDPs

    3

    App Gem Score=Category Weight×Sonic Native Weight×Incentive Weight (N/A in Season 1)Total Gem Score\text{App Gem Score} = \frac{\text{Category Weight} \times \text{Sonic Native Weight} \times \text{Incentive Weight} \, (\text{N/A in Season 1})}{\text{Total Gem Score}} App Gem Score=Total Gem ScoreCategory Weight×Sonic Native Weight×Incentive Weight(N/A in Season 1)​
    App Point Score=Points Generated by App for Users\text{App Point Score} = \text{Points Generated by App for Users}App Point Score=Points Generated by App for Users
    App Revenue Score=Revenue Generated by App\text{App Revenue Score} = \text{Revenue Generated by App}App Revenue Score=Revenue Generated by App
    App Final Score=(A⋅B)α⋅Cβ\text{App Final Score} = (A \cdot B)^{\alpha} \cdot C^{\beta}App Final Score=(A⋅B)α⋅Cβ
    Share of Gems=App Final ScoreTotal Final Score×Total Season 2 Gems\text{Share of Gems} = \frac{\text{App Final Score}}{\text{Total Final Score}} \times \text{Total Season 2 Gems}Share of Gems=Total Final ScoreApp Final Score​×Total Season 2 Gems
    points dashboard
    Sonic Builders

    Perps

    If the node cannot verify the database integrity and consistency, it refuses to start. The sonicd daemon terminates shortly after you attempt to start it, and the output log will contain an error message similar to this:

    You may encounter a similar error message:

    database is empty or the genesis import interrupted

    In this case, check the correct path set for --datadir and the filesystem privileges on the folders and files on the path. The sonicd daemon needs read/write access to the data folder and the files within.

    If the path and access rights are correct, check the genesis import logs. It should confirm a successful import when done. If the process was interrupted for some reason, for example due to insufficient storage size, or an I/O error, you need to fix these issues first and then repeat the import process.

    2. Understanding Why the Node Failed

    In general, there are three major reasons for Sonic node failure:

    • Misconfiguration of the Node Software

      The node resource management configuration is intentionally left for the node operator to decide. This opens options for resource sharing and fine tuning your node to the specific use case you need. If not configured properly, it may also lead to unexpected crashes and failures.

    • Resources Exhaustion

      There are lots of different scenarios of the node utilization. Some of them are very predictable and easily controllable, others may be more random. This mostly applies to the RPC interface and its operation. If your RPC load can vary greatly, especially if it involves high input/output disparity calls like utilizing the debug namespace, your node may run out of RAM memory and be forcefully terminated by the operating system.

    • Soft failures, for example storage space exhaustion, are usually detected by the node software correctly. In this case, the node tries to terminate gracefully. If an unpredictable issue arises, the node may terminate forcefully leading to the startup failure described above. This usually happens due to a storage device failure, different types of I/O errors, forcefully imposed operating system limits (file descriptors, open sockets, etc.), or forced system restart.

    How to Fix Node Misconfiguration

    • Check for the environment variable GOMEMLIMIT to be present and set correctly. If the sonicd node is the only user space software running on the system, it should be set between 85% and 90% of the available RAM. Make sure to properly account for any other software running on your system, including modules executed only occasionally or on a schedule. The value should include units for clarity and readability — better use GOMEMLIMIT=28GiB instead of a value in bytes without the unit.

    • Check the cache size to be explicitly specified and set between 12GiB and 20GiB. Values lower than 12GiB may cause potential issues with processing large blocks. There is no real benefit going over 20GiB of cache. The value itself is specified in MiB. For example, --cache 12000 represents 12 GiB.

    • Check your operating system limits, especially for open file descriptors and/or sockets. Consult your operating system documentation for your case.

    • If you use Systemd or a similar software lifecycle management tool, check the shutdown timeout of the service. The node shutdown procedure, if deployed on a recommended solid state drive (SSD), usually takes less than 15 seconds. If you use a remotely connected persistent storage, especially if an intermediate layer like cloud virtualization, or Kubernetes is involved, the shutdown may take significantly longer. We recommend setting the timeout to at least 1 minute.

    How to Fix Resource Exhaustion

    The most common reason for resource exhaustion leading to a forced node termination and the database corruption is the RPC interface utilization. If the allocated memory crosses a system imposed threshold, the node is terminated unexpectedly and your state DB will be corrupted.

    • Verify what other software components are utilizing the system resources Repeated crashes of your Sonic node may suggest there is another system component utilizing the system resources. An example may be a cloud scheduled system update, log clean-up process, a solid state drive sweep and optimization, or a planed backup task. If not accounted for, these components may trigger RAM exhaustion. In such cases, the biggest consumer would be the Sonic node, and the system may decide to terminate it to free the resources needed to finish the pending work. Update your Sonic node resource limits, especially the GOMEMLIMIT and --cache , to account for these components.

    • Check the usage pattern of your node Some types of RPC API calls have very high ratios between input and output size. An example would be debug and trace namespaces and batch API calls. The whole output has to be kept in memory until the user request is resolved. Configure your system according to the expected usage pattern. We recommend at least 64 GiB of RAM for regular RPC nodes. High demand nodes should run on 128 GiB RAM or more.

    • Do not over-provision cache and/or allocation limits Increasing cache amount above 20GiB has a diminishing return. You should set it between 12 and 20 GiB. The memory allocated for the cache cannot be used to process RPC calls, and to store the responses to be transmitted to end users. Make sure to set the GOMEMLIMIT value so that the system has enough RAM available for the regular operating system tasks. This is usually between 85% and 90% of the available system RAM. A typical server operating system needs only around 1–2GiB to run properly, but the usage can spike up to 4GiB or more. If your node utilizes a software RAID, you should allocate enough RAM for the module to be able to effectively manage the RAID storage read/write operations.

    • Moderate access to public RPC API

      If your node has a public RPC API interface, we strongly recommend to use a middleware layer moderating access to the node RPC port. A great start would be a proxy server, for example , or , configured to limit the number of parallel requests executed on the node interface. The proxy can create a queue for incoming calls before they can be safely pushed to the node for processing. You can also set the proxy to limit number of incoming calls from a single source, or a group of sources, and reject excessive traffic.

    • Load-balance your traffic

      The best approach to handle unpredictable RPC API traffic is to use multiple backend nodes to resolve and balance the traffic based on resource consumption. This usually requires more complex infrastructure setup. The benefit of such approach is that a regular maintenance does not make your interface inaccessible. Using several smaller systems instead of a single overpowered one may allow you to better control your resources cost, and will make your system way more issue resistant as a whole. The downside is much more complex configuration and maintenance which usually requires knowledge of high availability system setup and scalable architecture deployment.

    How to Fix Hardware Failures

    A hardware failure usually cannot be predicted, but there are some steps you can take to lower the impact of some types of failures.

    • Configure graceful shutdown, especially on cloud deployments Cloud-based systems offer obvious benefits compared to bare metal solutions. They can be deployed easily, scaled dynamically, and migrated very quickly between different regions and/or system groups. If you opt for this type of configuration, make sure the shutdown process of the node uses a graceful ACPI shutdown, or its equivalent, and is set to wait for the procedure to finish. If not possible, configure the shutdown timer so that your Sonic node has enough time to sync its cache with the persistent storage. Please refer to the node deployment guidelines for the usual termination times. A non-cloud environment usually does not suffer from migrations, or unexpected resets, however they still may need to be shutdown for a hardware maintenance. Make sure to configure your system timeouts and the shutdown procedure to always allow your Sonic node to close properly.

    • Use redundant storage (RAID) to prevent single drive failure caused crash Persistent storage failure is the most common type of hardware issue you may encounter. The node state data can be easily obtained from the Sonic network. There is no exclusive content on your drive beyond the <datadir>/keystore folder. Surely, your account keys and the validator consensus keys are already backed up securely. However, if your storage drive holding the state DB fails, the system will inevitably crash. To prevent the immediate impact of such failure, you should utilize RAID storage with the redundancy level configured to match your resiliency expectations.

    • Use high availability deployment setup for up-time sensitive RPC systems As discussed above, if your RPC node is part of a critical infrastructure, you should always opt for some level of node redundancy. It would not only allow you to recover after an unexpected system failure, but will also help you perform regular maintenance without experiencing the whole system downtime. A great starting point may be a proxy based load balancer, for example .

    A validator node must always use a single instance deployment. If you attempt to run multiple validator nodes with the same signing key, your validator will be penalized for double-signing, removed from the network, and your stake will be slashed.

    • Monitor your system health and resources

      This may be obvious, but your system will age, and it will fail eventually. Modern systems usually do have sensors which can warn you about possible failures and shortages in advance. Refer to your system documentation for the details about available monitoring solutions, and system level alerts, allowing you to take appropriate steps to resolve an imminent crash before it happens.

    3. Recovering From the Node Failure

    If your node runs in the validator mode, it does not have enough data to recover from the failure on its own. After you resolve the reason of the node crash, you need to download the latest state snapshot and rebuild the corrupted database from it. Please refer to the validator node deployment guide for the instructions how to obtain and unpack the latest snapshot. You should consider upgrading your node to the latest available version of the node software before you proceed.

    If your node runs in the RPC mode and it did run at least 15 minutes after the initialization from the snapshot before it crashed, you may be able to recover the live state from the archive database. In this case, follow these steps:

    1. Identify and fix the reason for the crash.

    2. Make sure you have the latest available Sonic node version. If your local version is outdated, build the latest Sonic node software. Use the version command to check your node version:

    3. Try to recover the state from your archive database.

      The heal will attempt to recover the state. If the healing succeeds, you can start your node normally and the node will finish syncing from the network. Any failure means your archive state is not consistent and cannot be used to recover from the failure.

    4. If your heal process failed, you need to remove <datadir>/carmen and <datadir>/chaindata folders, download the latest archive or pruned database snapshot, and rebuild your state from them. Refer to the for the details of the process.

    Programmatic Gateway

    This page explains how to use the Sonic Gateway in your application or script to transfer ERC-20 assets from Ethereum to Sonic and back.

    Sonic Bridge: Programmatic Usage Guide

    Contract Addresses

    Validator Node

    Validator nodes are critical to the Sonic chain, responsible for validating transactions and creating new blocks in accordance with the . These nodes ensure the integrity and security of the network by verifying data, participating in block creation, and maintaining the chain’s state.

    Unlike , validator nodes focus on real-time operations rather than storing extensive historical data or responding to general API requests.

    To run a validator node on the Sonic mainnet or testnet, follow the steps below.

    Steps to Run a Validator

    Native USDC

    Quick-Start Guide

    Overview

    USDC by Circle enables the seamless transfer of digital dollars on Sonic using a smart contract. This guide walks you through building a simple React app that lets users connect their wallet and send USDC on the .

    $ sonicd version
    Sonic
    Version: 2.0.5
    Git Commit: ea9e363178ea9fb28a723beb803fb5dcf223cbbc
    ...
    GOMEMLIMIT=28GiB sonictool --datadir <path> --cache 12000 heal
    failed to initialize the node: failed to make consensus engine: 
    failed to open existing databases: dirty state: gossip-21614: DE
    Hardware Failure
    HAproxy
    Nginx
    HAproxy
    archive node database priming guide
    The address of USDC on the testnet is 0x0BA304580ee7c9a980CF72e55f5Ed2E9fd30Bc51.

    1. Prerequisites

    Development Environment

    • Node.js 16 + (includes npm)

    • MetaMask browser extension

    Funding Your Wallet

    • Native gas token (S on the Sonic testnet) for transaction fees

    • USDC test tokens — use the CCTP V2 Sample App to bridge USDC from another testnet


    2. Project Setup

    Step 1: Create a new project

    Step 2: Install dependencies

    Step 3: Verify package.json

    Step 4: Add the scripts section (if needed)

    Step 5: Run the dev server


    3. Configure Blockchain Clients

    Create src/clients.ts:


    4. Define USDC Contract Details

    Create src/constants.ts:


    5. Implement Wallet Connection & USDC Transfer

    Create src/App.tsx:


    6. Configure the Entry Point

    Create src/main.tsx:


    7. Create index.html


    8. Start the Application

    Open http://localhost:5173 in your browser and start transferring USDC on the Sonic Blaze testnet!

    Sonic testnet
    tee -a /etc/security/limits.conf > /dev/null <<EOT
    @sonic           soft    nofile          950000
    @sonic           hard    nofile          950000
    EOT
    [Service]
    Type=simple
    User=sonic
    Group=sonic
    Environment="GOMEMLIMIT=28GiB"
    ExecStart=/usr/bin/sonicd --datadir=/var/lib/sonic --cache=16000
    LimitNOFILE=934073
    TimeoutSec=300
    mkdir usdc-transfer-app
    cd usdc-transfer-app
    npm init -y
    npm install react@latest react-dom@latest \
      @types/react@latest @types/react-dom@latest \
      @vitejs/plugin-react@latest typescript@latest \
      vite@latest viem@latest
    {
      "name": "usdc-transfer-app",
      "version": "1.0.0",
      "main": "index.js",
      "scripts": {
        "dev": "vite",
        "build": "vite build",
        "preview": "vite preview"
      },
      "dependencies": {
        "@types/react": "^19.1.2",
        "@types/react-dom": "^19.1.2",
        "@vitejs/plugin-react": "^4.4.1",
        "react": "^19.1.0",
        "react-dom": "^19.1.0",
        "typescript": "^5.8.3",
        "viem": "^2.28.0",
        "vite": "^6.3.2"
      }
    }
    "scripts": {
      "dev": "vite",
      "build": "vite build",
      "preview": "vite preview"
    }
    npm run dev
    import { http, createPublicClient, createWalletClient, custom } from 'viem';
    import { sonicBlazeTestnet } from 'viem/chains';
    
    declare global {
      interface Window {
        ethereum: any;
      }
    }
    
    export const publicClient = createPublicClient({
      chain: sonicBlazeTestnet,
      transport: http(),
    });
    
    export const walletClient = createWalletClient({
      chain: sonicBlazeTestnet,
      transport: custom(window.ethereum),
    });
    export const USDC_CONTRACT_ADDRESS =
      '0x391071Fe567d609E4af9d32de726d4C33679C7e2';
    
    export const USDC_ABI = [
      {
        constant: false,
        inputs: [
          { name: '_to',    type: 'address' },
          { name: '_value', type: 'uint256' },
        ],
        name: 'transfer',
        outputs: [{ name: '', type: 'bool' }],
        type: 'function',
      },
      {
        constant: true,
        inputs: [{ name: '_owner', type: 'address' }],
        name: 'balanceOf',
        outputs: [{ name: 'balance', type: 'uint256' }],
        type: 'function',
      },
    ];
    import React, { useEffect, useState } from 'react';
    import { publicClient, walletClient } from './clients';
    import { USDC_CONTRACT_ADDRESS, USDC_ABI } from './constants';
    import {
      type Address,
      type Hash,
      type TransactionReceipt,
    } from 'viem';
    
    function USDCApp() {
      const [account, setAccount] = useState<Address>();
      const [balance, setBalance] = useState<string>();
      const [hash, setHash] = useState<Hash>();
      const [receipt, setReceipt] = useState<TransactionReceipt>();
      const [recipient, setRecipient] = useState('');
      const [amount, setAmount] = useState('');
      const [isTransferring, setIsTransferring] = useState(false);
    
      // Fetch USDC balance
      const fetchBalance = async (address: Address) => {
        const raw = await publicClient.readContract({
          address: USDC_CONTRACT_ADDRESS,
          abi: USDC_ABI,
          functionName: 'balanceOf',
          args: [address],
        }) as bigint;
        setBalance((Number(raw) / 1e6).toFixed(2));
      };
    
      // Connect wallet
      const connect = async () => {
        const [addr] = await walletClient.requestAddresses();
        setAccount(addr);
        fetchBalance(addr);
      };
    
      // Transfer USDC
      const transferUSDC = async (e: React.FormEvent) => {
        e.preventDefault();
        if (!account || !recipient || !amount) return;
        try {
          setIsTransferring(true);
    
          const value = BigInt(Math.floor(Number(amount) * 1e6));
          const { request } = await publicClient.simulateContract({
            account,
            address: USDC_CONTRACT_ADDRESS,
            abi: USDC_ABI,
            functionName: 'transfer',
            args: [recipient as Address, value],
          });
    
          const txHash = await walletClient.writeContract(request);
          setHash(txHash);
    
          const rcpt = await publicClient.waitForTransactionReceipt({ hash: txHash });
          setReceipt(rcpt);
    
          await fetchBalance(account);  // refresh balance
          setRecipient('');
          setAmount('');
        } catch (err) {
          console.error('Transfer failed:', err);
        } finally {
          setIsTransferring(false);
        }
      };
    
      return (
        <div>
          <h1>USDC Transfer Sample App</h1>
    
          {account ? (
            <>
              <p><strong>Connected wallet:</strong> {account}</p>
              <p><strong>USDC balance:</strong> {balance ?? 'Fetching…'} USDC</p>
    
              <form onSubmit={transferUSDC} style={{ marginTop: 20 }}>
                <div style={{ marginBottom: 10 }}>
                  <label>
                    Recipient&nbsp;address&nbsp;
                    <input
                      type="text"
                      value={recipient}
                      onChange={e => setRecipient(e.target.value)}
                      placeholder="0x..."
                      style={{ marginLeft: 10, width: 300 }}
                    />
                  </label>
                </div>
    
                <div style={{ marginBottom: 10 }}>
                  <label>
                    Amount&nbsp;(USDC)&nbsp;
                    <input
                      type="number"
                      value={amount}
                      onChange={e => setAmount(e.target.value)}
                      placeholder="0.00"
                      step="0.01"
                      min="0"
                      style={{ marginLeft: 10 }}
                    />
                  </label>
                </div>
    
                <button type="submit" disabled={isTransferring}>
                  {isTransferring ? 'Transferring…' : 'Transfer USDC'}
                </button>
              </form>
    
              {hash && (
                <p style={{ marginTop: 20 }}>
                  <strong>Transaction hash:</strong> {hash}
                </p>
              )}
    
              {receipt && (
                <p style={{ marginTop: 10 }}>
                  <strong>Transaction status:</strong>{' '}
                  {receipt.status === 'success' ? 'Success' : 'Failed'}
                </p>
              )}
            </>
          ) : (
            <button onClick={connect}>Connect Wallet</button>
          )}
        </div>
      );
    }
    
    export default USDCApp;
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import USDCApp from './App';
    
    ReactDOM.createRoot(document.getElementById('root')!).render(
      <React.StrictMode>
        <USDCApp />
      </React.StrictMode>,
    );
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>USDC Transfer Sample App</title>
      </head>
      <body>
        <div id="root"></div>
        <script type="module" src="/src/main.tsx"></script>
      </body>
    </html>
    npm run dev
    Setup

    Bridge Operations

    1. Ethereum to Sonic Transfer

    2. Claim Tokens on Sonic

    3. Sonic to Ethereum Transfer

    4. Claim Tokens on Ethereum

    Complete Example

    Required ABIs

    Important Notes

    1. State Updates

      • Ethereum → Sonic: Monitor StateOracle.lastBlockNum until it's >= deposit block

      • Sonic → Ethereum: Monitor StateOracle.lastBlockNum until it's >= withdrawal block

    2. Proofs

      • Required for all claim operations

      • Generated using eth_getProof RPC call with correct storage slots

      • Must be RLP encoded in format: RLP.encode([RLP.encode(accountProof), RLP.encode(storageProof)])

      • Storage slots are calculated using:

        • Deposits: keccak256(abi.encode(depositId, uint8(7)))

        • Withdrawals: keccak256(abi.encode(withdrawalId, uint8(1)))

    3. Gas Fees

      • Keep enough ETH/S for gas on both networks

      • Claim operations typically cost more gas due to proof verification

    4. Security

      • Never share private keys

      • Always verify contract addresses

      • Test with small amounts first

    5. Monitoring

      • Monitor transaction status on both networks

      • Keep transaction hashes for reference

      • Verify successful claims before proceeding

    Launch a Server Instance

  • Install Required Development Tools

  • Build the Sonic Node Software

  • Prime the Sonic Database

  • Synchronize With the Network

  • Create a Validator Wallet

  • Create a Validator Signing Key

  • Register Your Validator

  • Run Your Validator Node

  • Validator Name and Logo

  • Next Steps

    • Minimum self-stake amount: 500,000 S

    • Maximum validator size: 15x self-stake

    • Rewards: ~6% APR initially, plus 15% of delegators' rewards and network fees

    The minimum self-stake on Sonic is set at 500,000 S to ensure security during the network's early months, with plans to gradually reduce it.

    • Mainnet RPC:

    • Testnet RPC:

    • WebSocket Endpoint: wss://rpc.soniclabs.com

    • Mainnet Explorer:

    1. Launch a Server Instance

    You can run your validator node on dedicated hardware (bare metal) or use a cloud provider. We recommend choosing one of the established providers, such as Google GCP or Amazon AWS.

    Node Hardware Specifications

    • At least 4 vCPUs and 32 GB of RAM

    • At least 1 Gbps redundant backbone connectivity for stable and uninterrupted network traffic

    • At least 1 TB of local SSD/NVMe storage. Remote block devices (e.g., AWS EBS) typically do not provide the required latency and random access performance. Google GCP N2D instances with local SSD or AWS i3en.xlarge with instance storage are good options.

    • Ubuntu LTS Server (64-bit) or a similar Linux distribution is recommended.

    Required Storage Capacity

    • 1 TB of local SSD/NVMe is sufficient for a validator database.

    Network Settings

    A Sonic node requires both TCP and UDP network traffic allowed on port 5050 by default. You can use --port <port> to customize this if needed.

    2. Install Required Development Tools

    You need the essential build tools and the latest Go compiler, version 1.24 or newer, to build the Sonic client and its bundled tools. Example (Ubuntu/Debian):

    Install Go language compiler (Ubuntu/Debian):

    3. Build the Sonic Node Software

    Check the latest Sonic release and adjust commands if necessary:

    You can confirm the Sonic release by running:

    Optionally, copy the binaries to a system-wide location:

    4. Prime the Sonic Database

    To participate in the Sonic network, you need a valid state database. The fastest way is to use a genesis file from the official repository. Download the appropriate genesis file. For the mainnet, for example:

    Use sonictool to prime the state database. Adjust GOMEMLIMIT and --cache according to your available RAM size. For the most common cases, use 12GiB as --cache and ~90% of RAM as GOMEMLIMIT.

    After processing, you should see a confirmation of a successfully imported state.

    5. Synchronize With the Network

    Now that your database is primed, start the node to synchronize it with the network. Ensure your firewall is configured correctly.

    The Sonic node will connect to the network and advance its state by processing new blocks. Once fully synchronized, the "age" of new blocks should be only a few seconds.

    6. Create a Validator Wallet

    Your Sonic node is now synchronizing. Next, create a wallet to identify and control your validator account. This wallet must hold the minimum amount you are going to use as the self-stake (500,000 S).

    We recommend creating the wallet securely (e.g. a hardware wallet). If you choose to create it locally using sonictool:

    Important: Keep your wallet and keys secure. Never share them.

    7. Create a Validator Signing Key

    A Sonic validator node signs consensus messages. Your node needs a validator signing key to participate. Create it on the server:

    Follow the prompts and set a secure password. Note the public key (starts with 0xc00). This key will be used during registration.

    Important: Back up your signing key. Although it cannot move funds, misuse could lead to penalties.

    8. Register Your Validator

    The network must recognize your validator key. Register by invoking the SFC (Staking and Consensus) contract:

    • SFC Contract Address: 0xFC00FACE00000000000000000000000000000000

    Call createValidator with your validator public key and at least the minimum required stake (500,000 S). Sign this transaction with your validator wallet. After confirmation, query your validator ID using the getValidatorID function. The easiest way would be to open the Sonic explorer and navigate to the SFC address.

    The contract is validated and you can interact with it using SonicScan and a connected Web3 wallet. The control validator account can be imported into your Web3 wallet either using the generated JSON key store or as your hardware wallet. With the account open, you can sign the createValidator transaction call specifying the amount of stake and the public key obtained in the previous step.

    9. Run Your Validator Node

    Stop the currently running node:

    Wait for it to gracefully shut down. Never force-terminate it, as it could corrupt the database. Restart your node in validator mode, providing the validator ID, public key, and password file:

    Your validator node will now participate in consensus and produce blocks.

    10. Validator Name and Logo

    Create a config file in JSON format that contains the following parameters (you can also leave parameters empty):

    Host it somewhere so it is publicly accessible, such as in this example. Make sure anybody can download the JSON file using a browser and that the hosting site supports HTTPS. A 100x100 logo size is sufficient.

    Now you need to insert the JSON URL into the STI contract.

    1. Go to SonicScan and open the STI contract.

    2. Hit Contract -> Write Contract.

    3. Find the function updateInfo and paste the JSON URL.

    4. Connect using your validator account Web3 wallet (the one you used to register).

    5. Sign and execute the update.

    11. Next Steps

    Congratulations! You are now running a Sonic validator node.

    consensus protocol
    archive nodes
    // Ethereum (L1)
    const ETH_CONTRACTS = {
        TOKEN_DEPOSIT: "0xa1E2481a9CD0Cb0447EeB1cbc26F1b3fff3bec20",
        TOKEN_PAIRS: "0xf2b1510c2709072C88C5b14db90Ec3b6297193e4",
        STATE_ORACLE: "0xB7e8CC3F5FeA12443136f0cc13D81F109B2dEd7f"
    };
    
    // Sonic (L2)
    const SONIC_CONTRACTS = {
        BRIDGE: "0x9Ef7629F9B930168b76283AdD7120777b3c895b3",
        TOKEN_PAIRS: "0x134E4c207aD5A13549DE1eBF8D43c1f49b00ba94",
        STATE_ORACLE: "0x836664B0c0CB29B7877bCcF94159CC996528F2C3"
    };
    // Network RPC endpoints
    const ETHEREUM_RPC = "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY";
    const SONIC_RPC = "https://rpc.soniclabs.com";
    
    // Initialize providers
    const ethProvider = new ethers.providers.JsonRpcProvider(ETHEREUM_RPC);
    const sonicProvider = new ethers.providers.JsonRpcProvider(SONIC_RPC);
    
    // Initialize signer with your private key
    const PRIVATE_KEY = "your-private-key";
    const ethSigner = new ethers.Wallet(PRIVATE_KEY, ethProvider);
    const sonicSigner = new ethers.Wallet(PRIVATE_KEY, sonicProvider);
    async function bridgeToSonic(tokenAddress, amount) {
        // 1. Check if token is supported
        const tokenPairs = new ethers.Contract(ETH_CONTRACTS.TOKEN_PAIRS, TOKEN_PAIRS_ABI, ethProvider);
        const mintedToken = await tokenPairs.originalToMinted(tokenAddress);
        if (mintedToken === ethers.constants.AddressZero) {
            throw new Error("Token not supported");
        }
    
        // 2. Approve token spending
        const token = new ethers.Contract(tokenAddress, ERC20_ABI, ethSigner);
        const approveTx = await token.approve(ETH_CONTRACTS.TOKEN_DEPOSIT, amount);
        await approveTx.wait();
    
        // 3. Deposit tokens
        const deposit = new ethers.Contract(ETH_CONTRACTS.TOKEN_DEPOSIT, TOKEN_DEPOSIT_ABI, ethSigner);
        const tx = await deposit.deposit(Date.now(), tokenAddress, amount);
        const receipt = await tx.wait();
    
        return {
            transactionHash: receipt.transactionHash,
            mintedToken,
            blockNumber: receipt.blockNumber,
            depositId: receipt.events.find(e => e.event === 'Deposit').args.id
        };
    }
    async function waitForStateUpdate(depositBlockNumber) {
        const stateOracle = new ethers.Contract(SONIC_CONTRACTS.STATE_ORACLE, STATE_ORACLE_ABI, sonicProvider);
        
        while (true) {
            const currentBlockNum = await stateOracle.lastBlockNum();
            if (currentBlockNum >= depositBlockNumber) {
                return currentBlockNum;
            }
            await new Promise(resolve => setTimeout(resolve, 30000)); // Check every 30 seconds
        }
    }
    
    async function generateProof(depositId, blockNum) {
        // Generate storage slot for deposit
        const storageSlot = ethers.utils.keccak256(
            ethers.utils.defaultAbiCoder.encode(['uint256', 'uint8'], [depositId, 7])
        );
        
        // Get proof from Ethereum node
        const proof = await ethProvider.send("eth_getProof", [
            ETH_CONTRACTS.TOKEN_DEPOSIT,
            [storageSlot],
            ethers.utils.hexValue(blockNum) // important to use current stateOracle.lastBlockNum
        ]);
        
        // Encode proof in required format
        return ethers.utils.RLP.encode([
            ethers.utils.RLP.encode(proof.accountProof),
            ethers.utils.RLP.encode(proof.storageProof[0].proof)
        ]);
    }
    
    async function claimOnSonic(depositBlockNumber, depositId, tokenAddress, amount) {
        // 1. Wait for state oracle update
        console.log("Waiting for state oracle update to block ", depositBlockNumber);
        const blockNum = await waitForStateUpdate(depositBlockNumber);
        
        // 2. Generate proof
        console.log("Generating proof...");
        const proof = await generateProof(depositId, blockNum);
        
        // 3. Claim tokens with proof
        console.log("Claiming tokens...");
        const bridge = new ethers.Contract(SONIC_CONTRACTS.BRIDGE, BRIDGE_ABI, sonicSigner);
        const tx = await bridge.claim(depositId, tokenAddress, amount, proof);
        const receipt = await tx.wait();
    
        return receipt.transactionHash;
    }
    async function bridgeToEthereum(tokenAddress, amount) {
        // 1. Check if token is supported
        const tokenPairs = new ethers.Contract(SONIC_CONTRACTS.TOKEN_PAIRS, TOKEN_PAIRS_ABI, sonicProvider);
        const originalToken = await tokenPairs.mintedToOriginal(tokenAddress);
        if (originalToken === ethers.constants.AddressZero) {
            throw new Error("Token not supported");
        }
        
        // 2. Approve token spending
        const token = new ethers.Contract(tokenAddress, ERC20_ABI, sonicSigner);
        const approveTx = await token.approve(SONIC_CONTRACTS.BRIDGE, amount);
        console.log("waiting... ", approveTx.hash);
        await approveTx.wait();
    
        // 3. Initiate withdrawal
        const bridge = new ethers.Contract(SONIC_CONTRACTS.BRIDGE, BRIDGE_ABI, sonicSigner);
        const tx = await bridge.withdraw(Date.now(), originalToken, amount);
        const receipt = await tx.wait();
    
        return {
            transactionHash: receipt.transactionHash,
            originalToken,
            blockNumber: receipt.blockNumber,
            withdrawalId: receipt.events.find(e => e.event === 'Withdrawal').args.id
        };
    }
    async function waitForEthStateUpdate(withdrawalBlockNumber) {
        const stateOracle = new ethers.Contract(ETH_CONTRACTS.STATE_ORACLE, STATE_ORACLE_ABI, ethProvider);
        
        while (true) {
            const currentBlockNum = await stateOracle.lastBlockNum();
            if (currentBlockNum >= withdrawalBlockNumber) {
                return currentBlockNum;
            }
            await new Promise(resolve => setTimeout(resolve, 30000)); // Check every 30 seconds
        }
    }
    
    async function generateWithdrawalProof(withdrawalId, blockNum) {
        // Generate storage slot for withdrawal
        const storageSlot = ethers.utils.keccak256(
            ethers.utils.defaultAbiCoder.encode(['uint256', 'uint8'], [withdrawalId, 1])
        );
        
        // Get proof from Sonic node
        const proof = await sonicProvider.send("eth_getProof", [
            SONIC_CONTRACTS.BRIDGE,
            [storageSlot],
            ethers.utils.hexValue(blockNum) // important to use current stateOracle.lastBlockNum
        ]);
        
        // Encode proof in required format
        return ethers.utils.RLP.encode([
            ethers.utils.RLP.encode(proof.accountProof),
            ethers.utils.RLP.encode(proof.storageProof[0].proof)
        ]);
    }
    
    async function claimOnEthereum(withdrawalBlockNumber, withdrawalId, tokenAddress, amount) {
        // 1. Wait for state oracle update
        console.log("Waiting for state oracle update to block ", withdrawalBlockNumber);
        const blockNum = await waitForEthStateUpdate(withdrawalBlockNumber);
        
        // 2. Generate proof
        console.log("Generating proof...");
        const proof = await generateWithdrawalProof(withdrawalId, blockNum);
        
        // 3. Claim tokens with proof
        console.log("Claim tokens with proof...");
        const deposit = new ethers.Contract(ETH_CONTRACTS.TOKEN_DEPOSIT, TOKEN_DEPOSIT_ABI, ethSigner);
        const tx = await deposit.claim(withdrawalId, tokenAddress, amount, proof);
        const receipt = await tx.wait();
    
        return receipt.transactionHash;
    }
    async function bridgeUSDC() {
        try {
            // USDC details
            const USDC_ADDRESS = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
            const amount = ethers.utils.parseUnits("100", 6); // USDC has 6 decimals
    
            // 1. Bridge USDC to Sonic
            console.log("Initiating bridge to Sonic...");
            const deposit = await bridgeToSonic(USDC_ADDRESS, amount);
            console.log(`Deposit successful: ${deposit.transactionHash}`);
    
            // 2. Claim USDC on Sonic
            console.log("Waiting for state update and claiming on Sonic...");
            const claimTx = await claimOnSonic(deposit.blockNumber, deposit.depositId, USDC_ADDRESS, amount);
            console.log(`Claim successful: ${claimTx}`);
    
            // Later: Bridge back to Ethereum
            console.log("Initiating bridge back to Ethereum...");
            const withdrawal = await bridgeToEthereum(deposit.mintedToken, amount);
            console.log(`Withdrawal initiated: ${withdrawal.transactionHash}`);
    
            // Claim on Ethereum
            console.log("Waiting for state update and claiming on Ethereum...");
            const finalClaim = await claimOnEthereum(
                withdrawal.blockNumber,
                withdrawal.withdrawalId,
                withdrawal.originalToken,
                amount
            );
            console.log(`Final claim successful: ${finalClaim}`);
        } catch (error) {
            console.error("Bridge operation failed:", error.message);
            throw error;
        }
    }
    const STATE_ORACLE_ABI = [
        "function lastBlockNum() external view returns (uint256)",
        "function lastState() external view returns (bytes32)"
    ];
    
    const ERC20_ABI = [
        "function approve(address spender, uint256 amount) external returns (bool)",
        "function allowance(address owner, address spender) external view returns (uint256)"
    ];
    
    const TOKEN_PAIRS_ABI = [
        "function originalToMinted(address) external view returns (address)",
        "function mintedToOriginal(address) external view returns (address)"
    ];
    
    const TOKEN_DEPOSIT_ABI = [
        "function deposit(uint96 uid, address token, uint256 amount) external",
        "function claim(uint256 id, address token, uint256 amount, bytes calldata proof) external",
        "event Deposit(uint256 indexed id, address indexed owner, address token, uint256 amount)"
    ];
    
    const BRIDGE_ABI = [
        "function withdraw(uint96 uid, address token, uint256 amount) external",
        "function claim(uint256 id, address token, uint256 amount, bytes calldata proof) external",
        "event Withdrawal(uint256 indexed id, address indexed owner, address token, uint256 amount)"
    ];
    sudo apt-get update
    sudo apt-get install -y build-essential git
    sudo rm -rf /usr/local/go
    wget https://go.dev/dl/go1.25.2.linux-amd64.tar.gz
    sudo tar -xzf go1.25.2.linux-amd64.tar.gz -C /usr/local/
    rm -f go1.25.2.linux-amd64.tar.gz
    
    sudo tee /etc/profile.d/golang.sh > /dev/null <<EOT
    export GOROOT=/usr/local/go
    export GOPATH=\$HOME/go
    export PATH=\$PATH:\$GOROOT/bin:\$GOPATH/bin
    EOT
    
    source /etc/profile.d/golang.sh
    git clone https://github.com/0xsoniclabs/Sonic.git
    cd Sonic
    git fetch --tags && git checkout -b v2.1.2 tags/v2.1.2
    make all
    build/sonicd version
    sudo mv build/sonic* /usr/local/bin/
    wget https://genesis.soniclabs.com/sonic-mainnet/genesis/sonic.g
    GOMEMLIMIT=54GiB sonictool --datadir ~/.sonic \
        --cache 12000 genesis \
        --mode validator sonic.g
    GOMEMLIMIT=54GiB sonicd --datadir ~/.sonic --cache 12000 --mode validator
    sonictool --datadir ~/.sonic account new
    sonictool --datadir ~/.sonic validator new
    pkill sonicd
    GOMEMLIMIT=50GiB sonicd \
        --datadir ~/.sonic \
        --cache 12000 \
        --mode validator \
        --validator.id <your_validator_ID> \
        --validator.pubkey <your_public_key> \
        --validator.password <path_to_password_file>
    {
      "name": "VALIDATOR_NAME", /* Name of the validator */
      "logoUrl": "LOGO_URL", /* Validator logo (PNG|JPEG|SVG 100x100) starting https:// */
      "website": "WEBSITE_URL", /* Website icon on the right */
      "contact": "CONTACT_URL" /* Contact icon on the right */
    }
    
    /* It could look something like this 👇 */
    
    {
      "name": "SonicLabs",
      "logoUrl": "https://repository.sonic.soniclabs.com/validator/sonic.svg",
      "website": "https://www.soniclabs.com",
      "contact": "https://www.soniclabs.com/contact"
    }
    Use the same private key for both networks

    Monitor StateOracle updates for claim timing

    Testnet Explorer: https://testnet.sonicscan.org

  • SFC Contract Address: 0xFC00FACE00000000000000000000000000000000

  • STI Contract (Validators' Information): 0xFf4cD89f549432c312c497628748d4d76AC180f6

  • Genesis Files: https://genesis.soniclabs.com

  • Validator/Name Logo

    You can set a validator name and logo on the explorer. Check official repositories for instructions.

    The STI contract on Sonic: 0xFf4cD89f549432c312c497628748d4d76AC180f6

    Community and Help

    Join Sonic community channels, follow updates, and use your stake to participate in network governance. If you have issues, the community can provide guidance.

    Monitoring and Health

    If your node goes offline, you stop earning rewards. Extended downtime (e.g. more than 5 days) may result in suspension, requiring you to withdraw and start over. Regular monitoring, maintenance, and backups are essential.

    https://rpc.soniclabs.com
    https://rpc.testnet.soniclabs.com
    https://sonicscan.org

    Tic-Tac-Toe Demo

    This repository demonstrates account abstraction on Sonic using both EIP-7702 and ERC-4337 standards through a fully functional on-chain tic-tac-toe game.

    It showcases how Sonic is upgrading its infrastructure to support Ethereum's account abstraction features, enabling gasless transactions, smart account capabilities, and enhanced user experiences.

    Quick Start

    1. Sonic Testnet Deploy your own contracts using Hardhat Ignition (chain ID 14601)

    2. Frontend Demo Requires a running for UserOperation submission

    3. Bot Demo Interacts directly with deployed contracts

    Table of Contents

    Key Features

    🎮 On-Chain Tic-Tac-Toe Game

    • Fully decentralized 5x5 tic-tac-toe game with 4-in-a-row win condition

    • Prize token rewards (10 tokens for winners, one token for draws)

    • Time-limited moves (24-hour timeout protection)

    • Upgradeable smart contract using UUPS proxy pattern

    🔐 EIP-7702 Account Abstraction

    • Transform regular EOAs into smart accounts without changing addresses

    • Enable transaction batching and gas sponsorship for existing wallets

    • Demonstrate SET_CODE_TX_TYPE transaction format

    📦 ERC-4337 UserOperations

    • Complete implementation of UserOperation flow

    • EntryPoint interaction for validation and execution

    • Support for both MetaMask integration and programmatic signing

    • Gas estimation and fee management

    💰 Paymaster Infrastructure

    • TargetCheckingPaymaster: Sponsors gas for whitelisted contract interactions

    • SignatureCheckingPaymaster: Validates authorized transactions with signature verification

    • Gas-free gameplay for users

    🤖 AI Game Bot

    • Automated tic-tac-toe player using min-max algorithm

    • Monitors blockchain events and responds to game moves

    • Configurable joining delay and strategy selection

    • Complete event subscription and game state management

    🌐 Frontend Demo

    • Vue.js web interface for game interaction

    • Two authentication methods:

    • MetaMask integration (requires pre-configured delegation)

    • Private key input (sets up delegation automatically)

    Architecture Overview

    Understanding Account Abstraction

    EIP-7702: Protocol-Level Account Abstraction

    EIP-7702 introduces a new transaction type that allows EOAs to delegate their execution logic to smart contracts:

    • No Address Change EOAs maintain their original addresses

    • Code Delegation EOA delegates code execution to a specified smart contract

    • Native Batching Execute multiple operations in a single transaction

    • Backward Compatible Works with existing infrastructure

    Key Innovation: The SET_CODE_TX_TYPE transaction format with authorization lists enables EOAs to act as smart accounts without permanent migration.

    ERC-4337: Smart Account Framework

    ERC-4337 provides a complete account abstraction solution without protocol changes:

    • UserOperations Pseudo-transactions that encapsulate user intent

    • Bundlers Aggregate and submit UserOps to the blockchain

    • EntryPoint Singleton contract for validation and execution

    • Paymasters Services that sponsor gas fees

    Key components:

    1. Sender ERC-4337 compatible smart contract wallet

    2. UserOperation Contains nonce, calldata, gas limits, and signatures

    3. Bundler Collects UserOps and submits them on-chain

    4. Paymaster Covers transaction fees on behalf of users

    How They Work Together

    EIP-7702 and ERC-4337 are complementary, not competing standards:

    1. EIP-7702 upgrades an EOA to execute smart contract code

    2. The upgraded EOA implements ERC-4337's IAccount interface

    3. The account can now receive UserOperations through EntryPoint

    4. Paymasters can sponsor gas for the upgraded account

    Project Components

    Smart Contracts (/contracts)

    • TicTacToe.sol: Main game contract with UUPS upgradeability

    • PrizeToken.sol: ERC20 token for game rewards

    • Simple7702Account.sol: EIP-7702 compatible account implementation (in /contracts/testing)

    • TargetCheckingPaymaster.sol: Paymaster that sponsors specific contract calls

    Backend Services (/cmd)

    senduserop

    • Demonstrates UserOperation creation and submission

    • EIP-7702 authorization signing

    • Gas estimation and fee calculation

    • Direct EntryPoint interaction

    tictactoebot

    • Automated game player with an AI strategy

    • Event monitoring and subscription

    • Minimax algorithm implementation

    • Keystore management

    Frontend (/frontenddemo)

    • Vue.js single-page application

    • UserOperation construction in the browser

    • MetaMask and private key support

    • Real-time game interaction

    Testing (/test)

    • Comprehensive contract testing

    • Paymaster validation tests

    • Game logic verification

    • Gas usage optimization

    Installation & Setup

    Prerequisites

    • Node.js 18+ and npm

    • Go 1.24+ (yes, 1.24 is correct - see go.mod)

    • Git

    • A funded wallet for deploying contracts and running the bundler

    Clone Repository

    Install Dependencies

    Environment Configuration

    Create a .env file in the root directory:

    Notes:

    • Private key should be without the '0x' prefix

    • Sonic RPC URL is already configured in hardhat.config.ts

    Deployment

    Compile Contracts

    Deploy Contracts

    Deploy to Sonic testnet (chain ID 14601):

    Verify Contracts

    Running the Demo

    1. Start the Bundler

    The bundler aggregates UserOperations and submits them to the EntryPoint:

    The bundler RPC will be exposed at: http://localhost:3000/rpc

    Notes:

    • Use --unsafe flag for RPCs that don't support debug_traceCall (most public RPCs)

    • The mnemonic account needs sufficient balance to send transactions (0.1 S recommended)

    2. Start the TicTacToe Bot

    The bot automatically plays games and demonstrates event monitoring:

    Bot flags:

    • --gameAddress: TicTacToe contract address

    • --startBlock: Block number to start event scanning (default: 1)

    • --joiningDelay: Time to wait before joining new games (default: 1 minute)

    3. Launch Frontend

    Open in your browser.

    Testing

    Run the comprehensive test suite:

    Technical Deep Dive

    UserOperation Structure

    EIP-7702 Authorization

    Paymaster Validation

    The TargetCheckingPaymaster validates:

    1. Account code hash matches whitelist

    2. The target contract is approved

    3. Gas fees are within limits

    Game Mechanics

    • Board Size: 5x5 grid

    • Win Condition: 4 stones in a row

    • Rewards: 10 tokens for the winner, one token each for the draw

    • Timeout: 24 hours per move

    Developer Resources

    Key Concepts

    Account abstraction benefits:

    • 🔒 Enhanced security with smart account features

    • ⛽ Gas sponsorship for better UX

    • 📦 Transaction batching for efficiency

    • 🔑 Flexible authentication methods

    Implementation patterns:

    1. Delegation Pattern EOA delegates to smart contract logic

    2. Validation Pattern Custom signature validation in accounts

    3. Sponsorship Pattern Paymasters cover gas costs

    4. Batching Pattern Multiple operations in a single transaction

    API References

    Smart account interface:

    Paymaster interface:

    Troubleshooting

    Common issues and solutions:

    1. "AA25 invalid account nonce": Account nonce mismatch - check EntryPoint.getNonce()

    2. "AA33 reverted": Paymaster validation failed - check gas limits

    3. "AA51 prefund too low": Insufficient paymaster deposit

    4. "Not from self or EntryPoint": Invalid caller for account execution

    Additional setup issues:

    1. Frontend bundler connection: Update bundler URL in Vue components if not using default

    2. Go version error: Ensure Go 1.24+ is installed (check with go version)

    3. Contract deployment fails: Ensure wallet has sufficient funds and correct network is selected

    4. Bot can't join games: Check keystore file permissions and passphrase

    Further Reading

    ERC-4337: Smart Account Framework

  • How They Work Together

  • Project Components

  • Installation & Setup

  • Deployment

  • Running the Demo

  • Testing

  • Technical Deep Dive

  • Developer Resources

  • Real-time UserOperation construction and submission

    Persistent Until Changed Delegation remains active until explicitly updated

    Users benefit from both simple EOA interactions AND smart account features

    SignatureCheckingPaymaster.sol: Paymaster with signature validation

  • Note: EntryPoint contract is imported from @account-abstraction/contracts

  • --blocksPerQuery: Max block range for event queries (default: 10000)
  • --keystore: Path to keystore JSON file

  • --keystorePass: Path to keystore passphrase file (optional)

  • Storage: Packed uint256 for efficient gas usage
    🔄 Social recovery and multi-sig support

    Bundler errors: Ensure the mnemonic account has funds for gas

    bundler
    Key Features
    Architecture Overview
    Understanding Account Abstraction
    EIP-7702: Protocol-Level Account Abstraction
    http://localhost:5173
    EIP-7702 Specification
    ERC-4337 Specification
    Account Abstraction Resources
    git clone <repository-url>
    cd TicTacToeDemo
    # Install Node.js dependencies
    npm install
    
    # Install Go dependencies
    go mod download
    
    # Install frontend dependencies
    cd frontenddemo
    npm install
    cd ..
    # Required for deployment
    PRIVATE_KEY=your_private_key_here_without_0x_prefix
    npx hardhat compile
    # Deploy complete TicTacToe system
    npx hardhat ignition deploy ./ignition/modules/TicTacToe.ts --network sonic-testnet
    
    # Deploy paymasters separately (if needed)
    npx hardhat ignition deploy ./ignition/modules/TargetCheckingPaymaster.ts --network sonic-testnet
    npx hardhat ignition deploy ./ignition/modules/SignatureCheckingPaymaster.ts --network sonic-testnet
    # For Sonic testnet
    npx hardhat ignition verify --network sonic-testnet
    # Clone the bundler (if not already done)
    git clone https://github.com/eth-infinitism/bundler
    cd bundler
    
    
    # Configure and run
    yarn install
    yarn run bundler --network https://rpc.soniclabs.com/ \
                     --mnemonic path/to/mnemonic.txt \
                     --entryPoint 0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108 \
                     --unsafe
    
    # Build the bot
    cd cmd/tictactoebot
    go build
    
    
    # Run with configuration
    ./tictactoebot \
      --rpcUrl https://rpc.soniclabs.com/ \
      --gameAddress 0xYourGameAddress \
      --keystore path/to/keystore.json \
      --joiningDelay 30s
    cd frontenddemo
    npm run dev
    
    # Run all tests
    npx hardhat test
    
    # Run with gas reporting
    REPORT_GAS=true npx hardhat test
    
    # Run with detailed traces
    npx hardhat test --fulltrace
    
    # Run specific test file
    npx hardhat test test/TicTacToe.ts
    struct PackedUserOperation {
        address sender;               // Smart account address
        uint256 nonce;               // Anti-replay parameter
        bytes initCode;              // Account creation code (if needed)
        bytes callData;              // Execution calldata
        bytes32 accountGasLimits;    // Verification and call gas limits
        uint256 preVerificationGas;  // Gas for bundler overhead
        bytes32 gasFees;            // maxPriorityFee and maxFeePerGas
        bytes paymasterAndData;      // Paymaster address and data
        bytes signature;             // Account signature
    }
    auth := types.SetCodeAuthorization{
        ChainID: chainId,
        Address: accountImplementation,  // Smart account code
        Nonce:   accountNonce,
    }
    signedAuth := SignSetCode(privateKey, auth)
    interface IAccount {
        function validateUserOp(
            PackedUserOperation calldata userOp,
            bytes32 userOpHash,
            uint256 missingAccountFunds
        ) external returns (uint256 validationData);
    }
    interface IPaymaster {
        function validatePaymasterUserOp(
            PackedUserOperation calldata userOp,
            bytes32 userOpHash,
            uint256 maxCost
        ) external returns (bytes memory context, uint256 validationData);
    }