# 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 [S token](/sonic/s-token) 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**](/funding/fee-monetization)\
  Developers earn 90% of the network fees generated by their applications.

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden></th></tr></thead><tbody><tr><td><strong>Users</strong></td><td><ul><li><a href="https://howtobridge.soniclabs.com/">Bridge to Sonic</a></li><li><a href="/pages/XDSSsEBqwfoWqSLkcMqt">Earn Airdrop Points</a></li><li><a href="https://x.com/SonicEcosystem">Explore Apps</a></li></ul></td><td><a href="/files/WQC7AtDQgyZdo2QQ8brZ">/files/WQC7AtDQgyZdo2QQ8brZ</a></td><td></td></tr><tr><td><strong>Developers</strong></td><td><ul><li><a href="/pages/jkBoDV4g6fZeJzFS4edy">Deploy App</a></li><li><a href="/pages/ufSdxgvh3d1zmXlcHfOu">Fee Monetization</a></li><li><a href="/pages/IdCHVPoSWSMEH34SmbHG">Earn Airdrop Gems</a></li></ul></td><td><a href="/files/PBnAyi4xIFTObRvReYp3">/files/PBnAyi4xIFTObRvReYp3</a></td><td></td></tr></tbody></table>

## Network Information

* **Network name**: Sonic
* **RPC URL:** [**https://rpc.soniclabs.com**](https://rpc.soniclabs.com)
* **Explorer URL:** [**https://sonicscan.org**](https://sonicscan.org)
* **Chain ID**: 146
* **Currency symbol**: S


# 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:

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden></th></tr></thead><tbody><tr><td><a href="/pages/ufSdxgvh3d1zmXlcHfOu"><strong>Fee Monetization</strong></a></td><td>Developers earn 90% of the network fees their apps generate.</td><td></td></tr><tr><td><a href="/pages/FKimegjIg4Rb9RN8D0rY"><strong>Innovator Fund</strong></a></td><td>Up to 200 million S to onboard apps to Sonic and support new ventures.</td><td></td></tr><tr><td><a href="/pages/ZxZwqsejKNoJy2uejYID"><strong>Airdrop</strong></a></td><td>~200 million S to incentivize users of Sonic via an innovative points program.</td><td></td></tr></tbody></table>

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 [native token](/sonic/s-token) of Sonic is S, which is used for transaction fees, staking, running validators, and participating in governance.

Furthermore, the [Sonic Gateway](/sonic/sonic-gateway) 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.


# 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](/sonic/node-deployment/validator-node), and participating in governance.

— [Staking](#staking)\
— [Tokenomics](/sonic/s-token#tokenomics)\
‎‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎— [Institutional Expansion](#institutional-expansion)\
‎‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎— [Airdrop](#airdrop)\
‎‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎— [Ongoing Funding](#ongoing-funding)\
‎‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎— [Block Rewards](#block-rewards)\
‎‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎— [Token Burn](#token-burn)\
— [Validator Rewards](#validator-rewards)\
— [Ecosystem Vault](#ecosystem-vault)

## Staking

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

1. Visit [MySonic](https://my.soniclabs.com/stake).
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.

***

## Tokenomics

### Institutional Expansion

A [governance proposal](https://snapshot.box/#/s:info.sonic/proposal/0x489f1583b2db1e6e752404626283249223a1dbfb7337f4fb7dbaf28b1da1b759) 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 [occurred on September 4, 2025](https://sonicscan.org/tx/0x2acf561539705b8d0004da7aaa5e8ee2971e34fdbca0e017ac753761e862ae2c). 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 [SonicStrategy](https://www.sonicstrategy.io/).

* [126,622,348.845 S transfer](https://sonicscan.org/tx/0xbf6f4e580d849b1b5f02c654fb72e0882fd6bfb3002d1ea9e501a44c7e743bb9) to **old** SonicStrategy DAT Multisig
* [500,000 S transfer](https://sonicscan.org/tx/0xf27eab2abc9451302492d18c05660103e06cd66249570c2cd9412e5a8a8074e9) to **new** SonicStrategy DAT Multisig for validator setup
* [126,122,433.845 S transfer](https://sonicscan.org/tx/0xf31d3b9f08fde90ab3e42384e3676d0758a87c86ef0b6b68124f1f194668ba1d) 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 [airdrop program](/funding/sonic-airdrop). The airdrop features an [innovative burn mechanism](https://blog.soniclabs.com/designing-a-deflationary-airdrop/) that rewards active participation and gradually reduces the total supply of S tokens.

The first issuance of 89,778,181.9 S occurred on [July 17, 2025](https://sonicscan.org/tx/0xd0d0148b527c9c60373e73ce9320925146cbdb466356b92a4d153c3a9111ccf6) and [July 31, 2025](https://sonicscan.org/tx/0x0550080bece31fabecbd52a224b2a7bc15c70151bf55b08417113e6b44c16878).

### Ongoing Funding

To fund ongoing growth and expansion, the Sonic network could [issue additional S tokens](https://forum.fantom.network/t/governance-vote-3-booming-and-building-for-the-long-run/1240) 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 [this wallet](https://sonicscan.org/address/0xfcecc79bc12b7c3bb96d9d062ecb7f830961a2e7). The first issuance of 47,625,000 S [occurred on June 18, 2025](https://sonicscan.org/tx/0xce8078a6e5c44630f86868034df50d8e08b18e3f405d912696a7e745c40d7508).

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

[Block rewards](https://forum.fantom.network/t/gov-vote-4-unlocking-the-new-frontier-for-validators-and-stakeholders/1273) 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.

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden></th></tr></thead><tbody><tr><td><a href="/pages/ZxZwqsejKNoJy2uejYID">Airdrop Burn</a></td><td>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.</td><td></td></tr><tr><td><a href="#ongoing-funding">Ongoing Funding Burn</a></td><td>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.</td><td></td></tr></tbody></table>

***

## 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.&#x20;

### 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, [as outlined above](#block-rewards).

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, [see here](/funding/fee-monetization#fee-structure).

<br>


# USSD

### **What is** [**USSD**](https://www.soniclabs.com/USSD)**?**

USSD is a U.S. Treasury-backed stablecoin native to the Sonic ecosystem. It is built on [Frax's](https://frax.com/) GENIUS-compatible frxUSD stablecoin infrastructure and serves as the primary source of stable liquidity across Clove and the broader Sonic network.

USSD is designed to be a foundational asset within the Sonic ecosystem — powering lending markets, trading pairs, and liquidity across the platform's integrated products.

### **Backing & Collateral**

USSD is fully backed 1:1 by short-duration USD assets held with regulated custodians. Reserves are composed of tokenized U.S. Treasury products from established institutions, including:

* BlackRock (BUIDL)
* Superstate (USTB)
* WisdomTree (WTGXX)
* Additional top-tier providers as the reserve set expands

All reserves are transparent and verifiable on-chain through Frax's infrastructure.

***

### **Minting**

USSD is minted through non-custodial smart contracts at a 1:1 ratio with no minting fees.

Supported mint assets include:

* **Stablecoins:** USDC, USDT, PYUSD, USDB
* **Tokenized Treasuries:** BUIDL, USTB, WTGXX, and other approved USD/Treasury representations

USSD supports cross-chain minting from 10+ networks. Users can deposit a supported asset on another chain and receive USSD directly on Sonic, depending on available routes.

Mint now: [**Mint USSD**](https://net.frax.com/dashboard/mint)

### Redemption

USSD can be redeemed 1:1 into supported USD assets on the chain of your choice. Redemption is contract-driven and supports:

* Cross-chain liquidity movement
* Settlement and treasury operations
* Rebalancing between ecosystems

*Redemption paths are available across CCTP-supported chains where applicable.*

Redeem now: [**Redeem USSD**](https://net.frax.com/dashboard/redeem)

### Fiat On/Off-Ramp

Subject to applicable KYC/AML requirements and issuer approval, eligible users may access fiat conversion routes through supported infrastructure.

On/Off-ramp now: [**On/Off-ramp USSD**](https://net.frax.com/dashboard/redeem)

***

### **Contract & Deployments**

**Contract & Deployments**

Contract address: [`0x000000000eccff26b795f73fb0a70d48da657fef`](https://sonicscan.org/token/0x000000000eccff26b795f73fb0a70d48da657fef)

Deployed on: [Sonic](https://sonicscan.org/token/0x000000000eccff26b795f73fb0a70d48da657fef), [Ethereum](https://etherscan.io/address/0x000000000eccff26b795f73fb0a70d48da657fef), [Base](https://basescan.org/address/0x000000000eccff26b795f73fb0a70d48da657fef), [Arbitrum](https://arbiscan.io/address/0x000000000eCcFf26B795F73fb0A70d48da657fEf), and 7 additional chains.

***

### Price Feeds

USSD/USD pricing is available on-chain via Chainlink. Additional price feeds will be added as USSD expands across supported networks.

| Asset Pair | Provider                                                        | Network |
| ---------- | --------------------------------------------------------------- | ------- |
| USSD/USD   | [Chainlink](https://data.chain.link/feeds/sonic/sonic/ussd-usd) | Sonic   |

***

### **Why a Native Stablecoin?**

Unlike externally issued stablecoins that serve multiple blockchain networks, USSD is designed to be native to Sonic. This alignment means stablecoin liquidity grows alongside the network and its applications, rather than being fragmented across competing ecosystems. The underlying Treasury yield flows back into the DeFi ecosystem through Frax's infrastructure.

***

***For more information on Frax's stablecoin infrastructure and security track record, visit*** [***frax.com***](https://frax.com/)***.***

***Security audit for Frax (USD Stablecoin):*** [***Frax USD Stablecoin Audit by Zellic***](https://github.com/Zellic/publications/blob/master/Frax%20\(USD%20Stablecoin\)%20-%20Zellic%20Audit%20Report.pdf)

***See*** [***USSD Disclaimer***](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFigzFE2ScpiZHSkLRCev%2Fuploads%2F6pFXKqf7Kq4tnm3p3bmw%2FFRXUSD%20_%20USSD%20Disclaimer.pdf?alt=media\&token=234509c8-e339-4a05-8ac9-a101c5963313) ***for important disclosures.***


# 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**](https://rpc.soniclabs.com)
* **Explorer URL:** [**https://sonicscan.org**](https://sonicscan.org)
* **Chain ID**: 146
* **Currency symbol**: S

## User Wallets

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th data-hidden></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td>Rabby Wallet</td><td></td><td></td><td><a href="https://rabby.io/">https://rabby.io/</a></td><td><a href="/files/f2xsQouKq4xmOqp1lxuh">/files/f2xsQouKq4xmOqp1lxuh</a></td></tr><tr><td>MetaMask</td><td></td><td></td><td><a href="https://metamask.io/">https://metamask.io/</a></td><td><a href="/files/HRsRPW8i7v069DAISIBm">/files/HRsRPW8i7v069DAISIBm</a></td></tr><tr><td>OKX Wallet</td><td></td><td></td><td><a href="https://www.okx.com/web3">https://www.okx.com/web3</a></td><td><a href="/files/rIaOz1yp4vZzGFNYC2ro">/files/rIaOz1yp4vZzGFNYC2ro</a></td></tr><tr><td>Trust Wallet</td><td></td><td></td><td><a href="https://trustwallet.com/">https://trustwallet.com/</a></td><td><a href="/files/GrJj2ingt5ZIOtxqhSuF">/files/GrJj2ingt5ZIOtxqhSuF</a></td></tr><tr><td>Bitget Wallet</td><td></td><td></td><td><a href="https://web3.bitget.com/en">https://web3.bitget.com/en</a></td><td><a href="/files/GW6mx7h2xwxuTYy2fRSQ">/files/GW6mx7h2xwxuTYy2fRSQ</a></td></tr><tr><td>1inch Wallet</td><td></td><td></td><td><a href="https://1inch.io/wallet/">https://1inch.io/wallet/</a></td><td><a href="/files/ZGw7tFi7v8AjxvCtkDCm">/files/ZGw7tFi7v8AjxvCtkDCm</a></td></tr></tbody></table>

## Institutional Wallets

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th data-hidden></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td>Safe</td><td></td><td></td><td><a href="https://safe.global/">https://safe.global/</a></td><td><a href="/files/avW2uws29ZoPOJmP15jI">/files/avW2uws29ZoPOJmP15jI</a></td></tr><tr><td>Safe (Backup)</td><td></td><td></td><td><a href="https://sonic.palmeradao.xyz/welcome">https://sonic.palmeradao.xyz/welcome</a></td><td><a href="/files/MHvhQBlZ6ToGQqlkMjzO">/files/MHvhQBlZ6ToGQqlkMjzO</a></td></tr><tr><td>Fordefi</td><td></td><td></td><td><a href="https://fordefi.com/">https://fordefi.com/</a></td><td><a href="/files/1N2LbYfAmSuyOaP6jXt1">/files/1N2LbYfAmSuyOaP6jXt1</a></td></tr><tr><td>Fireblocks</td><td></td><td></td><td><a href="https://www.fireblocks.com/">https://www.fireblocks.com/</a></td><td><a href="/files/nPRgwfwlzDx8SPrgegpf">/files/nPRgwfwlzDx8SPrgegpf</a></td></tr></tbody></table>


# Sonic Gateway

— [Quick Overview](#quick-overview)\
— [Introduction](#introduction)\
— [Fail-Safe Mechanism](#gateway-fail-safe-mechanism)\
— [Fast Lane](#fast-lane)\
— [Looking Into the Future](#looking-into-the-future)\
— [Frequently Asked Questions](#frequently-asked-questions)

## Quick Overview

The [Sonic Gateway](https://gateway.soniclabs.com) 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.

{% hint style="info" %}
Sonic Gateway uses [Circle’s CCTP V2](https://www.circle.com/cross-chain-transfer-protocol) for USDC transfers.
{% endhint %}

## 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 [$2.5 billion lost](https://cointelegraph.com/news/report-half-of-all-defi-exploits-are-cross-bridge-hacks?ref=blog.soniclabs.com) 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.

<figure><img src="/files/PshAXGsnQl03nLmRtPgP" alt=""><figcaption><p>Credit: <a href="https://x.com/paramonoww?ref=blog.soniclabs.com">Pavel Paramonov</a></p></figcaption></figure>

### Fail-Safe Mechanism <a href="#gateway-fail-safe-mechanism" id="gateway-fail-safe-mechanism"></a>

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.

<figure><img src="/files/juJUWiTbv37DQ2HVlSoB" alt=""><figcaption><p>Credit: <a href="https://x.com/paramonoww?ref=blog.soniclabs.com">Pavel Paramonov</a></p></figcaption></figure>

### 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 <a href="#looking-into-the-future" id="looking-into-the-future"></a>

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

<details>

<summary><strong>Does the Sonic Gateway also secure third-party bridges?</strong></summary>

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.

</details>

<details>

<summary><strong>Does Sonic rely on the state of Ethereum?</strong></summary>

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.

</details>

<details>

<summary><strong>Does Sonic store data on Ethereum?</strong></summary>

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 (2x256-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.

</details>

## 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.


# 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](/funding/fee-monetization), necessary to innovate and thrive in the ecosystem.

Test your contracts on the [Sonic testnet](/sonic/build-on-sonic/getting-started#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.

{% hint style="info" %}
To meet other builders and receive support, join the [official Sonic builders group](https://t.me/SonicBuilders).
{% endhint %}


# Getting Started

Sonic offers developers two distinct networks to build and deploy their apps. First, the [Sonic testnet](https://testnet.soniclabs.com/) 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:

{% tabs %}
{% tab title="Sonic Mainnet" %}

* **Network name**: Sonic
* **RPC URL:** [**https://rpc.soniclabs.com**](https://rpc.soniclabs.com)
* **Explorer URL:** [**https://sonicscan.org**](https://sonicscan.org)
* **Explorer API:** [**https://api.etherscan.io/v2/api?chainid=146**](https://api.etherscan.io/v2/api?chainid=146)
* **Chain ID**: 146
* **Currency symbol**: S
  {% endtab %}

{% tab title="Sonic Testnet" %}

* **Network name**: Sonic Testnet
* **RPC URL:** [**https://rpc.testnet.soniclabs.com**](https://rpc.testnet.soniclabs.com/)
* **Explorer URL:** [**https://testnet.sonicscan.org**](https://testnet.sonicscan.org)
* **Explorer API:** [**https://api.etherscan.io/v2/api?chainid=14601**](https://api.etherscan.io/v2/api?chainid=14601)
* **Chain ID**: 14601
* **Currency symbol**: S
* **Faucet:** [**https://testnet.soniclabs.com/account**](https://testnet.soniclabs.com/account)
  {% endtab %}
  {% endtabs %}

{% hint style="info" %}
To meet other builders and receive support, join the [official Sonic builders group](https://t.me/SonicBuilders).
{% endhint %}


# 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 [https://rpc.testnet.soniclabs.com](https://rpc.blaze.soniclabs.com) as the connection endpoint for the Sonic testnet or <https://rpc.soniclabs.com> for the mainnet.

For the Sonic testnet, you can use the [Sonic testnet dashboard](https://testnet.soniclabs.com/account) 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:

{% tabs %}
{% tab title="Sonic Mainnet" %}

```solidity
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]
    }
  }
};
```

{% endtab %}

{% tab title="Sonic Testnet" %}

```solidity
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]
    }
  }
};
```

{% endtab %}
{% endtabs %}

To deploy, execute `npx hardhat run scripts/deploy.js --network sonic`.&#x20;

{% hint style="info" %}
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.
{% endhint %}


# 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 [Sonic mainnet explorer](https://sonicscan.org/) and the [Sonic testnet explorer](https://testnet.sonicscan.org/).

— [Method 1: Hardhat Verification](#method-1.-hardhat-verification-recommended)\
— [Method 2: Programmatic Verification<br>](#method-2-programmatic-verification)— [Method 3: Manual Verification](#method-3-manual-verification)\
— [Method 4: Flattened Source](#method-4-flattened-source)\
— [Troubleshooting](#troubleshooting)

## Method 1. Hardhat Verification (*Recommended*)

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

1. Install Hardhat toolbox:

```bash
npm install --save-dev @nomicfoundation/hardhat-toolbox
```

2. Configure `hardhat.config.js`:

```javascript
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"
        }
      }
    ]
  }
};
```

3. Store your SonicScan API key in a `.env` file:

```
API_KEY=your_sonicscan_api_key
```

4. Verify your contract:

```bash
# For mainnet
npx hardhat verify --network sonic DEPLOYED_CONTRACT_ADDRESS [CONSTRUCTOR_ARGUMENTS]

# For testnet
npx hardhat verify --network sonicTestnet DEPLOYED_CONTRACT_ADDRESS [CONSTRUCTOR_ARGUMENTS]
```

## Method 2: Programmatic Verification

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

```javascript
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]
  });
}
```

## Method 3: Manual Verification

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

1. Go to the [Sonic explorer](https://sonicscan.org/) (or the [testnet explorer](https://testnet.sonicscan.org/))
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. [HashEx](https://abi.hashex.org/)
   * 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:

```bash
npm install --save-dev hardhat-flattener
```

2. Flatten your contract:

```bash
npx hardhat flatten contracts/YourContract.sol > flattened.sol
```

3. 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


# 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.

***

<details>

<summary>Automation/VRF</summary>

* [Gelato](https://docs.gelato.network/web3-services/web3-functions)
* [Pyth Network (Entropy)](https://www.pyth.network/entropy)

</details>

<details>

<summary>Data Indexers</summary>

* [Alchemy](https://www.alchemy.com/subgraphs)
* [Sentio](https://docs.sentio.xyz/docs/supported-networks#sonic)
* [The Graph](https://thegraph.com/docs/en/quick-start/)
* [OnFinality](https://indexing.onfinality.io/)
* [QuickNode](https://www.quicknode.com/chains/sonic)
* [SubQuery](https://subquery.network/indexer/146)
* [SQD](https://v2.archive.subsquid.io/network/sonic-mainnet)

</details>

<details>

<summary>Development Tools</summary>

* [Sentio Explorer](https://app.sentio.xyz/explorer)
* [Tenderly](https://tenderly.co/)
* [thirdweb](https://thirdweb.com/sonic)

</details>

<details>

<summary>Explorers</summary>

* [Arkham](https://intel.arkm.com/)
* [CoinStats API](https://dev-c758229b.mintlify.dev/docs)
* [SonicScan](https://sonicscan.org/)

</details>

<details>

<summary>Interoperability</summary>

* [Chainlink](https://docs.chain.link/ccip/directory/mainnet/chain/sonic-mainnet)
* [LayerZero](https://layerzero.network/)
* [Reactive Network](https://reactive.network/)

</details>

<details>

<summary>Oracles</summary>

* [API3](https://market.api3.org/sonic)
* [Band Protocol](https://www.bandprotocol.com/standard-dataset)
* [Chainlink (Data Streams)](https://chain.link/data-streams)
* [Chainlink (Data Feeds)](https://chain.link/data-feeds)
* [Pyth Network (Price Feed](https://www.pyth.network/price-feeds)[)](https://www.pyth.network/price-feeds)
* [Stork Network](https://www.stork.network/)
* [Supra](https://docs.supra.com/oracles)
* [DIA](https://www.diadata.org)

</details>

<details>

<summary>RPCs</summary>

Official RPC by Sonic Labs.

* [**https://rpc.soniclabs.com**](https://rpc.soniclabs.com)
* wss\://rpc.soniclabs.com

***

* [Ankr](https://www.ankr.com/rpc/sonic)
* [Alchemy](https://www.alchemy.com/)
* [Chainstack](https://chainstack.com/build-better-with-sonic/)
* [dRPC](https://drpc.org/chainlist/sonic)
* [OnFinality](https://www.onfinality.io/en/networks/sonic)
* [QuickNode](https://www.quicknode.com/chains/sonic)
* [thirdweb](https://thirdweb.com/sonic)
* [NowNodes](https://nownodes.io/nodes/sonic-s)

</details>

<details>

<summary>On-Ramps</summary>

* [Alchemy Pay](https://alchemypay.org/)
* [Banxa](https://banxa.com/)
* [ChangeNOW](https://changenow.io/)
* [Changelly](https://changelly.com/)
* [Guardarian](https://guardarian.com/)
* [Mt Pelerin](https://www.mtpelerin.com/)
* [Onramp Money](https://onramp.money/)
* [Onramper](https://www.onramper.com/)
* [Topper](https://www.topperpay.com/)
* [TransFi](https://www.transfi.uk/)
* [Wirex](https://wirexapp.com/)

</details>


# 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 [Sonic testnet](https://testnet.soniclabs.com/).

The address of USDC on the testnet is [0x0BA304580ee7c9a980CF72e55f5Ed2E9fd30Bc51](https://testnet.sonicscan.org/address/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

```bash
mkdir usdc-transfer-app
cd usdc-transfer-app
npm init -y
```

Step 2: Install dependencies

```bash
npm install react@latest react-dom@latest \
  @types/react@latest @types/react-dom@latest \
  @vitejs/plugin-react@latest typescript@latest \
  vite@latest viem@latest
```

Step 3: Verify `package.json`&#x20;

```jsonc
{
  "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"
  }
}
```

Step 4: Add the `scripts` section (if needed)&#x20;

```jsonc
"scripts": {
  "dev": "vite",
  "build": "vite build",
  "preview": "vite preview"
}
```

Step 5: Run the dev server

```bash
npm run dev
```

***

### 3. Configure Blockchain Clients

Create **`src/clients.ts`**:

```ts
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),
});
```

***

### 4. Define USDC Contract Details

Create **`src/constants.ts`**:

```ts
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',
  },
];
```

***

### 5. Implement Wallet Connection & USDC Transfer

Create **`src/App.tsx`**:

```tsx
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;
```

***

### 6. Configure the Entry Point

Create **`src/main.tsx`**:

```tsx
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>,
);
```

***

### 7. Create `index.html`

```html
<!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>
```

***

### 8. Start the Application

```bash
npm run dev
```

Open [**http://localhost:5173**](http://localhost:5173/) in your browser and start transferring USDC on the Sonic testnet!


# Contract Addresses

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

{% tabs %}
{% tab title="Sonic Mainnet" %}
**Tokens:**

* [Wrapped S (wS)](https://sonicscan.org/address/0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38)
  * 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38
* [Wrapped Ether (WETH)](https://sonicscan.org/address/0x50c42dEAcD8Fc9773493ED674b675bE577f2634b)
  * 0x50c42dEAcD8Fc9773493ED674b675bE577f2634b
* [USDC](https://sonicscan.org/address/0x29219dd400f2Bf60E5a23d13Be72B486D4038894)
  * 0x29219dd400f2Bf60E5a23d13Be72B486D4038894
* [EURC (Bridged)](https://sonicscan.org/address/0xe715cba7b5ccb33790cebff1436809d36cb17e57)
  * 0xe715cba7b5ccb33790cebff1436809d36cb17e57
* [USDT (Bridged)](https://sonicscan.org/token/0x6047828dc181963ba44974801ff68e538da5eaf9)
  * 0x6047828dc181963ba44974801ff68e538da5eaf9

**Core Contracts:**

* [SFC](https://sonicscan.org/address/0xFC00FACE00000000000000000000000000000000)
  * 0xFC00FACE00000000000000000000000000000000
* [Multicall3](https://sonicscan.org/address/0xcA11bde05977b3631167028862bE2a173976CA11)
  * 0xcA11bde05977b3631167028862bE2a173976CA11
* [FTM to S Upgrade Portal (Opera)](https://ftmscan.com/address/0x3561607590e28e0848ba3B67074C676D6D1C9953)
  * 0x3561607590e28e0848ba3B67074C676D6D1C9953
* [FTM to S Upgrade Portal (Sonic)](https://sonicscan.org/address/0x3561607590e28e0848ba3B67074C676D6D1C9953)
  * 0x3561607590e28e0848ba3B67074C676D6D1C9953

**Gateway Infrastructure (on Sonic):**

* [MPTProofVerifier](https://sonicscan.org/address/0xD2f1e904dAf7446686F8057b7dfeb068c75D29A9)
  * 0xD2f1e904dAf7446686F8057b7dfeb068c75D29A9
* [StateOracle](https://sonicscan.org/address/0x836664B0c0CB29B7877bCcF94159CC996528F2C3)
  * 0x836664B0c0CB29B7877bCcF94159CC996528F2C3
* [ValidatorsRegistry](https://sonicscan.org/address/0x12727D4169a42A9b5E3ECB11A6d2c95553d3f447)
  * 0x12727D4169a42A9b5E3ECB11A6d2c95553d3f447
* [MessageBus](https://sonicscan.org/address/0xB5B371B75f9850dDD6CCB6C436DB54972a925308)
  * 0xB5B371B75f9850dDD6CCB6C436DB54972a925308
* [TokenPairs](https://sonicscan.org/address/0x134E4c207aD5A13549DE1eBF8D43c1f49b00ba94)
  * 0x134E4c207aD5A13549DE1eBF8D43c1f49b00ba94
  * [Implementation](https://sonicscan.org/address/0xE34e6851a4a3763e1d27aa7ac5980d2D33C2d315): 0xE34e6851a4a3763e1d27aa7ac5980d2D33C2d315
* [Bridge](https://sonicscan.org/address/0x9Ef7629F9B930168b76283AdD7120777b3c895b3)
  * 0x9Ef7629F9B930168b76283AdD7120777b3c895b3
  * [Implementation](https://sonicscan.org/address/0x0B3fe0c10C050270a9bc34271987989B6CF2107C): 0x0B3fe0c10C050270a9bc34271987989B6CF2107C
* [UpdateManager](https://sonicscan.org/address/0x1D3c99DA3CEF5C26f02a86dC7D685efa40176bb7)
  * 0x1D3c99DA3CEF5C26f02a86dC7D685efa40176bb7
  * [Implementation](https://sonicscan.org/address/0x1071405A4736535C545580064039A235827ee6D4): 0x1071405A4736535C545580064039A235827ee6D4

**Gateway Infrastructure (on Ethereum):**

* [MPTProofVerifier](https://etherscan.io/address/0x921B147a90Ef738BBb7c2c89D88ea9d8Af3e9306)
  * 0x921B147a90Ef738BBb7c2c89D88ea9d8Af3e9306
* [StateOracle](https://etherscan.io/address/0xB7e8CC3F5FeA12443136f0cc13D81F109B2dEd7f)
  * 0xB7e8CC3F5FeA12443136f0cc13D81F109B2dEd7f
* [ValidatorsRegistry](https://etherscan.io/address/0x72965045A6691E5A74299D1e878f303264D4D910)
  * 0x72965045A6691E5A74299D1e878f303264D4D910
* [TokenPairs](https://etherscan.io/address/0xf2b1510c2709072C88C5b14db90Ec3b6297193e4)
  * 0xf2b1510c2709072C88C5b14db90Ec3b6297193e4
  * [Implementation](https://etherscan.io/address/0x0c40Ae1c82401EA741953D3f026ADc07BE9e7943): 0x0c40Ae1c82401EA741953D3f026ADc07BE9e7943
* [TokenDeposit](https://etherscan.io/address/0xa1E2481a9CD0Cb0447EeB1cbc26F1b3fff3bec20)
  * 0xa1E2481a9CD0Cb0447EeB1cbc26F1b3fff3bec20
  * [Implementation](https://etherscan.io/address/0x4cbd824685F1E21B119F230B54d65C5a7D2a5330): 0x4cbd824685F1E21B119F230B54d65C5a7D2a5330
* [DirectExitAdministrator](https://etherscan.io/address/0x7390251Bf35AA7eA7C196fc4750bd5d6c5918329)
  * 0x7390251Bf35AA7eA7C196fc4750bd5d6c5918329
* [UpdateManager](https://etherscan.io/address/0xB0bECf0fBfE431D42bA0FbD8dFBFbB0DCFd62Da4)
  * 0xB0bECf0fBfE431D42bA0FbD8dFBFbB0DCFd62Da4
  * [Implementation](https://etherscan.io/address/0x13bd43A6BE5795D4A4E3Efc4baC21Cd36Ae9e68A): 0x13bd43A6BE5795D4A4E3Efc4baC21Cd36Ae9e68A
    {% endtab %}

{% tab title="Sonic Testnet" %}
**Tokens:**

* [Wrapped S (wS)](https://testnet.sonicscan.org/address/0x039e2fb66102314ce7b64ce5ce3e5183bc94ad38)
  * 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38
* [USDC](https://testnet.sonicscan.org/address/0x391071Fe567d609E4af9d32de726d4C33679C7e2)
  * 0x0BA304580ee7c9a980CF72e55f5Ed2E9fd30Bc51

**Contracts:**

* [Multicall3](https://testnet.sonicscan.org/address/0xcA11bde05977b3631167028862bE2a173976CA11)
  * 0xcA11bde05977b3631167028862bE2a173976CA11
    {% endtab %}
    {% endtabs %}


# Network Parameters

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

```bash
curl -sX POST -H "Content-type: application/json" -d '{"id":1,"jsonrpc":"2.0","method":"eth_getRules","params": ["latest"]}' https://rpc.soniclabs.com | jq
```

```json
{
  "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
    }
  }
}
```


# 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:**
  * `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 [SonicScan](https://sonicscan.org/address/0xFC00FACE00000000000000000000000000000000#code:~:text=Contract-,ABI,-API) for the full SFC ABI.


# 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

```javascript
// 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"
};
```

### Setup

```javascript
// 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);
```

### Bridge Operations

#### 1. Ethereum to Sonic Transfer

```javascript
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
    };
}
```

#### 2. Claim Tokens on Sonic

```javascript
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;
}
```

#### 3. Sonic to Ethereum Transfer

```javascript
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
    };
}
```

#### 4. Claim Tokens on Ethereum

```javascript
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;
}
```

### Complete Example

```javascript
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;
    }
}
```

### Required ABIs

```javascript
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)"
];
```

### 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
   * Use the same private key for both networks
5. **Monitoring**
   * Monitor transaction status on both networks
   * Keep transaction hashes for reference
   * Verify successful claims before proceeding
   * Monitor StateOracle updates for claim timing


# 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**. 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

<details>

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

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.

</details>

<details>

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

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

</details>

<details>

<summary>What's the difference between the block base fee and the fee returned by eth_feeHistory?</summary>

* Block base fee: Usually at its current minimum of 50 GWei (0xba43b7400 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"

</details>

<details>

<summary>Why are my transactions being rejected as "underpriced"?</summary>

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

</details>

<details>

<summary>How should I calculate gas fees for Sonic transactions?</summary>

For legacy (Type 0) 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

</details>

<details>

<summary>Why doesn't the base fee change dynamically on Sonic?</summary>

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

</details>

<details>

<summary>Why does gasUsedRatio show 99% if the network isn't congested?</summary>

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

</details>

<details>

<summary>What's the recommended approach for gas pricing on Sonic?</summary>

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

</details>

<details>

<summary>Why does Sonic add a 10% buffer to gas price suggestions?</summary>

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

</details>

## **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


# 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](https://www.hackquest.io/learning-track/Sonic).

<figure><img src="/files/qS4d3uN1kdnx8Rwd4G08" alt=""><figcaption></figcaption></figure>

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

{% stepper %}
{% step %}

### Phase 1

Web3 Basics.
{% endstep %}

{% step %}

### Phase 2

Ecosystem Overview
{% endstep %}

{% step %}

### Phase 3

Basic Solidity Syntax
{% endstep %}

{% step %}

### Phase 4

Advanced Solidity Syntax
{% endstep %}

{% step %}

### Phase 5

Build With Guided Projects
{% endstep %}

{% step %}

### Phase 6

Practical Frameworks — Foundry
{% endstep %}

{% step %}

### Phase 7

Smart Contract Security
{% endstep %}

{% step %}

### Phase 8

Explore More Resources on Sonic
{% endstep %}
{% endstepper %}


# Safe

[Safe](https://app.safe.global/new-safe/create?chain=sonic) is a smart contract wallet deployed on Sonic. It is designed for multi-signature management of crypto assets and interactions with other smart contracts. You can [access Safe on Sonic natively](https://app.safe.global/new-safe/create?chain=sonic).

You can designate the Safe's owners and specify the minimum number of approvals required for a transaction to be executed. This differs from a single-key wallet, also known as an externally owned account (EOA), where one person holds the private key and approves transactions independently, which is the approach used by most Web3 wallets, such as Rabby and MetaMask.

## Getting Started With Safe

Please see the [Safe documentation](https://docs.safe.global/home/what-is-safe) to learn how to use Safe.


# 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.

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Archive Node</strong></td><td>Stores the entire history of the chain since the genesis block but does not validate transactions or create new blocks.</td><td></td><td><a href="/pages/OzK2kBoRIPFRcOnrM9SQ">/pages/OzK2kBoRIPFRcOnrM9SQ</a></td></tr><tr><td><strong>Validator Node</strong><br>Validates transactions and creates new blocks to securely power and maintain the integrity of the network.</td><td></td><td></td><td><a href="/pages/ycklmVREhe4bDmkq6Vvn">/pages/ycklmVREhe4bDmkq6Vvn</a></td></tr></tbody></table>


# 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.

{% hint style="info" %}
The system firewall must allow TCP and UDP connections from/to port 5050.
{% endhint %}

Building the Sonic binary requires the essential software compilation tools and the Go language version [1.25 or newer](https://go.dev/dl/) 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.

```
git clone https://github.com/0xsoniclabs/sonic.git
```

Switch to the most recent [Sonic release](https://github.com/0xsoniclabs/sonic/releases).

```
git fetch --tags && git checkout -b v2.1.6 tags/v2.1.6
```

Build the Sonic binary using the provided configuration.

```
make all
```

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

```
sudo cp build/sonic* /usr/local/bin/
```

## 2. Prime Sonic State DB

Download the most recent network archive genesis file for the [**Sonic mainnet or testnet**](https://genesis.soniclabs.com)**.**

```bash
curl -JLO https://genesis.soniclabs.com/latest-sonic-archive.g
```

The genesis file will be used to prime your local state database and will allow you to join the network and synchronize with it.

### 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.

```bash
GOMEMLIMIT=50GiB sonictool --datadir <datadir> --cache 12000 genesis latest-sonic-archive.g
```

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. Please note that **the state root hash** will be different and **should correspond with the expected state** provided for the latest genesis file on the [download page](https://genesis.soniclabs.com/).

{% tabs %}
{% tab title="Sonic Mainnet" %}

```
StateDB imported successfully, stateRoot matches module=gossip-store index=1 root="1ccba39...9ea2be"
```

{% endtab %}

{% tab title="Sonic Testnet" %}

```
StateDB imported successfully, stateRoot matches module=gossip-store index=1 root="9601e5...c3d639"
```

{% endtab %}
{% endtabs %}

## 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.

```
--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
```

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.

```
--ws --ws.addr=0.0.0.0 --ws.port=18546 --ws.origins=*
--ws.api=eth,web3,net,ftm,txpool,abft,dag,trace,debug
```

{% hint style="info" %}
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.
{% endhint %}

Now, start your node with the sonicd application.

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


# Validator Node

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

Unlike [archive nodes](/sonic/node-deployment/archive-node), 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

1. [Launch a Server Instance](#id-1.-launch-a-server-instance)
2. [Install Required Development Tools](#id-2.-install-required-development-tools)
3. [Build the Sonic Node Software](#id-3.-build-the-sonic-node-software)
4. [Prime the Sonic Database](#id-4.-prime-the-sonic-database)
5. [Synchronize With the Network](#id-5.-synchronize-with-the-network)
6. [Create a Validator Wallet](#id-6.-create-a-validator-wallet)
7. [Create a Validator Signing Key](#id-7.-create-a-validator-signing-key)
8. [Register Your Validator](#id-8.-register-your-validator)
9. [Run Your Validator Node](#id-9.-run-your-validator-node)
10. [Validator Name and Logo](#id-10.-validator-name-and-logo)
11. [Next Steps](#id-10.-next-steps)

{% tabs %}
{% tab title="Validator Parameters" %}

* Minimum self-stake amount: 500,000 S
* Maximum validator size: 16x self-stake
* Rewards: \~3.5% APR target (at 50% network staking rate), plus 15% of delegators' rewards and network fees

{% hint style="info" %}
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.
{% endhint %}
{% endtab %}

{% tab title="Network Resources" %}

* Mainnet RPC: [https://rpc.soniclabs.com](https://rpc.soniclabs.com/)
* Testnet RPC: [https://rpc.testnet.soniclabs.com](https://rpc.testnet.soniclabs.com/)
* WebSocket Endpoint: wss\://rpc.soniclabs.com
* Mainnet Explorer: [https://sonicscan.org](https://sonicscan.org/)
* Testnet Explorer: [https://testnet.sonicscan.org](https://sonicscan.org/)
* SFC Contract Address: [0xFC00FACE00000000000000000000000000000000](https://sonicscan.org/address/0xFC00FACE00000000000000000000000000000000)
* STI Contract (Validators' Information): [0xFf4cD89f549432c312c497628748d4d76AC180f6](https://sonicscan.org/address/0xFf4cD89f549432c312c497628748d4d76AC180f6)
* Genesis Files: [https://genesis.soniclabs.com](https://genesis.soniclabs.com/)
  {% endtab %}
  {% endtabs %}

## 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.25 or newer](https://go.dev/dl/), to build the Sonic client and its bundled tools. Example (Ubuntu/Debian):

```bash
sudo apt-get update
sudo apt-get install -y build-essential git
```

Install Go language compiler (Ubuntu/Debian):

```bash
sudo rm -rf /usr/local/go
wget https://go.dev/dl/go1.26.2.linux-amd64.tar.gz
sudo tar -xzf go1.26.2.linux-amd64.tar.gz -C /usr/local/
rm -f go1.26.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
```

## 3. Build the Sonic Node Software

Check the [latest Sonic release](https://github.com/0xsoniclabs/sonic/releases) and adjust commands if necessary:

```bash
git clone https://github.com/0xsoniclabs/Sonic.git
cd Sonic
git fetch --tags && git checkout -b v2.1.6 tags/v2.1.6
make all
```

You can confirm the Sonic release by running:

```bash
build/sonicd version
```

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

```bash
sudo mv build/sonic* /usr/local/bin/
```

## 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](https://genesis.soniclabs.com). For the mainnet, for example:

```bash
curl -JLO https://genesis.soniclabs.com/latest-sonic-pruned.g
```

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`.

```bash
GOMEMLIMIT=54GiB sonictool --datadir ~/.sonic \
    --cache 12000 genesis \
    --mode validator latest-sonic-pruned.g
```

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.

```bash
GOMEMLIMIT=54GiB sonicd --datadir ~/.sonic --cache 12000 --mode validator
```

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).&#x20;

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

```bash
sonictool --datadir ~/.sonic account new
```

Important: Keep your wallet and keys secure. Never share them.&#x20;

## 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:

```bash
sonictool --datadir ~/.sonic validator new
```

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

<figure><img src="/files/kqYLNx2hpfEMkvlUuX5O" alt=""><figcaption></figcaption></figure>

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](https://sonicscan.org/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](https://sonicscan.org) 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.

<figure><img src="/files/z21tEEiO6IJWUgo1FqQX" alt=""><figcaption></figcaption></figure>

## 9. Run Your Validator Node

Stop the currently running node:

```bash
pkill sonicd
```

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:

```bash
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>
```

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):

```json
{
  "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"
}
```

Host it somewhere so it is publicly accessible, such as in [this example](https://repository.sonic.soniclabs.com/validator/soniclabs.json). 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](https://sonicscan.org/) and open the [STI contract](https://sonicscan.org/address/0xFf4cD89f549432c312c497628748d4d76AC180f6#writeContract).
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.

<figure><img src="/files/AMVDikkGSdhTZXtnuPHy" alt=""><figcaption></figcaption></figure>

## 11. Next Steps

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden></th></tr></thead><tbody><tr><td><strong>Validator/Name Logo</strong></td><td><p>You can set a validator name and logo on the explorer. Check <a href="https://github.com/block42-blockchain-company/fantom-staker-info">official repositories</a> for instructions.</p><p></p><p>The STI contract on Sonic: <a href="https://sonicscan.org/address/0xFf4cD89f549432c312c497628748d4d76AC180f6">0xFf4cD89f549432c312c497628748d4d76AC180f6</a></p></td><td></td></tr><tr><td><strong>Community and Help</strong></td><td>Join <a href="https://linktr.ee/soniclabs">Sonic community channels</a>, follow updates, and use your stake to participate in network governance. If you have issues, the community can provide guidance.</td><td></td></tr><tr><td><strong>Monitoring and Health</strong></td><td>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.</td><td></td></tr></tbody></table>

Congratulations! You are now running a Sonic validator node.


# 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.

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:&#x20;

```log
failed to initialize the node: failed to make consensus engine: 
failed to open existing databases: dirty state: gossip-21614: DE
```

{% hint style="info" %}
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**.
{% endhint %}

## 2. Understanding Why the Node Failed

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

* [Misconfiguration of the Node Software](#how-to-fix-node-misconfiguration)

  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](#how-to-fix-resource-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.
* [Hardware Failure](#how-to-fix-hardware-failures)

  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.

  ```bash
  tee -a /etc/security/limits.conf > /dev/null <<EOT
  @sonic           soft    nofile          950000
  @sonic           hard    nofile          950000
  EOT
  ```
* 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.

  ```
  [Service]
  Type=simple
  User=sonic
  Group=sonic
  Environment="GOMEMLIMIT=28GiB"
  ExecStart=/usr/bin/sonicd --datadir=/var/lib/sonic --cache=16000
  LimitNOFILE=934073
  TimeoutSec=300
  ```

### 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.&#x20;
* **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 [HAproxy](https://www.haproxy.org), or [Nginx](https://nginx.org/en/community.html), 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.&#x20;

### 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](https://en.wikipedia.org/wiki/Standard_RAID_levels) 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 [HAproxy](https://www.haproxy.org).

{% hint style="danger" %}
**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.
{% endhint %}

* **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](#id-2.-why-the-node-failed) 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](https://docs.soniclabs.com/sonic/node-deployment/pages/ycklmVREhe4bDmkq6Vvn#id-4.-prime-the-sonic-database) the latest snapshot. You should consider [upgrading your node](https://docs.soniclabs.com/sonic/node-deployment/pages/ycklmVREhe4bDmkq6Vvn#id-3.-build-the-sonic-node-software) to the [latest available version](https://github.com/0xsoniclabs/sonic/releases) 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](#id-2.-why-the-node-failed) for the crash.
2. Make sure you have [the latest available Sonic](https://github.com/0xsoniclabs/sonic/releases) node version. If your local version is outdated, [build the latest](/sonic/node-deployment/archive-node#build-sonic-client) Sonic node software. Use the `version` command to check your node version:

   ```bash
   $ sonicd version
   Sonic
   Version: 2.1.6
   Git Commit: 26dd110c076a7efcde5bc177ffe8726f9287c0a3
   ...
   ```
3. Try to recover the state from your archive database.

   ```bash
   GOMEMLIMIT=28GiB sonictool --datadir <path> --cache 12000 heal
   ```

   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[ archive node database priming guide](/sonic/node-deployment/archive-node#prime-sonic-database) for the details of the process.


# Upgrade Instructions (2.1.6)

This guide describes the steps for upgrading a Sonic mainnet node to the latest 2.1.6 version, which includes the Ethereum Prague feature set, gas subsidies, event throttling for validators, and security patches (CVE-2026-26314, CVE-2026-26315)

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.

**Important:** After installing v2.1.6, we recommend recreating your p2p node key by removing `<datadir>/p2p/nodekey` before restarting. This will change your p2p node ID, which may break static peering setups.

The guide covers the following steps:

1. [Build Sonic Client and Tooling](#id-1.-build-sonic-client-and-tooling)
2. [Prime Sonic State DB From Genesis File (Optional)](#id-2.-prime-sonic-state-db-from-genesis-file-optional)
3. [Restart Sonic Node With New Version and Synchronize](#id-3.-restart-sonic-node-with-new-version-and-synchronize)

{% hint style="info" %}
Reach out to [Seg on Telegram](https://t.me/segfault0x) for support.
{% endhint %}

## Upgrade Steps Overview

1. Update your operating system.
2. Verify the version and upgrade the [Golang](https://go.dev/dl/) version to v1.25 or newer as needed.
3. Obtain the latest [Sonic release](https://github.com/0xsoniclabs/sonic/releases) 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 [*in maintenance*](https://xapi.sonic.soniclabs.com/html/validators/down) 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](https://go.dev/dl/) language version 1.24 or newer to be available. Please refer to your Linux distribution manuals to obtain the development tools on your system.

{% hint style="danger" %}
**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.**
{% endhint %}

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.6 tags/v2.1.6`
3. (Optional) Verify your source code consistency.\
   `git status && git log -n1`   &#x20;

   *On branch v2.1.6*\
   *nothing to commit, working tree clean*

   *commit* 26dd110c076a7efcde5bc177ffe8726f9287c0a3 *(HEAD -> v2.1.6, tag: v2.1.6)*
4. Build the Sonic binary using the provided configuration.\
   `make all`
5. Check the Sonic binary version (the most recent version is v2.1.6).\
   `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/`

{% hint style="info" %}
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 -- .`&#x20;
{% endhint %}

## 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.1.5 is fully compatible with the new Sonic client version v2.1.6. If your node has been running one of the versions v2.0.1 to v2.1.5, 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.&#x20;

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-archive.g>
* <https://genesis.soniclabs.com/latest-sonic-pruned.g>

1. Download the genesis file.\
   `curl -JLO https://genesis.soniclabs.com/sonic-mainnet/genesis/sonic-74120-archive.g`
2. (Optional) Download the genesis checksum file.\
   `curl -JLO https://genesis.soniclabs.com/sonic-mainnet/genesis/sonic-74120-archive.g.md5`&#x20;
3. (Optional) Validate the genesis file consistency.\
   `md5sum --check sonic-74120-archive.g.md`\
   `Expected output is: sonic-74120-archive.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 <genesis path>`
* Start the genesis expansion for validator mode.\
  `GOMEMLIMIT=50GiB sonictool --datadir --cache 12000 genesis --mode validator <genesis path>`

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. The expected state root hash for each genesis file is provided on the [download page](https://genesis.soniclabs.com/).&#x20;

`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`&#x20;

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.

{% hint style="info" %}
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.
{% endhint %}

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

{% hint style="warning" %}
This step is [extremely important for validators](https://xapi.sonic.soniclabs.com/html/validators/down). 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.
{% endhint %}

**2. Start New Node**

Use the node database path (`<datadir>`) from the previous installation or the new expansion created in [the previous step](#id-2.-prime-sonic-state-db-from-genesis-file-optional).

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.

{% hint style="info" %}
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.
{% endhint %}

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

<br>


# FAQ

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

## S Token

<details>

<summary>Where can I buy or sell S?</summary>

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

</details>

<details>

<summary>Will the S token have any inflation?</summary>

The S token will not experience inflation during the first six months after Sonic's launch. Following that period, [the network will mint S tokens](https://docs.soniclabs.com/sonic/s-token#tokenomics) 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.

</details>

<details>

<summary>Is there an S airdrop?</summary>

Yes. We're planning an [airdrop of 190,500,000 S](https://docs.soniclabs.com/funding/sonic-airdrop) to incentivize Sonic users.

</details>

## Sonic Chain

<details>

<summary>Is Sonic EVM compatible?</summary>

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.

</details>

<details>

<summary>Can apps on Sonic be coded with Solidity and Vyper?</summary>

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

</details>

<details>

<summary>How many transactions per second (TPS) can Sonic handle?</summary>

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

</details>

<details>

<summary>Is there a Sonic testnet?</summary>

Yes. You can immediately access [the Sonic testnet](https://testnet.soniclabs.com/) to deploy your apps and experience the speed of Sonic.

</details>

<details>

<summary>Is there an incentive program for developers to build on Sonic?</summary>

Yes. Sonic Labs is running a massive incentive program, which includes the [Fee Monetization](/funding/fee-monetization) program that rewards developers with up to 90% of the fees their apps generate, and the [Innovator Fund](https://docs.soniclabs.com/funding/innovator-fund) that offers up to 200,000,000 S to expedite the immediate adoption of apps to Sonic and support new ventures.

</details>

<details>

<summary>What are the tooling/infrastructure apps available on Sonic?</summary>

Check out all the tooling and infrastructure in our [app explorer](https://my.soniclabs.com/apps) on MySonic.

</details>

<details>

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

[Get started here](/sonic/build-on-sonic).

</details>


# Sonic Airdrop

{% hint style="info" %}
Claims for season one remain open. [Learn more](/funding/sonic-airdrop/claim-season-1).
{% endhint %}

{% hint style="warning" %}
Season 2 and the Kaito campaign have concluded. Future incentives will be distributed through targeted airdrop incentive programs.
{% endhint %}

The S airdrop minted 190,500,000 S tokens to incentivize users of Sonic. These tokens were allocated through Sonic Points, Sonic Gems, and Game Gems.

## Program Status

| Program                | Allocation         | Status                                                                                 |
| ---------------------- | ------------------ | -------------------------------------------------------------------------------------- |
| Season 1               | \~89,500,000 S     | Complete                                                                               |
| Season 2               | \~6,000,000 S      | Complete                                                                               |
| Kaito Campaign         | \~2,800,000 S      | Complete                                                                               |
| **Remaining Treasury** | \~**92,200,000 S** | [*Reserved*](https://sonicscan.org/address/0x2889604E75637D3AfE919201C27ac9d1221E6210) |

The S airdrop was distributed across two seasons. Season 1 ended on June 18, 2025, and Season 2 ran immediately after until November 1, 2025. The Kaito campaign ran concurrently with Season 2.

* Visit the [points dashboard](https://my.soniclabs.com/points) to track your points.

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Sonic Points</strong></td><td>User-focused airdrop points, earned by deploying assets as liquidity across apps on Sonic.</td><td></td><td><a href="/pages/XDSSsEBqwfoWqSLkcMqt">/pages/XDSSsEBqwfoWqSLkcMqt</a></td></tr><tr><td><strong>Sonic Gems</strong></td><td>DeFi-focused airdrop points, earned by apps driving user engagement on Sonic.</td><td></td><td><a href="/pages/IdCHVPoSWSMEH34SmbHG">/pages/IdCHVPoSWSMEH34SmbHG</a></td></tr><tr><td><strong>Game Gems</strong></td><td>Game-focused airdrop points, earned by games driving player engagement and retention.</td><td></td><td><a href="/pages/oajhSMJdg78mH2JBBAh0">/pages/oajhSMJdg78mH2JBBAh0</a></td></tr></tbody></table>

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

* [Sonic Points (Season 1)](/funding/sonic-airdrop/sonic-points-season-1)
* [Sonic Gems (Season 1)](/funding/sonic-airdrop/sonic-gems-season-1)

{% hint style="info" %}
The airdrop has also rewarded historical activity on Opera, participation on Sonic Arcade, and minters of the exclusive Shard NFT.
{% endhint %}

## What's Next

The Sonic ecosystem is transitioning from broad airdrop distribution to targeted airdrop incentives. The remaining \~92,200,000 S in treasury is reserved for:

* Sustainable Usage - Rewarding deel liquidity providers and consistent network participants
* Builder Economy - Supporting developers creating applications on Sonic
* Strategic Reserve - Funding future targeted airdrop incentives and ecosystem initiatives

**No additional tokens will be minted for these incentive programs.**

## 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 [Airdrop Order Book](https://airdrop.paintswap.io/) 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.

<figure><img src="/files/74kuAgbJOqqGjLalbRXa" alt=""><figcaption><p>Burn amount of the vested airdrop allocation if claimed early</p></figcaption></figure>

{% hint style="info" %}
The above vesting structure applied to Season 1. Future targeted airdrop incentives may utilize different distribution models based on program objectives.
{% endhint %}

### Burn Amount and Examples

| Day     | Burn Amount |
| ------- | ----------- |
| 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% |
| 180–210 | 33.4%–22.3% |
| 211–240 | 22.3%–11.2% |
| 241–270 | 11.2%–0%    |

{% tabs %}
{% tab title="Example A" %}
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).
{% endtab %}

{% tab title="Example B" %}
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).
{% endtab %}
{% endtabs %}

## Data Collection

We are working with[ OpenBlock](https://openblock.com/) and [Sentio](https://www.sentio.xyz/) 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.


# Claim (Season 1)

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

[**Sonic Points**](/funding/sonic-airdrop/sonic-points-season-1)\
Earned directly by users holding and using whitelisted assets across apps on Sonic.

[**Sonic Gems**](/funding/sonic-airdrop/sonic-gems-season-1)\
Earned by apps that drove user activity, based on their performance across key metrics.

## Sonic Points

{% hint style="success" %}
[Claim now](https://airdrop.paintswap.io/)
{% endhint %}

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

You can trade this NFT on the official [Airdrop Order Book](https://airdrop.paintswap.io/orderbook/advanced?quote=S) 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](https://my.soniclabs.com/points/vesting) 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.

{% hint style="info" %}
Gems are distributed entirely by developers, not by Sonic Labs.
{% endhint %}


# Sonic Points

This page is specific to season 2 of the airdrop.

{% hint style="warning" %}
The second season of the airdrop and Kaito program are ended on November 1, 2025. Future incentive programs will be announced at a later stage.
{% endhint %}

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](/funding/sonic-airdrop#distribution), ensuring long-term sustainability and preventing sudden supply shifts.

— [How To Earn Points](#how-to-earn-points)\
&#x20;   — [User Points](#id-1.-points-deploy-assets-on-apps)\
&#x20;   — [App Gems](#id-2.-app-gems-earn-further-allocation)\
— [Loyalty Multiplier](#loyalty-multiplier)\
— [Whitelisted Assets](#whitelisted-assets)\
— [Airdrop Points Dashboard](#airdrop-points-dashboard)\
— [Terms and Conditions](#terms-and-conditions)

## How To Earn Points

### **1. User Points — Deploy Assets on Apps**

By deploying [whitelisted assets](#whitelisted-assets) as liquidity on participating apps, users will earn points. A list of [participating apps](https://my.soniclabs.com/apps?pointsOnly=true) 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 [Sonic Gems](/funding/sonic-airdrop/sonic-gems). 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 |
| --------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| 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         |

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

| Token Type                | Multiplier |
| ------------------------- | ---------- |
| Sonic Tokens              | 12x        |
| Ecosystem Tokens          | 10x        |
| Yield Bearing Stablecoins | 10x        |
| Pegged Stablecoins        | 8x         |
| ETH/BTC                   | 4x         |
| Yield Bearing ETH/BTC     | 4x         |

<p align="right"><em>Sonic reserves the right to determine the appropriate category for any app.</em></p>

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.

{% hint style="info" %}
[Learn more about scUSD/scETH by Rings](https://blog.soniclabs.com/rings-protocol-explained-scusd-and-sceth/). Sonic Labs makes no guarantee to the safety or peg of third-party assets, such as Rings. Use them at your own risk.
{% endhint %}

## Airdrop Points Dashboard

The [Sonic points dashboard](https://my.soniclabs.com/points) 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
* View a leaderboard that displays the points and Gems earned by users and apps

***

## Terms and Conditions

View the [terms and conditions](https://soniclabs.notion.site/Sonic-Points-Terms-and-Conditions-17b178962bd28044af98c8b70898bf87) for the Sonic points program.


# Sonic Points (Season 1)

Archived page for season 1 of the airdrop.

{% hint style="info" %}
[Season 2 has begun](/funding/sonic-airdrop/sonic-points).
{% endhint %}

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, hold and use whitelisted assets across various DeFi apps. These points will be distributed over multiple seasons as [NFT positions](/funding/sonic-airdrop#distribution), ensuring long-term sustainability and preventing sudden supply shifts. The first season began with Sonic's launch and will conclude in June 2025.

— [How To Earn Points](#how-to-earn-points)\
&#x20;   — [Passive Points](#id-1.-passive-points-hold-assets)\
&#x20;   — [Activity Points](#id-2.-activity-points-deploy-assets-on-apps)\
&#x20;   — [App Points (Gems)<br>](#id-3.-app-points-gems-earn-further-allocation)— [Whitelisted Assets](#whitelisted-assets)\
— [Airdrop Points Dashboard](#airdrop-points-dashboard)\
— [Sonic Arcade Points](#sonic-arcade-points)\
— [Terms and Conditions](#terms-and-conditions)

## How To Earn Points

### **1. Passive Points — Hold Assets**

Users can earn passive points by holding [whitelisted assets](#whitelisted-assets) directly in their Web3 wallets, such as Rabby or MetaMask, including hardware wallets. Assets held on centralized exchanges are not eligible.

Please note that WETH, USDT, WBTC, scUSD, scETH, scBTC, aUSDC, and bUSDC.e-20 earn activity points only, not passive points.

<figure><img src="/files/S0dhGQW61g7LupKwhtlZ" alt=""><figcaption></figcaption></figure>

### **2. Activity Points — Deploy Assets on Apps**

By deploying [whitelisted assets](#whitelisted-assets) as liquidity on participating apps, users will earn activity points, which provide 2x the amount of points compared to simply holding assets passively. A list of [participating apps](https://my.soniclabs.com/apps?pointsOnly=true) is available on the points dashboard.

Please note that when a user provides liquidity (LPs), both tokens in the LP must be whitelisted in order to earn points. If neither or only one of the tokens is whitelisted, the user will not earn points.

<figure><img src="/files/1x5oLNWsRnmwHLUY6LGp" alt=""><figcaption></figcaption></figure>

### **3. App Points (Gems) — Earn Further Allocation**

The S airdrop includes a developer-focused portion, where apps compete for an airdrop allocation known as [Sonic Gems](/funding/sonic-airdrop/sonic-gems). 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 passive and activity points regardless. 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.

<figure><img src="/files/WpNV3YlPzNsOAoSqtkAC" alt=""><figcaption></figcaption></figure>

## Whitelisted Assets

To qualify for the S airdrop, you must hold or use the whitelisted assets listed in the table below. The multipliers are applied to the passive or activity points you earn.

| Asset                                                                                       | Multiplier   |
| ------------------------------------------------------------------------------------------- | ------------ |
| USDC.e, scUSD, stkscUSD, wstkscUSD, aUSDC,  bUSDC.e-20                                      | 6x (Boosted) |
| s, wS, stS, OS, wOS, anS, wanS, beS, scETH, stkscETH, wstkscETH, scBTC, stkscBTC, wstkscBTC | 4x (Boosted) |
| WETH, USDT, WBTC, x33, SHADOW, BEETS, SWPX, METRO                                           | 2x (Boosted) |

Please note that WETH, USDT, WBTC, scUSD, scETH, scBTC, aUSDC, and bUSDC.e-20 earn activity points only, not passive points.

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 [stS by Beets](https://beets.fi/stake), a liquid staking token.

{% hint style="info" %}
[Learn more about scUSD/scETH by Rings](https://blog.soniclabs.com/rings-protocol-explained-scusd-and-sceth/). Sonic Labs makes no guarantee to the safety or peg of third-party assets, such as Rings. Use them at your own risk.
{% endhint %}

## Airdrop Points Dashboard

The [Sonic points dashboard](https://my.soniclabs.com/points) 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
* View a leaderboard that displays the points and Gems earned by users and apps

## Sonic Arcade Points

The Sonic Arcade was a digital playground on the Sonic testnet that featured three play-to-earn games — Plinko, Mines, and Wheel — each offering airdrop points.

Arcade players will receive their points at the end of the S airdrop's first season.

***

## Terms and Conditions

View the [terms and conditions](https://soniclabs.notion.site/Sonic-Points-Terms-and-Conditions-17b178962bd28044af98c8b70898bf87) for the Sonic points program.


# Sonic Gems

This page is specific to season 2 of the airdrop.

{% hint style="warning" %}
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.
{% endhint %}

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.&#x20;

— [What are Sonic Gems?](#what-are-sonic-gems)\
‎‎‎‏— [Distribution of Gems](#distribution-of-gems)\
— [Gems Revocation Policy](#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 [points dashboard](https://my.soniclabs.com/points).

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 [Sonic Builders](https://t.me/SonicBuilders) 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 <a href="#distribution-of-gems" id="distribution-of-gems"></a>

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.&#x20;

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.

{% tabs %}
{% tab title="Category" %}
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 |
| -------------------------- | ------ |
| Yield Tokenization         | 4      |
| Isolated / Modular Lending | 4      |
| Spot / CLOB DEX            | 3      |
| Pooled Lending / CDPs      | 3      |
| Perps                      | 3      |
| Options / Derivatives      | 2      |
| Yield Aggregators          | 2      |
| GambleFi                   | 2      |
| Bridges                    | 2      |
| {% endtab %}               |        |

{% tab title="Sonic Native" %}
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.
{% endtab %}

{% tab title="Incentive" %}
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.

$$
\text{Incentive Weight} = \frac{\text{S Distributed to Users}}{\text{S Claimed}}
$$

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.
{% endtab %}

{% tab title="Point Score" %}
Point score is determined by calculating the total amount of [Sonic Points](/funding/sonic-airdrop/sonic-points) that an app has generated for its users. This score is then divided by the total points generated across all eligible apps.

$$
\text{Point Score} = \frac{\text{Sonic Points Generated By App}}{\text{Total Sonic Points Generated}}
$$
{% endtab %}

{% tab title="Revenue Score" %}
Revenue score rewards apps that drive real, sustainable usage.

$$
\text{Revenue Score} = \text{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.
{% endtab %}
{% endtabs %}

### Final Gems Calculation <a href="#final-gems-calculation" id="final-gems-calculation"></a>

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

<details>

<summary>Step A — Gem Score</summary>

$$\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}}$$

</details>

<details>

<summary><strong>Step B — Point Score</strong></summary>

$$\text{App Point Score} = \text{Points Generated by App for Users}$$

</details>

<details>

<summary><strong>Step C — Revenue Score</strong></summary>

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

</details>

<details>

<summary><strong>Step D — Final Score</strong></summary>

$$\text{App Final Score} = (A \cdot B)^{\alpha} \cdot C^{\beta}$$

</details>

<details>

<summary><strong>Step E — Share of Gems</strong></summary>

$$\text{Share of Gems} = \frac{\text{App Final Score}}{\text{Total Final Score}} \times \text{Total Season 2 Gems}$$

</details>

{% hint style="info" %}
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*.
{% endhint %}

## Gems Revocation Policy <a href="#gems-revocation-policy" id="gems-revocation-policy"></a>

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.
4. **Failure to Integrate OpenBlock**\
   Failing to integrate with OpenBlock or adhere to its guidelines.
5. **Tokenization**\
   Tokenizing Gems in any way.

{% hint style="warning" %}
Users are encouraged to report any suspicious activity or malpractice to Sonic Labs.
{% endhint %}

<br>


# Sonic Gems (Season 1)

Archived page for season 1 of the airdrop.

{% hint style="info" %}
[Season 2 has begun](/funding/sonic-airdrop/sonic-points).
{% endhint %}

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. Gems are distributed across multiple seasons, ensuring a dynamic and sustainable reward structure. The first season is set to end around June 2025.

— [What are Sonic Gems?](#what-are-sonic-gems)\
‎‎‎‏‏‎‎— [Gems Season 1](#gems-season-1)\
— [Distribution of Gems](#distribution-of-gems)\
— [Gems Revocation Policy](#gems-revocation-policy)\
— [Example Distribution of Gems](https://blog.soniclabs.com/sonic-points-and-gems-explained-200-million-s-airdrop/#example-distribution-of-gems)

## 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 [points dashboard](https://my.soniclabs.com/points).

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

* Mint a new token representing its share of Gems.
* Maintain an internal record of user balances.
* Use the third-party [Merkl program](https://blog.merkl.xyz/merkl-shards-program-sonic-gems-airdrop)
* Join [Sonic Builders](https://t.me/SonicBuilders) 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.

## Gems Season 1 <a href="#gems-season-1" id="gems-season-1"></a>

A total of 1,680,000 Gems will be distributed during season 1. Out of this, 262,500 Gems are pre-allocated to [Sonic Boom](https://docs.soniclabs.com/funding/airdrop/sonic-boom?ref=blog.soniclabs.com) winners. The chart below shows the number of Gems allocated to each tier in Sonic Boom.

| Category | Gems Per Winner |
| -------- | --------------- |
| Emerald  | 13,125          |
| Sapphire | 8,750           |
| Ruby     | 4,375           |

The remaining 1,417,500 Gems will be available for any app to earn throughout the season — whether they’re Sonic Boom winners or not. At the end of season 1, all eligible apps will be able to claim S tokens based on the number of Gems they have earned.

## Distribution of Gems <a href="#distribution-of-gems" id="distribution-of-gems"></a>

Sonic Gems are distributed by considering factors such as category type, Sonic exclusivity, and effective reward distribution, promoting fairness and incentivizing active participation.&#x20;

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.

{% tabs %}
{% tab title="Category" %}
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 |
| -------------------------------- | ------ |
| Bridges                          | 5      |
| CLOB DEX                         | 4      |
| Lending Markets / CDPs           | 4      |
| Fixed Yield / Yield Tokenization | 4      |
| Spot DEX                         | 4      |
| GambleFi                         | 3      |
| Perps                            | 3      |
| Derivatives                      | 3      |
| Yield                            | 2      |
| Gaming                           | 2      |
| Tooling, Misc, and Payment       | 1      |
| {% endtab %}                     |        |

{% tab title="Sonic Native" %}
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.
{% endtab %}

{% tab title="Point Score" %}
Point score is determined by calculating the total amount of [Sonic Points](/funding/sonic-airdrop/sonic-points) that an app has generated for its users. This score is then divided by the total points generated across all eligible apps.

$$
\text{Point Score} = \frac{\text{Sonic Points Generated By App}}{\text{Total Sonic Points Generated}}
$$
{% endtab %}

{% tab title="Incentive" %}
{% hint style="warning" %}
Only applicable from season 2 onwards.
{% endhint %}

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.

$$
\text{Incentive Weight} = \frac{\text{S Distributed to Users}}{\text{S Claimed}}
$$

For example, if an app distributed 100% of its claimed S to its users, it’ll receive a weight of 1 in the next season, 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.
{% endtab %}
{% endtabs %}

### Final Gems Calculation <a href="#final-gems-calculation" id="final-gems-calculation"></a>

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

<details>

<summary>Step 1 — App Gem Score</summary>

$$\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}}$$

</details>

<details>

<summary><strong>Step 2 — App Point Score</strong></summary>

$$\text{App Point Score} = \text{Total activity points generated by app for its users}$$

</details>

<details>

<summary><strong>Step 3 — App Final Score</strong></summary>

$$\text{App Final Score} = \text{App Gem Score} \times \text{App Point Score}$$

</details>

<details>

<summary><strong>Step 4 — Share of Gems</strong></summary>

$$\text{Share of Sonic Gems} = \frac{\text{App Final Score}}{\text{Total Final Score}} \times \text{Total Gems}$$

</details>

{% hint style="info" %}
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*.
{% endhint %}

## Gems Revocation Policy <a href="#gems-revocation-policy" id="gems-revocation-policy"></a>

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.
4. **Failure to Integrate OpenBlock**\
   Failing to integrate with OpenBlock or adhere to its guidelines.

{% hint style="warning" %}
Users are encouraged to report any suspicious activity or malpractice to Sonic Labs.
{% endhint %}

<br>


# Game Gems

{% hint style="warning" %}
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.
{% endhint %}

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 [Sonic Gems](/funding/sonic-airdrop/sonic-gems), 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.

## Game Gems Calculation <a href="#game-gems-calculation" id="game-gems-calculation"></a>

### 1. Growth Score <a href="#id-1-growth-score" id="id-1-growth-score"></a>

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.

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

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

### 2. Activity Score <a href="#id-2-activity-score" id="id-2-activity-score"></a>

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.

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

### 3. Score and Final Allocation <a href="#id-3-score-and-final-allocation" id="id-3-score-and-final-allocation"></a>

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

$$\text{Score}(g) = \max\left(0,\ w\_g \times \text{Growth Score}(g) + w\_a \times \text{Activity Score}(g)\right)$$

$$\text{Final Allocation}(g) = \left( \text{Score}(g) \bigg/ \sum\limits\_{g'}^{G} \text{Score}(g') \right) \times \text{Total Tokens Allocated to Games}$$

{% hint style="info" %}
Game Gems are separate from [Sonic Gems](/funding/sonic-airdrop/sonic-gems) and come from a separate prize pool as part of the airdrop.
{% endhint %}


# Fee Monetization

{% hint style="success" %}
[Apply to Fee Monetization](/funding/fee-monetization/apply).
{% endhint %}

[Fee Monetization](https://feem.soniclabs.com/) (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

{% stepper %}
{% step %}

### Transaction Submitted

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

{% step %}

### Validator Allocation

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

{% step %}

### FeeM Allocation

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

{% step %}

### Off-Chain Oracle Tracking

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

{% step %}

### 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.
{% endstep %}
{% endstepper %}

<figure><img src="/files/Gcv6Y2HTVG3CFRBHzXCD" alt=""><figcaption></figcaption></figure>

## 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:
  * 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.

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.

<figure><img src="/files/2nrbvnDjGNIz37WvxjNH" alt=""><figcaption></figcaption></figure>

## Frequently Asked Questions

<details>

<summary><strong>My app uses an upgradeable (proxy) contract</strong>. Should I register the implementation too?</summary>

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

</details>

<details>

<summary><strong>What if my app deploys many user-specific contracts?</strong></summary>

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.

</details>

<details>

<summary><strong>How do I claim my rewards?</strong></summary>

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](https://feem.soniclabs.com/) for a user-friendly claim UX.

</details>

<details>

<summary><strong>What if I don’t claim my rewards immediately?</strong></summary>

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

</details>

<details>

<summary><strong>Why do my rewards stay the same over a longer time period?</strong></summary>

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.

</details>

{% hint style="info" %}
Questions? Join [Sonic Builders](https://t.me/SonicBuilders) on Telegram.
{% endhint %}


# Apply

All apps on Sonic are eligible to participate in Fee Monetization. To apply, visit the [FeeM dashboard](https://feem.soniclabs.com/) 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.

{% embed url="<https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFigzFE2ScpiZHSkLRCev%2Fuploads%2FVyZsQoMaxqjZw1ciBVzQ%2FxZYnzT4Pyz34QA8C.mp4?alt=media&token=726bd1d3-b124-4a00-ab59-4401c6382ed7>" %}

## Step 1 — App Registration

Visit the [Fee Monetization dashboard](https://feem.soniclabs.com/), connect your admin wallet, and click *Apply for FeeM*. The registration form will request several details from you.

* **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](/funding/fee-monetization/dispute).
* **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.

{% hint style="info" %}
The 25 S registration fee will be refunded once your app has been added to FeeM.
{% endhint %}

## 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](https://feem.soniclabs.com/), connect with your admin wallet, and claim your rewards. These will be sent to the recipient address you provided during the initial application step.

{% hint style="info" %}
For assistance, join [Sonic Builders](https://t.me/SonicBuilders) on Telegram.
{% endhint %}

***

## 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](https://feem.soniclabs.com/) to register.

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

```
{
  "name": "MySuperCoolProject",
  "image_url": "https://mysupercoolproject.com/icons/icon.png",
  "website": "https://mysupercoolproject.com/"
}
```

2. 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.
3. Go to the FeeM [ProjectsRegistrar](https://sonicscan.org/address/0x897d37f040Ec8DEFFD0ae1De743e1b1a14cf221f#writeProxyContract) 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.
4. 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.

```solidity
/// @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");
}
```

Your app and its contracts are now integrated into FeeM. Proceed to [Step 3 ](#step-3-claim-revenue)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](https://t.me/samharc) 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

<details>

<summary><strong>My app uses an upgradeable (proxy) contract</strong>. Should I register the implementation too?</summary>

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

</details>

<details>

<summary><strong>What if my app deploys many user-specific contracts?</strong></summary>

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.

</details>

<details>

<summary><strong>How do I claim my rewards?</strong></summary>

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](https://feem.soniclabs.com/) for a user-friendly claim UX.

</details>

<details>

<summary><strong>What if I don’t claim my rewards immediately?</strong></summary>

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

</details>

<details>

<summary><strong>Why do my rewards stay the same over a longer time period?</strong></summary>

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.

</details>


# 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](https://feem.soniclabs.com/) 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.

{% hint style="info" %}
To manually dispute a contract, use the [DisputeResolver](https://sonicscan.org/address/0x4A843aa35E1bcdE5279fE642D511A0C77DF725D6#code) 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.
{% endhint %}


# 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:

<table data-card-size="large" data-view="cards"><thead><tr><th></th></tr></thead><tbody><tr><td><strong>Liquidity Incentives</strong><br>Directing FeeM Vault revenue toward strategic pools to deepen liquidity and reduce borrowing costs.</td></tr><tr><td><strong>Protocol Integrations</strong><br>Funding integrations of core assets like USDC.e, WETH, and wS into apps.</td></tr></tbody></table>

{% hint style="info" %}
More information about the distribution of funds from the FeeM Vault will be available soon.
{% endhint %}

## 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.
5. **And the cycle continues.**


# Innovator Fund

{% hint style="info" %}
[Apply for funding from the Innovator Fund](https://www.soniclabs.com/bd-intake).
{% endhint %}

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.&#x20;

To do so, we’ll work closely with strategic angel investors such as [Michael](https://x.com/newmichwill?ref=blog.fantom.foundation) (Curve), [Stani](https://x.com/StaniKulechov?ref=blog.fantom.foundation) (Aave), [Robert](https://x.com/Rleshner?ref=blog.fantom.foundation) (Compound), [Tarun](https://x.com/tarunchitra?ref=blog.fantom.foundation) (Gauntlet), and [Sam](https://x.com/samkazemian?ref=blog.fantom.foundation) (FRAX), as well as our venture partners [Hashed](https://x.com/hashed_official?ref=blog.fantom.foundation), [Signum Capital](https://x.com/Signum_Capital?ref=blog.fantom.foundation), and [UOB Venture Management](https://www.uobvm.com.sg/en/index.page?ref=blog.fantom.foundation).&#x20;

<br>


# Overview

[Sonic](/sonic/overview) is an EVM blockchain featuring the native S token, which is used for transaction fees, staking, running validators, and participating in governance.

Sonic is migrating from the Fantom chain and its FTM token. Users holding FTM can now [upgrade to S](https://blog.soniclabs.com/the-ultimate-sonic-upgrade-handbook-ftm-to-s/).

{% tabs %}
{% tab title="Users" %}
**Users holding FTM:**\
If you're a user holding FTM wanting to upgrade to the S token, follow the instructions on the [Sonic Upgrade Handbook](https://blog.soniclabs.com/the-ultimate-sonic-upgrade-handbook-ftm-to-s/).\
\
**Users holding app tokens:**\
If you're a user holding an app token on Opera, follow the instructions on the[ App Token Migration page](/migration/app-token-migration).
{% endtab %}

{% tab title="Developers" %}
If you're an Opera app developer wanting to migrate to Sonic, follow the instructions on the [App Token Migration page](/migration/app-token-migration).
{% endtab %}

{% tab title="Validators" %}
If you run a validator node on Opera and you choose to migrate, please follow these steps:

* Un-delegate your stake first.
* Wait at least 2 epochs (≈15 minutes) before you shut down your node.
* Turn off the node and back up your validator key securely.
  {% endtab %}
  {% endtabs %}

## Migration Overview

Here is an overview of the migration timeline and associated events:

| Event                          | Period            |
| ------------------------------ | ----------------- |
| Sonic launch                   | December 18, 2024 |
| Migration period               | Launch onwards    |
| Two-way swap between FTM and S | First 90 days     |
| One-way swap (FTM to S only)   | After 90 days     |

{% hint style="info" %}
Opera will continue to operate, but all future development focus will shift to Sonic.
{% endhint %}

{% content-ref url="/pages/CcCW67Cg8ezfSHsJsq4g" %}
[Migration FAQ](/migration/migration-faq)
{% endcontent-ref %}


# App Token Migration

This page outlines token migration options for apps from Fantom Opera to the Sonic chain.

It provides comprehensive guidance for both token holders and project owners regarding their migration options.

{% tabs %}
{% tab title="App Token Holders" %}

## Instructions for Token Holders

The official Sonic Labs [upgrade portal](https://my.soniclabs.com/upgrade) will facilitate the FTM to S upgrade on a 1:1 basis.

For the first 90 days after Sonic's launch, you'll be able to swap between the two tokens freely. After this period, swaps will only be possible in one direction, from FTM to S.

### Official Migration Contract Timeline

| Phase          | Duration   | Conversion Type | Notes                 |
| -------------- | ---------- | --------------- | --------------------- |
| Initial period | 90 days    | Two-way FTM ↔ S | Full flexibility      |
| Final phase    | Indefinite | One-way FTM → S | No reverse conversion |

### CEX-Held FTM

If you hold FTM on a centralized exchange, we’re collaborating with major exchanges to enable users to upgrade FTM to S directly on their platforms. Stay tuned for updates from the CEX where you hold your FTM.

Alternatively, you can withdraw your FTM to Fantom Opera and upgrade to S through our [upgrade portal](https://my.soniclabs.com/upgrade).

### Staked FTM

Users will be able to unlock their staked FTM and bridge immediately to Sonic following a 24-hour withdrawal waiting period. The new Sonic staking system features:

| Parameter         | Requirement |
| ----------------- | ----------- |
| Withdrawal period | 14 days     |
| Minimum stake     | 1 S         |

### LP Positions

If you hold liquidity positions, you'll need to:

1. Break existing LP positions on Fantom
2. Migrate each token individually following their specific processes
3. Recreate your positions on Sonic

### Other Token Holders

Contact your token's project team to learn their specific migration plan. Each project will choose between migration options such as:

* Bridge migration through LayerZero
* Airdrop migration based on snapshots
* Hybrid approach combining both methods
  {% endtab %}

{% tab title="Project Developers" %}

## Instructions for Project Owners

Projects have several options to migrate tokens from Fantom to Sonic. There is no one-size-fits-all solution — choose based on your token's setup and requirements.

### Option 1: Bridge Migration

Day-one token bridging will be available through LayerZero at the Sonic launch.

| Provider  | Implementation      | User Interface | Documentation                                                                       |
| --------- | ------------------- | -------------- | ----------------------------------------------------------------------------------- |
| LayerZero | Technical OFT setup | Stargate       | [OFT Standard](https://docs.layerzero.network/v2/home/token-standards/oft-standard) |

**Limitations**

* Burnt LP remains on Fantom
* If LP was sent to SCC, it can be bridged and recreated
* Original token contract stays on Fantom (generally not an issue)

***

### Option 2: Airdrop Migration

Deploy new token contract on Sonic with snapshot-based airdrop distribution.

**Special Cases Requirements**

| Case         | Handling Required | Solution                     |
| ------------ | ----------------- | ---------------------------- |
| Multisigs    | Yes               | Different addresses on Sonic |
| LP tokens    | Yes               | Snapshot by LP weights       |
| Burnt tokens | Optional          | Can redistribute on Sonic    |
| Initial LP   | Yes               | Additional funds for pairing |

**Advantages**

* Works for burnt tokens and LPs
* No bridge needed

**Limitations**

* Special handling for LP and multisig holders
* More preparation work needed
* Recreation of initial burnt LP requires additional funds

***

### Option 3: Hybrid (Beethoven X Approach)

1. Deploy new token on Sonic
2. Enable bridging of original tokens
3. Create migration contract for 1:1 swaps
4. Allow two-way conversion initially
5. Switch to one-way later

**Example Implementation**

* New contract: sonicBeets
* Users bridge fantomBeets to Sonic
* Migration contract handles 1:1 exchange
* Two-way conversion for limited time
* Mirrors official FTM → S migration process
  {% endtab %}
  {% endtabs %}

{% content-ref url="/pages/CcCW67Cg8ezfSHsJsq4g" %}
[Migration FAQ](/migration/migration-faq)
{% endcontent-ref %}


# Migration FAQ

Below are the most frequently asked questions specifically regarding the migration process from Fantom Opera to Sonic.

<details>

<summary>What if I hold FTM somewhere other than Opera?</summary>

Check out the [Sonic Upgrade Handbook](https://blog.soniclabs.com/the-ultimate-sonic-upgrade-handbook-ftm-to-s/).

</details>

<details>

<summary>Does the upgrade portal handle app token migrations?</summary>

No, the official upgrade portal only supports FTM to S migration on Opera. Each project must implement its own migration solution.

</details>

<details>

<summary>What happens to my LP positions during migration<strong>?</strong></summary>

LP positions must be broken, tokens migrated individually, and positions re-created on Sonic.

</details>

<details>

<summary>How long will two-way migration be available<strong>?</strong></summary>

Two-way migration between FTM and S will be available for 90 days following launch, after which it will switch to one-way from FTM to S.

</details>

<details>

<summary>What happens if I don't migrate during the two-way period<strong>?</strong></summary>

You'll still be able to upgrade from FTM to S but not back to FTM from S.

</details>

<details>

<summary>Will my transaction history migrate?</summary>

No, transaction history remains on the original chain. Sonic is a fresh chain with no history.

</details>

<details>

<summary>How do I know the migration method used by a token I'm holding<strong>?</strong></summary>

Check your project's announcements or contact the team directly.

</details>


# Overview

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

Sonic achieves 400,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](/technology/consensus)
* [Database Storage](/technology/database-storage)
* [Proof of Stake](/technology/proof-of-stake)


# 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. As of Sonic v2.1, the network also supports the Ethereum Prague/Pectra feature set, including EIP-7702 (set EOA account code), EIP-2537 (BLS12-381 precompile), and EIP-7623 (increased calldata cost). See Pectra Compatibility for the full list of supported Prague-era EIPs.

{% hint style="info" %}
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.
{% endhint %}


# 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**

* [Account Abstraction](/technology/pectra-compatibility/account-abstraction)\
  Customize transaction authorization logic with smart contract wallets.
* [Fee Subsidies](/technology/pectra-compatibility/fee-subsidies)\
  Let users interact with an app without paying gas themselves.
* [Dynamic Fees](/technology/pectra-compatibility/dynamic-fees)\
  Monetize app usage via increased gas consumption.
* [Alternative Fee Payments](/technology/pectra-compatibility/alternative-fee-payments)\
  Accept ERC-20 tokens or off-chain settlement for gas fees.


# 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**\
  **R**equiring multiple signatures before a transaction can be executed.
* **Social Recovery**\
  **A**llowing 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** \[[account-abstraction-webauthn](https://github.com/G7DAO/account-abstraction-webauthn)]
   * 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** \[[solidity-based-social-auth](https://luhenning.medium.com/solidity-based-social-auth-sending-crypto-to-any-google-account-ae098044bb2d)]
   * 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.
3. **n-of-m signature requirements via** [**Web3Auth**](https://web3auth.io/docs/infrastructure/)
   * Supports conventional social login (e.g. Google account plus additional factors).
   * Depends on the trustworthiness of the third-party service (Web3Auth servers).
4. **Social Recovery** ([ERC-7093](https://eips.ethereum.org/EIPS/eip-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.


# 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**

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:

```solidity
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
   }
}
```


# Dynamic Fees

## **Objective**

Dynamic fees allow app developers to monetize usage of their app without requiring users to pay an explicit fee. Instead, users pay a multiple of the normal gas cost, and the excess is automatically transferred to the app developer.

## **Solution**

On Sonic, developers can enroll in the [Fee Monetization](/funding/fee-monetization) program, which lets builders earn 90% of the network fees their apps generate. To benefit, developers simply need to increase the gas consumption of their contracts in a controlled manner.

The following examples outline best practices for safely increasing contract gas usage. Use the abstract contract below as a parent for your own contract:

```solidity
abstract contract DynamicGasCharging {

   uint256 private gasScalingFactor;

   /**
    * @dev Consume the given amount of gas.
    * In contract code this function can be flexibly used at any place to add extra gas consumption
    */
   function _consumeGas(uint256 gas) view internal {
       uint256 initialGas = gasleft();
       uint256 wantedGas = initialGas - gas;
       while (gasleft() > wantedGas) {
           // do nothing
       }
   }

   // Modifier to increase the gas costs of a function by a configurable multiplier
   modifier scaleGasCosts() {
       uint256 initialGas = gasleft();
       _;
       uint256 gasUsed = initialGas - gasleft();
       _consumeGas(gasUsed * (gasScalingFactor-1));
   }

   // Set the scaling factor (to be called by implementations)
   function _setGasScalingFactor(uint256 newGasScalingFactor) internal {
       gasScalingFactor = newGasScalingFactor;
   }

}
```

Once integrated, the following changes must be applied to your contract:

1. Inherit from the `DynamicGasCharging` contract.
2. Add the `scaleGasCosts` modifier to each function where dynamic gas charging should apply.
3. Set the `gasScalingFactor`—either in the contract initializer or via an `onlyOwner` function.

Example:

```solidity
contract DynamicGasExample is DynamicGasCharging, Ownable {

   function myMethod() external scaleGasCosts {
       counter++; // code of your method
   }

   function setGasScalingFactor(uint256 newGasScalingFactor) external onlyOwner {
       _setGasScalingFactor(newGasScalingFactor);
   }

}
```


# 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.

## **Solution**

An alternative fee payment system can be built on the same ERC-4337 account abstraction principles used in the [fee subsidies mechanism](https://docs.soniclabs.com/~/changes/292/technology/pectra-compatibility/fee-subsidies).

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](https://developers.circle.com/stablecoins/paymaster-overview) by the token issuer. For other ERC-20 tokens, developers can implement a custom paymaster by extending, for example, `PaymasterERC20` from OpenZeppelin community-contracts:

```solidity
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 {}
}
```

A guide for creating similar paymasters can be found in the [OpenZeppelin documentation](https://docs.openzeppelin.com/community-contracts/0.0.1/paymasters#chainlink_price_feeds).


# 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](/sonic/build-on-sonic/getting-started#sonic-testnet))
2. **Frontend Demo**\
   Requires a running [bundler](https://github.com/eth-infinitism/bundler) for UserOperation submission
3. **Bot Demo**\
   Interacts directly with deployed contracts

## Table of Contents

* [Key Features](#key-features)
* [Architecture Overview](#architecture-overview)
* [Understanding Account Abstraction](#understanding-account-abstraction)
  * [EIP-7702: Protocol-Level Account Abstraction](#eip-7702-protocol-level-account-abstraction)
  * [ERC-4337: Smart Account Framework](#erc-4337-smart-account-framework)
  * [How They Work Together](#how-they-work-together)
* [Project Components](#project-components)
* [Installation & Setup](#installation-and-setup)
* [Deployment](#deployment)
* [Running the Demo](#running-the-demo)
* [Testing](#testing)
* [Technical Deep Dive](#technical-deep-dive)
* [Developer Resources](#developer-resources)

## 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)
* Real-time UserOperation construction and submission

## Architecture Overview

<figure><img src="/files/RUYuim8hnXcH6tDx3633" alt=""><figcaption></figcaption></figure>

## 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
* **Persistent Until Changed**\
  Delegation remains active until explicitly updated

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
5. Users benefit from both simple EOA interactions AND smart account features

## 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
* SignatureCheckingPaymaster.sol: Paymaster with signature validation
* Note: EntryPoint contract is imported from @account-abstraction/contracts

### 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

```git
git clone <repository-url>
cd TicTacToeDemo
```

### Install Dependencies

```git
# Install Node.js dependencies
npm install

# Install Go dependencies
go mod download

# Install frontend dependencies
cd frontenddemo
npm install
cd ..
```

### Environment Configuration

Create a .env file in the root directory:

```git
# Required for deployment
PRIVATE_KEY=your_private_key_here_without_0x_prefix
```

Notes:

* Private key should be without the '0x' prefix
* Sonic RPC URL is already configured in hardhat.config.ts

## Deployment

### Compile Contracts

```git
npx hardhat compile
```

### Deploy Contracts

Deploy to Sonic testnet (chain ID 14601):

```git
# 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
```

### Verify Contracts

```git
# For Sonic testnet
npx hardhat ignition verify --network sonic-testnet
```

## Running the Demo

### 1. Start the Bundler

The bundler aggregates UserOperations and submits them to the EntryPoint:

```git
# 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

```

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:

```git
# 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
```

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)
* `--blocksPerQuery`: Max block range for event queries (default: 10000)
* `--keystore`: Path to keystore JSON file
* `--keystorePass`: Path to keystore passphrase file (optional)

### 3. Launch Frontend

```git
cd frontenddemo
npm run dev

```

Open [http://localhost:5173](http://localhost:5173/) in your browser.

## Testing

Run the comprehensive test suite:

```git
# 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
```

## Technical Deep Dive

### UserOperation Structure

```solidity
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
}
```

### EIP-7702 Authorization

```solidity
auth := types.SetCodeAuthorization{
    ChainID: chainId,
    Address: accountImplementation,  // Smart account code
    Nonce:   accountNonce,
}
signedAuth := SignSetCode(privateKey, auth)
```

### 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
* Storage: Packed uint256 for efficient gas usage

## 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
* 🔄 Social recovery and multi-sig support

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:

```solidity
interface IAccount {
    function validateUserOp(
        PackedUserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 missingAccountFunds
    ) external returns (uint256 validationData);
}
```

Paymaster interface:

```solidity
interface IPaymaster {
    function validatePaymasterUserOp(
        PackedUserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 maxCost
    ) external returns (bytes memory context, uint256 validationData);
}

```

### 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:

5. Frontend bundler connection: Update bundler URL in Vue components if not using default
6. Go version error: Ensure Go 1.24+ is installed (check with go version)
7. Contract deployment fails: Ensure wallet has sufficient funds and correct network is selected
8. Bot can't join games: Check keystore file permissions and passphrase
9. Bundler errors: Ensure the mnemonic account has funds for gas

### Further Reading

* [EIP-7702 Specification](https://eips.ethereum.org/EIPS/eip-7702)
* [ERC-4337 Specification](https://eips.ethereum.org/EIPS/eip-4337)
* [Account Abstraction Resources](https://www.erc4337.io/)

<br>


# 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 <a href="#practical-byzantine-fault-tolerance" id="practical-byzantine-fault-tolerance"></a>

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](https://academy.binance.com/en/articles/byzantine-fault-tolerance-explained?ref=blog.fantom.foundation), 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.

<figure><img src="/files/u72lp3OShs34w6gkaUM6" alt=""><figcaption></figcaption></figure>

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 [proof-of-stake](https://docs.fantom.foundation/technology/proof-of-stake?ref=blog.fantom.foundation), 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 <a href="#asynchronous-byzantine-fault-tolerance" id="asynchronous-byzantine-fault-tolerance"></a>

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 synchronous consensus systems, such as Bitcoin's Nakamoto consensus (proof-of-work), in which blocks are produced sequentially and finality is probabilistic, requiring multiple confirmations before a transaction is considered settled.

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 href="#directed-acyclic-graphs" id="directed-acyclic-graphs"></a>

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.

<figure><img src="/files/H9FJMwuBgLCBylDfjjhr" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/RTfz6zgunM4ldybRORq7" alt=""><figcaption><p><em>A validator’s block DAG</em></p></figcaption></figure>

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.

<figure><img src="/files/RiNoRlxJ4u0lTpwn1MWo" alt=""><figcaption><p><a href="https://www.cbcamerica.org/blockchain-insights/dag-the-dlt-directed-acyclic-graph-for-enterprise-blockchain?ref=blog.fantom.foundation"><em>Source:</em> <em>Central Blockchain Council of America</em></a></p></figcaption></figure>

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 [block explorer](https://ftmscan.com/?ref=blog.fantom.foundation), 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:

[Lachesis: Scalable Asynchronous BFT on DAG Streams](https://arxiv.org/abs/2108.01900?ref=blog.fantom.foundation).


# 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 [archive nodes](/sonic/node-deployment/archive-node) have both LiveDB and ArchiveDB to handle historical data requests through the RPC interface.

<figure><img src="/files/2GHfd2Zz29rdphET6jw8" alt=""><figcaption></figcaption></figure>

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.


# 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.


# 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.

<table data-full-width="true"><thead><tr><th width="99.26171875">Version</th><th width="135.3671875">End of Development</th><th width="124.578125">Release Date</th><th>Change Logs</th><th>Commits</th></tr></thead><tbody><tr><td>v2.1.6</td><td>Mar 12, 2026</td><td>Mar 12, 2026</td><td><ul><li>Geth dependency updated to v1.16.9. Integrated security patches for CVE-2026-26314 and CVE-2026-26315. </li><li><p><strong>Important:</strong> Recommend recreating p2p node key after install by removing <code>&#x3C;datadir>/p2p/nodekey</code> before restarting. </p><ul><li>Note: this changes the p2p node ID, which may break static peering setups.</li></ul></li></ul></td><td><p></p><ul><li>26dd110c – Update version to v2.1.6 (#714)</li><li>56146a6a – Geth dependency upgrade release 2.1.6 (#666)</li><li>8a0a07c4 – Update license (#651)</li><li>6897a5f6 – Update version to v2.1.6-rc.1 (#641)</li></ul></td></tr><tr><td>v2.1.5</td><td>Feb 5, 2026</td><td>Feb 5, 2026</td><td><ul><li>Added optional event throttling for validator nodes with low stake to reduce network resource usage. </li><li>Extended <code>eth_subscribe</code> RPC to optionally return full transaction details.</li></ul></td><td><p></p><ul><li>65a5ef18 – Update version to v2.1.5 (#640)</li><li>4c1ac99a – Rename event throttler flag (#633)</li><li>5b8f9d08 – Add metrics to monitor skipping event emission (#629)</li><li>65a11bbd – Integrate event throttler (#626)</li><li>c5f7b2ca – Add event throttler simulation (#623)</li><li>69402690 – Add event throttling object (#622)</li><li>58d24883 – Extend event throttler attendance testing (#621)</li><li>113be16f – Event emission throttling: Introduce attendance list (#620)</li><li>fce3382a – Add dominant set computation for event throttling (#617)</li><li>c3f8ce88 – Update event throttler config (#618)</li><li>4dba6a77 – Move emitter config to its own package (#615)</li><li>63ae97b1 – Event throttling config (#610)</li><li>41764525 – Add integration test for network progress with validator stake changes (#587)</li><li>cdc44bef – Add option to define validator stakes in integration testing (#568)</li><li>c33999e4 – eth_subscribe: Add option to return full transactions (#589) (#613)</li><li>0b0ed7d8 – Update version to v2.1.5-rc.1 development ready (#606)</li></ul></td></tr><tr><td>v2.1.4</td><td>Nov 25, 2025</td><td>Nov 25, 2025</td><td><ul><li>Fix log timestamps serialization (RPC). </li><li>Fix consistency of log transaction indices when querying logs using block hash (RPC). </li><li>Transaction Pool rejects transactions from non-EOA accounts.</li></ul></td><td><p></p><ul><li>d71420e9 – Update version to v2.1.4 (#602)</li><li>7b0077b2 – Add missing transaction indexing in log retrieval by hash (#578)</li><li>413c9133 – Add checks to txpool (#581)</li><li>b4f7090f – Fix logs blocktimestamp JSON encoding (#573)</li><li>f4ae9adf – Update version to v2.1.4-rc.1 development ready (#580)</li></ul></td></tr><tr><td>v2.1.3</td><td>Nov 5, 2025</td><td>Nov 5, 2025</td><td><ul><li>Reduce overhead from handling sponsored transactions in the transaction pool under heavy load. </li><li>Reuse transaction sender to reduce signature overheads. </li><li>Mitigation for P2P events broadcasting lag stalling block processing.</li></ul></td><td><p></p><ul><li>da095a25 – Update version to v2.1.3 (#579)</li><li>50ae700b – Dockerize Jenkins pipeline (#459) (#575)</li><li>2d8a2f1b – Increase default EventsBufferLimit to avoid sync lags (#555)</li><li>6a50a595 – Signers cleanup (#550)</li><li>ce5321bc – Cache results of isSubsidised (#543)</li><li>657d0441 – Update version to v2.1.3-rc.1 development ready (#548)</li></ul></td></tr><tr><td>v2.1.2</td><td>Oct 8, 2025</td><td>Oct 8, 2025</td><td><ul><li>Added Gas Subsidy support. </li><li>Fixed backward compatibility of gas limit updates.</li></ul></td><td><p></p><ul><li>7f4da1db – Update version to v2.1.2 (#547)</li><li>3b848aa5 – Fix backward compatibility of gas limit updates (#522)</li><li>163cacd0 – Add integration test: Subsidies funds deducted after sponsored tx (#535)</li><li>06162836 – Filter transactions with lost sponsorship in reorg (#534)</li><li>308646cb – Integrate getGasConfig call into Subsidies Registry contract (#523)</li><li>471fd56c – Validate sponsored transactions when added to transaction pool (#524)</li><li>0118bafe – Enforce inclusion of sponsored transactions into Pending set (#518)</li><li>f55eb775 – Deploy gas subsidies registry contract when upgrades enabled (#517)</li><li>6b3ce61c – Fix TransactionIndices in receipts if transactions introduced by state processor (#516)</li><li>a96cc9f7 – Add support for sponsored transactions (#514)</li><li>7d314e26 – Add GasSubsidies flag to tx_pool transaction validation (#515)</li><li>56fd50c5 – Introduce transaction processing context (#513)</li><li>66391d4d – Add fee overflow check to IsCovered utility (#512)</li><li>3e437b31 – Update subsidies registry interface (#507)</li><li>f8a26e11 – Factor out transaction processing from StateProcessor (#497)</li><li>6c28c32d – Introduce feature flag for gas subsidies (#481)</li><li>77d5e2be – Upgrade SFC version used in fake nets (#482)</li></ul></td></tr><tr><td>v2.1.1</td><td>Sep 23, 2025</td><td>Sep 23, 2025</td><td><ul><li>Fix empty logs bloom (RPC). Add CreateTransaction helper function. </li><li>Set chain ID for internal transactions in RPC. </li><li>Remove deprecated default command arguments. </li><li>Improve unit and integration tests.</li></ul></td><td><p></p><ul><li>4f798e29 – Update version to v2.1.1</li><li>0610ae03 – Increment release candidate version (#471)</li><li>98616c44 – RPC api: Fix empty logs bloom (#464)</li><li>3b8ea018 – Wait for processed transaction to leave tx pool (#463)</li><li>b9bc7173 – Add CreateTransaction helper function (#461)</li><li>9a6fb277 – Set chain ID for internal transaction in RPC (#454)</li><li>ec813b69 – Remove deprecated default command arguments (#442)</li><li>b2734b74 – Migrate gossip handler fuzzer (#441)</li><li>a26e5715 – Single proposer pkg (#436)</li><li>c48e3469 – Add integration test for RPC calls at different block heights (#428)</li><li>cb174be7 – Update version to v2.1.1-rc.1 (#450)</li></ul></td></tr><tr><td>v2.1.0</td><td>Aug 20, 2025</td><td>Aug 20, 2025</td><td><ul><li>Ethereum Prague upgrade support: EIP-7702 account abstraction, EIP-2537 BLS precompiles, EIP-2935 historic block hashes, EIP-7623 increased calldata gas cost. </li><li>Input validation for network rule updates. Updated go-ethereum to geth 1.16. </li><li>Legacy code quality improvements. </li><li>Protocol security enhancements. </li><li>Bug fixes.</li></ul></td><td><p></p><ul><li>8c95f202 – Update version on v2.1 branch to v2.1.0 (#447)</li><li>9ba90a92 – Add integration test for type 4 transaction (set EOA code, EIP-7702) (#72)</li><li>1119b125 – Implement EIP-7702 support in RPC calls (#81)</li><li>c37a7dc9 – Update transaction validation for Prague revision (#56)</li><li>7ce78679 – SetCodeTx: changes to transaction pool (#74)</li><li>83895ddc – Modify RPC callbacks to execute EIP-2935 History Storage Contract (#146)</li><li>bc15eca9 – EIP-2935: Implement processor routine to call history storage contract (#133)</li><li>9d020e70 – Add feature changes and test for EIP-7623 (#110)</li><li>4e353186 – Add implementation of a BLS library (#29)</li><li>93ee70c3 – Update ChainConfig to enable Prague fork (#44)</li><li>f523066a – Update geth dependency to version 1.16.0 (#349)</li><li>73f8bf9a – Update geth dependency to 1.15.11 (#321)</li><li>b263f56d – Network rule validation (#142)</li><li>9aa56547 – Integrate single-proposer protocol in emitter and block processor (#232)</li><li>6e812476 – Introduce brio hardfork (#292)</li><li>f9d6754b – Remove FeatureSet in favour of Upgrades (#238)</li><li>07ee5460 – Add allegro hard-fork flag (#20)</li><li>484ae8ce – Add license to Sonic files (#334)</li><li>47639163 – Replace outdated Fantom mentions by Sonic (#327)</li><li>ba4f4a93 – Rename Opera mentions to Sonic (#351)</li></ul></td></tr><tr><td>v2.0.7</td><td>June 26, 2025</td><td>TBA</td><td><br>• Improved error handling in <code>debug_traceBlock</code> — now uses error field and supports empty blob cases</td><td><ul><li>252c9ee0 – Fix error handling in debug_traceBlock (#307)</li></ul></td></tr><tr><td>v2.0.6</td><td>May 6, 2025</td><td>May 26, 2025</td><td><ul><li>Synchronized access to cached block hashes to prevent rare incorrect RPC returns</li><li>Added <code>NoArchiveError</code> check before sending block notifications</li><li>Updated Tosca dependency</li></ul></td><td><ul><li>e44b0188 – Update Tosca dependency</li><li>00c1f2af – Synchronize cached block hash access (#209)</li><li>124dc66e – Add <code>NoArchiveError</code> check for notifications (#214)</li><li>a4e31329 – Update to v2.0.6-dev (#217)</li><li>4551d1fc – Prepare v2.0.5 release (#201)</li></ul><p><br></p></td></tr><tr><td>v2.0.5</td><td>April 11, 2025</td><td>April 28, 2025</td><td><ul><li>Verified archive block height before sending subscriber notifications</li><li>Switched <code>eth_call</code> simulation to GETH for large code handling in state override</li><li>Fixed test infrastructure and updated Go to v1.24</li></ul></td><td><ul><li>ea9e3631 – Add missing dependency</li><li>2d9284a8 – Use GETH for eth_call with large code (#189)</li><li>135b69cc – Fix BlockInArchiveTest infra &#x26; Go 1.24</li><li>e95926e4 – Update indirect dependencies (#121)</li><li>e3f7b4c8 – Check archive height before notifications (#149)</li><li>48cdac00 – Update to v2.0.5-dev (#171)</li></ul></td></tr><tr><td>v2.0.4</td><td>March 15, 2025</td><td>March 26, 2025</td><td><ul><li>Enabled transaction replay on empty blocks</li><li>Added block overrides for RPC calls</li><li>Updated <code>NoBaseFee</code> VM parameter for transaction replay</li></ul></td><td><ul><li>#26 – Replay transactions on empty blocks</li><li>#30 – Add block overrides for RPC</li><li>#104 – Update NoBaseFee VM config</li></ul></td></tr><tr><td>v2.0.3</td><td>Feb 6, 2025</td><td>Feb 19, 2025</td><td><ul><li>Updated go-ethereum dependency to add on-curve check for unmarshaled public keys</li><li>Improved intrinsic gas error detection</li><li>Added <code>SetStorage</code> on Carmen adapter</li><li>Allowed profiler/tracer stop calls even if never started</li></ul></td><td><ul><li>ecc88ecd – Fix version commit/date (#15)</li><li>2340cc37 – Accept profiler/tracer stop calls (#17)</li><li>325fb5ea – Implement <code>SetStorage</code> on Carmen adapter (#2)</li><li>8cc06953 – Update go-ethereum for on-curve check (#5)</li><li>f9eb911a – Fix intrinsic gas error recognition (#4)</li><li>46908a5c – Update module name to 0xsoniclabs/sonic (#1)</li></ul></td></tr><tr><td>v2.0.2</td><td>Jan 23, 2025</td><td>Jan 31, 2025</td><td><ul><li>Enhanced RPC gas capping</li><li>Added <code>getAccount</code> RPC method</li><li>Improved finalized/safe block tag handling</li><li>Reduced event payload fetching during streaming</li><li>Minor bug fixes</li></ul></td><td><ul><li>19dc2691 – Remove <code>dev</code> from meta version (#394)</li><li>3f86ba1c – RPC gas capping (#391)</li><li>b9545c63 – Implement getAccount RPC (#370)</li><li>1a233d03 – Update version to v2.0.2 (#387)</li><li>79519713 – Fix error propagation (#389)</li><li>cda79533 – Handle finalized/safe block tags (#388)</li><li>0e1599a6 – Skip event payload fetch in streaming (#372)</li><li>7265d537 – Use data from proof (#371)</li></ul></td></tr><tr><td>v2.0.1</td><td>-</td><td>Dec 2, 2024</td><td>-</td><td>-</td></tr><tr><td>v2.0.0</td><td>-</td><td>Nov 29, 2024</td><td>-</td><td>-</td></tr></tbody></table>


# 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](/sonic/sonic-gateway) is our native bridge between Ethereum and Sonic.

* [OpenZeppelin](https://blog.openzeppelin.com/sonic-gateway-audit)
* [Quantstamp](https://certificate.quantstamp.com/full/sonic-gateway/fbb78575-2a22-4f4b-813f-340eb6296185/index.html)
* [Certora](https://www.certora.com/reports/sonic-bridge)

## FTM to S Bridge

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

* [OpenZeppelin](https://blog.openzeppelin.com/sonic-opera-native-token-bridge-audit)

## Special Fee Contract (SFC)

The SFC manages staking and validator operations on Sonic.

* [Quantstamp](https://certificate.quantstamp.com/full/sonic-sfc/69febf14-e620-45f8-bfa5-5de3277980c0/index.html)

***

{% hint style="info" %}
Please report bugs to <bugs@soniclabs.com>.
{% endhint %}


