Only this pageAll pages
Powered by GitBook
Couldn't generate the PDF for 101 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

CrossCurve MetaLayer

CrossCurve MetaLayer

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

CrossCurve DAO

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Earn with CrossCurve

Loading...

Loading...

Loading...

user documentation

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Developer documentation

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

About CrossCurve

Loading...

Loading...

Migration to Sonic

NFTs

CrossCurve Consensus bridge

The CrossCurve Consensus Bridge addresses one of the key problems of modern cross-chain solutions — the vulnerability of bridges and the so-called “black swan” risk. A prime example of such a risk is the Multichain incident, after which Curve DAO withdrew its trust from bridges based on centralized governance.

The core issue lies in the fact that most existing bridges are controlled by a limited group of participants — validators or members of multisig groups. This makes them vulnerable and unstable. Classic examples of such failures include hacks or loss of funds in protocols such as Multichain, PolyNetwork, Wormhole, Nomad and Ronin.

Unlike the traditional PoA (proof-of-authority) solutions, the CrossCurve Consensus Bridge uses a validation model based on agreement between independent data transmission protocols. This architecture involves Axelar, LayerZero, Router Protocol, Asterizm and Chainlink CCIP. A transaction is completed only if consensus is reached among multiple sources. If the data diverges, the transaction is automatically rejected, preventing potential compromise and ensuring the safety of user funds.

How it works:

  • The user's assets are locked in the consensus bridge smart contract on the source network.

  • Transaction data is transmitted through multiple protocols simultaneously, and the smart contract of the target network verifies their consistency.

  • If consensus is reached, the transaction is finalized; otherwise, the funds are returned to the user.

Advantages:

  • Security: The risk of compromise is minimized thanks to consensus among several protocols — the likelihood of all protocols being hacked at the same time is virtually zero.

  • Decentralization: Bridge security does not depend on individual teams; the bridge smart contracts are governed by CrossCurve DAO, and the protocol’s liquidity is fully controlled by users.

  • Versatility: The consensus bridge supports the transmission of both tokens and data, making it a universal tool for cross-chain applications.

Consensus Bridge is not just a bridge—it is the transport layer of the CrossCurve Metalayer, providing a reliable connection between blockchains. It enables developers and users to safely transfer assets, data, and liquidity, forming the foundation for a scalable and resilient cross-chain ecosystem of the future.

What is CrossCurve MetaLayer

CrossCurve MetaLayer is a unified decentralized infrastructure for cross-chain liquidity and incentives, powered by the Curve AMM. It enables efficient swaps, yield generation, and access to deep DeFi liquidity secured by the Consensus Bridge.

MetaLayer Architecture

CrossCurve MetaLayer emerged as a logical extension of the decentralized EYWA bridge. A simple “bridge” is no longer sufficient—more advanced solutions are required for real

DeFi
use. Reliability and efficiency are the two key requirements for modern cross-chain services.
MetaLayer
was created to meet these demands through a modular architecture that includes three interconnected layers:

1. Transport Layer — Consensus Bridge

This layer is responsible for securely transferring liquidity between blockchains. The Consensus Bridge simultaneously uses several trusted protocols (such as Axelar, LayerZero, Wormhole), significantly reducing the risk of attacks.

2.Liquidity Layer

This layer addresses several critical functions:

  • Efficient liquidity use. In traditional models, liquidity must be reserved for each blockchain pair, leading to exponential cost growth. In MetaLayer, all liquidity is concentrated in the Sonic hub-chain and shared through Curve Stable Pools. This reduces the liquidity requirement from 2N²−N to 2N, delivering up to ~49.5x efficiency gains when supporting 50 blockchains.

  • On-chain swaps. Curve AMM algorithms enable automatic asset exchanges based on liquidity distribution. If liquidity is lower in a certain direction, slippage increases—everything remains fair and transparent.

  • Secure storage. Curve pools are audited and manage over $2 billion in TVL— this represents proven security and user trust.

3. Management Layer — CrossCurve DAO

Decentralized governance is not just a slogan—it is the foundation of MetaLayer’s operation. All key decisions are made by DAO participant a through voting. This eliminates centralization risks. Additionally, the ve(3,3) tokenomics model allows incentives to be directed toward the most active and profitable areas. More activity means more rewards, which attracts more liquidity and makes swaps even more beneficial.


Why Decentralization Matters

CrossCurve MetaLayer is a decentralized protocol for managing cross-chain liquidity. Unlike intent-based protocols, where core logic runs off-chain and requires complex configurations, MetaLayer stays true to DeFi principles. Anyone can become a liquidity provider and earn–no high entry barriers or reliance on centralized intermediaries.

CrossCurve ($EYWA) Roadmap

CrossCurve Technical Roadmap

CrossCurve Roadmap

1. Migration to Sonic

Hub Chain Migration: Transition of CrossCurve’s main liquidity layer from Fantom to Sonic for higher performance and scalability.


2. CrossCurve V2: Liquidity MetaLayer

• New Architecture: Isolated paired pools with synthetic derivatives and Sonic-based liquidity.

• Synthetic Routing: Cross-chain swaps via Sonic liquid assets (e.g., USDC.e, scETH, scBTC).

• Efficient Swaps: Any asset from any chain can be exchanged through two pools.


3. Incentive Mechanisms

• CrossCurve Incentives: Projects can incentivize veEYWA and veCRV holders for voting and liquidity attraction.

• CrossCurve Delegations: Anyone can launch a veEYWA voting aggregator, manage voting power, and earn through protocol revenue, staking boosts, bribes, and inflation rewards.


4. Community Rewards

• Sonic Airdrop Rewards:

• CrossCurve won Sapphire Tier in Sonic BOOM Season 1.

• Received Sonic GEMs (~$1M).

• These will be distributed among CrossCurve liquidity providers.


5. Consensus Bridge

• LayerZero DVN Integration:

• Provides a secure base level of trust for cross-chain swaps and messaging.

• Recommended validator network for multiple protocols.


6. Router Evolution

Router v3

• Advanced Token Transfers:

• Supports transfers to arbitrary addresses.

• Integrated with top aggregators: Li.fi, Bungee, Rango.

• Collects fees for route construction.

• All transactions pass through the Consensus Bridge.

Router v4: CrossCurve as a Liquidity Aggregator

• “Router of Routers” model:

• Supports external token bridges (e.g., Circle, Tether, LayerZero OFT, Wormhole, Axelar, CCIP).

• Omnichain swap support.

• DEX Integration:

• Operates on any external DEX: Uniswap, Balancer, Velodrome, Aerodrome, etc.

• Non-EVM Expansion:

• Porting to chains like Solana, TON, Tron, Sui, Aptos, Ripple, Stellar, Cardano.

• Native Bitcoin Integration:

• Connection with Bitcoin L2 partners for native BTC liquidity.


7. CrossCurve Foundation

• Governance & Sustainability:

• Launching a dedicated CrossCurve Foundation.

• Focus on decentralization, maximizing holder value, and long-term ecosystem growth.

CrossCurve DAO NFT

EYWA DAO NFT is an ERC-721 NFT created when EYWA tokens are locked in the.

Key features:

  • Attaching assets: Each EYWA DAO NFT can have EYWA tokens, Vesting Safes, and other EYWA NFTs attached to it.

  • Obtaining veEYWA: The obtained veEYWA is automatically tired to the corresponding EYWA DAO NFT.

Voting for Incentives

Voting in CrossCurve is more than just participation in governance; it is an effective tool for generating additional income. Your voting power (veEYWA) becomes a valuable asset capable of producing returns alongside basic staking rewards.

How Voting Generates Income

By locking EYWA tokens, you receive veEYWA—voting power that:

  • Grants the right to influence liquidity distribution between pools

CrossCurve Pools v2

Introduction

CrossCurve Pools v2 is an advanced pool system designed to optimize cross-chain liquidity management within the СrossCurve MetaLayer. The system works with three primary asset types: USD-, ETH- and BTC-pegged tokens, which are issued by various projects across different networks. In the hubchain, a set of paired pools is created for each of these asset types. Each pool corresponds to a specific direction (blockchain) and functions as a bridge to that network.

CrossCurve Token Bridge

The CrossCurve Token Bridge lets projects present their token on other networks by locking their assets in smart contracts and issuing the token’s derivative on other networks. Our bridge allows you to move issued derivatives between blockchains in all directions, without having to return to the original token lock network using Cross-chain Data Protocol (CDP).

Regardless of the differences among protocols, rules specifications and governance mechanics of these networks, a usage of the CrossCurve Token Bridge makes it possible for users to move assets among these chains in a reliable and secure way.

Mechanics

The CrossCurve Token Bridge consists of the Portal and Synthesis

Staking mechanics

Staking is the process of locking coins for a certain period, making them unavailable for trading. This mechanism supports decentralization and provides rewards to participants.

In the CrossCurve protocol, staking involves locking tokens in the DAO locker. Rewards are accrued every epoch and are tied to each user’s EYWA DAO NFT. Accrual occurs at the start of the new epoch for the previous one. In CrossCurve, the epoch length is one week, with the end of the epoch at Wednesday 24:00 UTC and the start of the epoch at Thursday 00:00 UTC.

By using the “Compound” transaction, a user can add the earned rewards to the corresponding EYWA DAO NFT, in order to add them to the principal of your position and earn compound interest.


More details on reward calculations per epoch are provided below.

Allows support for projects offering additional rewards

  • Creates an additional income stream beyond basic staking

  • Important: The more veEYWA you hold, the higher the potential earnings from voting. Projects aiming to attract liquidity to their pools offer incentives in various tokens in exchange for your support in voting.

    Sources of Income from Voting

    1. Direct Incentives from Projects

    Different projects compete for your support, offering their tokens as incentives for your votes:

    • Additional token payouts occur each epoch

    • Opportunity to receive tokens from promising projects. Selling immediately or holding onto them is your choice.

    2. Monetizing Voting Power through NFTs

    A unique CrossCurve advantage is monetizing your voting power by selling EYWA DAO NFTs:

    • Vote Selling: Although the veEYWA tokens themselves cannot be transferred directly, you can sell NFTs containing your voting power on the secondary.

    • Pricing: NFT value directly correlates with the amount of veEYWA contained and potential income from voting.

    • Liquidity of Locked Assets: Option to sell voting power without waiting for the lock period to end.

    Given the limited issuance of veEYWA, their value could increase, enhancing the worth of your voting NFTs and creating a third revenue stream.

    Strategies for Maximizing Voting Profits

    Monitoring High-Incentive Offers

    Track projects offering the largest rewards for voting. Analyze proposals, selecting those providing an optimal balance between:

    • Reward size

    • Project stability

    • Token growth potential

    Or delegate this task to professionals via CrossCurve's website interface. (This feature will be available soon)

    Combining with NFT Boosters

    Strengthen your voting power through EYWA NFTs:

    • More veEYWA = more votes = higher rewards

    • Legendary or Infinity level NFTs can increase voting returns by up to 2.8x and 3x respectively

    Active Management of Voting Assets

    Regularly participate in votes to avoid idle veEYWA:

    • Unused votes yield no extra profits (delegate or remember to vote yourself)

    • Monetize your voting power by selling NFTs when necessary

    • Reinvest tokens received from voting into staking to leverage compound interest

    Conclusion

    Voting in CrossCurve is not merely a bureaucratic function but a tangible opportunity to gain additional income, influence the evolution of DeFi, and actively participate in a growing community.

    Multiple ownership: A user can own an unlimited number of EYWA DAO NFT.
  • Summation of veEYWA: The total amount of a user’s veEYWA is equal to the sum of the veEYWA of all their EYWA DAO NFTs.

  • Thus, EYWA DAO NFT serves as a hub for managing your locked assets and voting power in the DAO, providing flexibility and scalability in project governance.


    Creating an EYWA DAO NFT

    When creating an EYWA DAO NFT in the Locker, you can lock EYWA tokens in various states When transferring to the Locker:

    1. EYWA tokens (standard ERC-20)

    • Ownership is transferred to the Locker contract.

    1. Vesting Safe contracts with direct ownership (held in the user’s wallet)

    • Ownership of the Vesting Safe contract is transferred to the Locker.

    1. Vesting Safe contracts with ownership via an NFT (Vesting Safe contracts attached to an EYWA NFT)

    • The Vesting Safe is detached from an EYWA NFT and transferred to the Locker.

    • The EYWA NFT ownership is also transferred to the Locker.

    1. ERC-20 EYWA tokens with ownership via an NFT (EYWA tokens attached to an EYWA NFT)

    • Tokens are detached from an EYWA NFT and transferred to the Locker.

    • Ownership of an EYWA NFT is also transferred to the Locker.

    Calculating veEYWA:

    The Locker calculates the amount of veEYWA based on the total number of EYWA tokens locked, including both standard ERC-20 tokens and those in the Vesting Safe.

    Restrictions when creating an EYWA DAO NFT

    • You cannot create an EYWA DAO NFT by adding an empty EYWA NFT to the Locker.

    • You can attach no more than 100 Vesting Safes and 100 EYWA NFTs to one EYWA DAO NFT.


    Modifying an EYWA DAO NFT

    You can modify an EYWA DAO NFT in several ways:

    Adding additional EYWA tokens:

    • You can lock more EYWA tokens in any of the ways described above at the time of creating an EYWA DAO NFT.

    Adding/attaching empty EYWA NFTs:

    • You can attach additional empty EYWA NFTs to an existing EYWA DAO NFT.

    Removing/detaching EYWA NFTs:

    • You can detach an EYWA NFT from an EYWA DAO NFT, returning them to the user’s ownership.

    Extending the lock duration of tokens:

    • You can extend the lock duration of already locked EYWA tokens to increase voting power.

    Locker

    Why are we moving to Sonic

    CrossCurve is moving to Sonic

    We have made a strategic decision to migrate CrossCurve's hub chain from Fantom (FTM) to Sonic. This is not just a network change - it’s a transition to a new level of speed, efficiency, and possibilities. Let's explore why Sonic is the optimal choice, what benefits it brings to users, and how this step will shape our future.

    Why are we moving to Sonic?

    1. Game-changing speed

    Sonic dramatically accelerates blockchain operations. The average transaction finalization time is just 720 milliseconds.

    For comparison:

    • Ethereum — ~12 seconds

    • Fantom Opera — ~1-2 seconds

    This makes Sonic one of the fastest EVM-compatible blockchains. In DeFi, speed is critical: minimal latency reduces arbitrage risks, improves liquidity conditions, and enhances user experience.

    Sonic brings blockchain interactions closer to Web2 performance—transactions process instantly, while fees remain minimal.

    2. An economic model that rewards projects

    Most blockchains either burn fees or direct them to network funds. Sonic takes a different approach:

    • Up to 90% of fees are returned to developers

    • Projects generate sustainable revenue without raising fees

    • Liquidity is redistributed to benefit everyone: users, developers, and token holders

    The more activity in the network, the higher the protocol revenues and user incentives.

    3. Simple migration and ecosystem support

    Sonic is an evolution of Fantom’s technology but with enhanced features.

    What does this mean for projects?

    • Easy migration — smart contract code requires minimal changes

    • $120M support fund — Fantom has allocated grants to migrate dApps to Sonic

    • Major centralized exchanges have integrated automatic FTM → Sonic (S) swaps

    We gain all the advantages of the new network without losing functionality or liquidity.

    Why is Sonic better than other blockchains?

    1. ve(3,3) Flywheel: a powerful tokenomics model

    Sonic’s economy is built on the ve(3,3) concept, which incentivizes staking, liquidity, and long-term token holding.

    This model has already proven successful in Curve, Solidly and Velodrome, creating a sustainable DeFi cycle.

    2. Leading DeFi projects are moving to Sonic

    Sonic has already attracted top players, including:

    • AAVE — a leading DeFi protocol managing $10B+ in assets

    • Curve — the largest stablecoin exchange platform

    • Solidly and other major DeFi projects — key players in the industry

    This means liquidity and users are already migrating to Sonic, making participation in this ecosystem strategically important.

    3. Full Ethereum compatibility

    Sonic supports EVM, making it fully compatible with existing Ethereum and Fantom smart contracts.

    А Sonic Gateway — a native bridge enabling secure asset transfers between Ethereum and Sonic without reliance on centralized solutions.

    Conclusion

    CrossCurve’s transition to Sonic is not just an upgrade - it’s a leap forward in technology.

    What are the key benefits?

    • 720ms transactions — faster than any other EVM blockchain

    • Up to 90% of fees returned to developers — projects earn more

    • Seamless migration with $120M support — transition risks minimized.

    • Top DeFi projects onboarded — Sonic’s ecosystem is growing rapidly

    Deposit

    👇 Choose the mode to deposit your funds

    Easy mode (Imbalanced)via Curve (Balanced)

    Guide for Developers

    Pool Structure

    Each paired pool in the hubchain consists of two tokens:

    • Universal token - an asset from Sonic, common across all pools of the same type (xfrxUSD for USD assets, xfrxETH for ETH, and scBTC for BTC).

    • Synthetic derivative, backed by the original asset locked in the Consensus Bridge. This can include both single assets and Curve LP tokens.

    Cross-Chain Transfer Process

    CrossCurve Pools v2 enables asset transfers between blockchains in four stages:

    1. Bridge from the source network: The original token is locked in the Consensus Bridge in the source network, and the Consensus Bridge then mints a synthetic token (derivative) in the Sonic network.

    2. Exchange for the universal token: The synthetic token is exchanged for the universal token of the hubchain.

    3. Exchange for the destination synthetic token: The universal token is exchanged for a synthetic token corresponding to the target blockchain.

    4. Bridge to the destination network: The synthetic token is burned in the Consensus Bridge on Sonic, and the Consensus Bridge then unlocks the original token in the destination network.

    Advantages Compared to the Previous System

    The previous pool system used Curve stable pools with 8 assets, connected via liquidity provider (LP) tokens from one or more pools. CrossCurve MetaLayer introduces a fundamentally new approach — liquidity isolation, where each pool contains liquidity only for a single direction. This design delivers the following benefits:

    1. Targeted Incentives

    In the previous system, incentives directed into a pool were distributed across all 8 directions, reducing their effectiveness. In paired pools, blockchains can direct incentives exclusively into their own pool, increasing liquidity in that direction and improving bridge conditions for users.

    2. Reduced Slippage

    In Curve stable pools, increasing the number of tokens in a pool leads to higher slippage under imbalance. A 2-token pool shows significantly less slippage compared to an 8-token one under the same imbalance. Additionally, in the old system, a significant imbalance in one token increased slippage for all 8 directions, while in paired pools, slippage growth is confined to an affected direction only.

    3. Improved Liquidity Efficiency

    To minimize slippage in the previous system, equal liquidity was required across all 8 directions, which was inefficient for less active ones. Paired pools allow using smaller amounts of liquidity for lower-demand directions while maintaining the same slippage level, thus optimizing liquidity utilization.

    4. Lower Risk During Depegs

    A depeg – where an asset drops in value relative to its underlying – is a common occurrence. In multi-asset pools within a single network, a depeg can have wide-reaching consequences for all connected networks, leading to a liquidity drain across all tokens in the pool. For example, in the previous system, if one asset dropped to zero in value while each had $100,000 in liquidity, the total loss across the remaining directions could reach up to $700,000.

    In CrossCurve MetaLayer’s isolated pools, a depeg from one blockchain affects only a single pool. In the same scenario, losses would be capped at $100,000. The system automatically pauses the affected direction when a depeg is detected (based on price deviation), preventing further risks. However, a pool with the synthetic derivative of the depegged token remains in the hubchain until the price stabilizes.

    smart contracts deployed in each of the Blockchains: 1, 2, 3, and uses the
    CrossCurve Cross-chain Data Protocol (CDP)
    to transfer cross-chain calls between them.

    To move assets across Blockchains, the CrossCurve Token Bridge uses synthetic assets (s-tokens). S-tokens are created when someone needs to transfer an asset between two blockchains.

    Example: Native Token Bridging

    Example of bridge with native tokens

    When transferring token X, the bridge uses a Lock-Mint-Burn-Unlock mechanism. The original X token is locked in the Portal smart contract on Blockchain 1. This transaction triggers an event in the bridge smart contract, which is monitored by the Consensus Bridge.

    The Consensus Bridge uses multiple messaging protocols to transmit the event to Blockchain 2. Once a sufficient number of confirmations are received from messaging protocols, the synthetic token sX is minted in the destination blockchain.

    Example: Synth Token Transfer Without Portal

    Example how bridge Synth tokens to other chain without use Portal

    When transferring a synthetic token sX, the bridge uses a Mint-Burn mechanism. The original sX token is sent to the Synthesis smart contract on Blockchain 1, triggering an event in the bridge contract.

    The Consensus Bridge sends the message to Blockchain 2 through multiple messaging protocols. Once enough confirmations are gathered, a new instance of the same sX token is minted on Blockchain 2.

    Example in Practice

    Let’s consider Bob transferring X token from Blockchain 1 to Blockchain 2. The process works as follows:

    1. Bob sends a transaction to the CrossCurve Token Bridge.

    2. The original X token is locked in the Portal smart contract on Blockchain 1.

    3. This triggers an event in the bridge contract, which is tracked and processed by the Consensus Bridge.

    4. The Consensus Bridge uses multiple messaging protocols to independently relay the event to Blockchain 2.

    5. Once enough confirmations are collected, the sX token is minted in Blockchain 2.

    In our example, Bob’s transaction activates the Synthesis contract in Blockchain 2, which issues the synthetic sX token, backed by the X token locked in Blockchain 1.

    At any time, Bob can initiate a reverse conversion to retrieve the original X token.

    Transaction history

    Transferring tokens from one blockchain to another using the CrossCurve Token Bridge is a complex cross-chain operation. The user can track its execution in the interface in real time.

    Security

    Only tokens whose smart contracts have been thoroughly audited by the CrossCurve team are added to the CrossCurve Token Bridge. The audit takes into account many characteristics of the project, and also examines the code of smart contracts for the presence of logic for moving and locking user tokens, which potentially creates a danger to user funds. Only tokens whose code complies with all security rules are allowed to be moved.

    Distribution of Rewards Among DAO Participants

    Each epoch, a fixed number of EYWA tokens (), is allocated for DAO participant rewards. This amount depends only on the total number of locked EYWA tokens in that epoch. All calculations, including the number of locked tokens and the calculated veEYWA, are performed at the end of the epoch. The allocated rewards are then distributed among participants proportionally to their share of veEYWA.


    Algorithm for Calculating Rbase at the Start of DAO Operations

    1. Calculating the ratio of all locked EYWA tokens in this epoch to the total possible volume of EYWA tokens (1,000,000,000):

    1. If is less than 0.14, then is calculated as:

    , where

    Inflation - the emission amount in the calculation epoch.

    1. If is greater than or equal to 0.14, then is calculated as:

    , where

    Inflation - the emission amount in the calculation epoch.

    All numerical coefficients indicated in the formulas are current at the time of DAO launch. They can be changed by DAO participants via voting.


    Staking APY Table with 10 Million Locked Tokens Increments

    For convenience, we have prepared tables with results grouped by different levels of locked token amounts.


    Distribution of Rewards Among DAO Participants

    After determining the total amount for all users (), it is distributed among DAO participants proportionally to the amount of veEYWA each participants holds.

    , where

    - the user’s veEYWA,

    - the total veEYWA of all users,

    - the total reward allocated to all participants.

    DAO
    RatioLockedEYWA=VLockedEYWA1000000000Ratio_{Locked EYWA} = \frac{V_{Locked EYWA}}{1 000 000 000}RatioLockedEYWA​=1000000000VLockedEYWA​​
    Rbase=RatioLockedEYWA∗i∗Inflation+Inflation∗0.01R_{base} = Ratio_{Locked EYWA}*i*Inflation+Inflation*0.01Rbase​=RatioLockedEYWA​∗i∗Inflation+Inflation∗0.01
    i=(3−RatioLockedEYWA∗9)i = (3-Ratio_{Locked EYWA}*9)i=(3−RatioLockedEYWA​∗9)
    Rbase=RatioLockedEYWA∗i∗Inflation+Inflation∗0.18752R_{base} = Ratio_{Locked EYWA}*i*Inflation+Inflation*0.18752Rbase​=RatioLockedEYWA​∗i∗Inflation+Inflation∗0.18752
    i=(0.5−RatioLockedEYWA∗0.2)i= (0.5 - Ratio_{Locked EYWA}*0.2)i=(0.5−RatioLockedEYWA​∗0.2)
    RUserBase=LuserLall∗RbaseR_{User Base} = \frac{L_{user}}{L_{all}}*R_{base}RUserBase​=Lall​Luser​​∗Rbase​

    2024

    Product & CrossCurve Roadmap

    Roadmap timeline:

    📍 Q4 2024

    ▪️ ✅New and pools, as well as adding new chains

    Adding pools with Ethereum and Bitcoin, support of the Linea, Mantle, Blast, and Taiko chains.

    ▪️ ✅

    A unique program for liquidity providers within which users will be rewarded with rEYWA tokens. These tokens can then be exchanged for $EYWA 1:1 after the TGE.

    ▪️ ✅The first cross-chain listing on

    Listing of a project on the , which will make that token available for trading at once in all the networks included into CrossCurve.

    ▪️ ✅Two $EYWA sale community rounds

    An exclusive opportunity for the EYWA community (alpha-testers and anyone Airdrop-eligible) and our key partners — Curve Finance and Alphamind — to obtain $EYWA tokens prior to the listing.

    ▪️ ✅Activating the NFTs’ utility

    The transfer of EYWA NFTs into the Arbitrum network, activation of the merge function of the NFT, the ability to claim the Airdrop after the TGE, and listing on popular marketplaces.

    ▪️ ✅TGE

    Token generation, the start of the unlock period, and the preparation for CEX listing.

    ▪️ ✅CEX listing

    Adding the $EYWA token to centralized exchanges in December 2024.

    ▪️ ✅Launch of the EYWA DAO

    Transferring the control over all of the EYWA smart-contracts to the DAO community. Creating a marketplace of incentives for the EYWA DAO community, and the launch of veTokenomics. Stimulating the demand for $EYWA from Web3 projects and liquidity providers.

    ▪️ ✅Multiple Incentives in the EYWA DAO

    Increasing the income in several pools via a collaboration with Curve Finance. Governing the revenue via DAO voting.

    ▪️ ✅Adapting the TG Mini App for onchain-education.

    📍 Q1 2025

    ▪️ Upgrading Hubchain to Sonic

    Lowering gas fees, increasing transaction speed, and strengthening of security by connecting to the Consensus Bridge.

    ▪️ Connecting partner bridges & tokens to CrossCurve

    Adding new tokens from large partner projects for swapping on CrossCurve.

    Key Milestones:

    • ✅Launching and updating websites & PR campaign in February.

    • ✅Launching CrossCurve DEX based on the aggregation of Curve pools and Eywa Oracle Network in March.

    • ✅Implementing a point system and new tasks in EYWA Adventure Quest.

    • ✅Launching CrossCurve app, using Curve liquidity pools in March.

    CrossCurve Tokenomics

    We present the new improved edition of CrossCurve tokenomics, developed in accordance with the recommendations of experts, auditors and advisors.

    🔗 Full version of CrossCurve tokenomics is available in this spreadsheet

    🎬 Initial circulation supply, FDV and initial market cap

    Listing price: $0,07 Fully diluted valuation: $70 000 000 Market cap on TGE: $3 023 740 IMC (without liquidity): $921 539

    After listing, the total circulating number of the Eywa tokens will be 43 196 286 (4,32% of the total supply). This figure represents the sum of the tokens unlocked on the community round, market-making tokens, airdrop, treasury and KOL tokens.

    TGE mechanics

    The TGE stage includes the following steps:

    1. The Eywa token will be deployed in chain;

    2. The entire EYWA emission (1 billion tokens) will be issued and then transferred to the chain using the CrossCurve Token Bridge.

    3. The vesting contracts will be deployed in chain.

    4. EYWA is an omnichain token and can be moved to ,

    🕐 Eywa token vesting rules

    The CrossCurve tokenomics outline various user categories, each with different lockup periods. After the TGE, all users will receive their personalized safes with vested tokens.

    A vesting period is a time interval during which tokens are unlocked according to a previously approved schedule. The tokens’ unlock logic is programmed into smart contracts and cannot be changed.

    A vesting mechanism aims to mitigate pressure on a token market price, reduce the likelihood of speculation, protect the interests of token holders, and positively influence the long-term project development.

    Details on vesting periods and the unlock scheme are available in the CrossCurve .

    The Eywa vesting tokens feature the following:

    1. Limited movement. Allocations above 1.5 million tokens can only transfer their vesting tokens to whitelisted addresses, facilitating an OTC market.

      Allocations of smaller size, including all Airdrops rounds and Community round participants can move their tokens but ONLY by using . This feature will be available after the migrates to Arbitrum.

      In simple terms, this means that these tokens can be tied to Eywa NFTs and sold on an at any time before the lock-in period ends.

    Migration of Eywa NFTs will be enabled sometime before the TGE. Until then, Eywa NFT tokens can only be purchased on the in the Aurora chain.

    Once migrated, the collection will be listed on leading marketplaces such as and others.

    1. Opportunity to use vesting tokens for staking.

      Eywa vesting token holders can stake their tokens before the end of the vesting period and receive staking/farming rewards.

    2. Opportunity to participate in the CrossCurve DAO to receive veEYWA votes.

    Only veEYWA holders will be eligible to receive boosted rewards for liquidity provision, protocols income and bribes.

    Simply put, ONLY veEYWA vote holders will be able to receive EYWA tokens as rewards.

    Note: Any changes in the accruals during validators’ rounds will be updated .

    Providing Liquidity to CrossCurve Pools

    Types of Liquidity Pools

    CrossCurve offers two distinct types of pools, each with unique features and earning opportunities.

    Stable Pools

    Stable pools are designed for assets whose prices are pegged to each other:

    • Examples: Stablecoin pairs, such as USDT/USDC

    • Derivative Assets: Pairs like wstETH/rETH are also considered stable since their relative prices do not fluctuate significantly

    • Goal: Maintain an exchange rate of 1:1 between assets as accurately as possible

    • Features: Minimal slippage and stable exchange prices due to a specialized AMM formula

    Stable pools are optimized for trading correlated assets with minimal losses and slippage, making them attractive to conservative investors.

    Volatility Pools

    Volatility pools are intended for pairs of assets with fluctuating prices:

    • Examples: USDT/EYWA, ETH/BTC and other uncorrelated assets

    • Formation: Created by combining heterogeneous assets

    • Protection: Utilize Curve's unique mechanism to mitigate impermanent loss

    • Features: Higher risk but potentially higher returns

    Volatility pools are suitable for investors willing to accept higher risks in exchange for potentially higher returns.

    Liquidity Provision Process

    Adding Liquidity

    CrossCurve offers two modes for adding/removing liquidity:

    1. Easy Mode

    • Allows adding or removing funds with a single asset

    • Simplifies the process for beginners

    • Automatically handles all necessary conversions and transactions

    2. via Curve (Balanced)

    • Designed for adding large sums

    • Requires balanced addition of assets to optimize yield

    • Minimizes slippage losses

    Importance of Pool Balancing

    When working with liquidity pools, it's essential to understand the concept of balance:

    • An ideally balanced pool has an equal percentage distribution of all assets

    • For instance, in a xCRVUSDC pool with six s-tokens, the optimal share for each asset is 16.6% of the total TVL

    • Adding an underrepresented asset (share <16.6%) earns an additional bonus

    • Adding an overrepresented asset (share >16.6%) results in losses

    Ways to Earn When Providing Liquidity

    1. Trading fees

    The primary income source for liquidity providers is the trading fees from swaps occurring within the pool:

    • Fees are automatically distributed among all liquidity providers

    • The amount of fees received is proportional to your pool share

    2. Farming and Additional Rewards

    In addition to trading fees, liquidity providers may receive extra incentives:

    • EYWA inflation allocated by CrossCurve DAO voting as an incentive to attract liquidity

    • Other tokens added by external projects to attract liquidity

    • Increased rewards for veEYWA holders (vote-escrowed EYWA)

    • Points for participating in external project programs

    3. Access to StakeDAO and Convex Strategies for Enhanced Yields

    • Obtaining higher yields by placing funds into CrossCurve pools through strategies within “Curve Wars” protocols, such as Convex or StakeDAO

    4. Cross-chain Capabilities

    CrossCurve's unique advantage is its ability to manage liquidity across different blockchains:

    • Liquidity providers can add and withdraw liquidity from all available networks

    • Liquidity providers can swap LP tokens across networks without impermanent loss

    • The ability to quickly and cost-effectively move funds in search of higher yields

    Yield Optimization

    To maximize yields when providing liquidity, it's recommended to:

    • Analyze pool conditions before adding liquidity

    • Select the optimal mode:

      • Easy Mode for small amounts and beginners

    Conclusion

    Providing liquidity on CrossCurve is a powerful earning tool in DeFi. The platform combines Curve Finance's proven reliability with CrossCurve's innovative cross-chain technologies, ensuring user security, convenience, and potentially high returns.

    It’s crucial to remember that liquidity provision always entails certain risks; thus, it’s advisable to carefully study pool mechanisms and yield optimization strategies before making significant investments.

    Routing

    Routing provides a convenient graphical representation of a cross-chain transaction, showing all the transitions and fees involved step-by-step:

    Routing Details Legend

    - Adding token to the pool

    - Removing token from the pool

    - Burning of synthetic token

    - Receiving asset from the pool (LP or token obtained in exchange)

    - Cross-network transition using lock/receive or burn/unlock mechanics

    - Token exchange within the pool

    - Unwrap the native token

    Vesting

    Yield

    DAO

    Operation Interruption

    There are situations where a cross-chain operation may be interrupted:

    1. The operation is interrupted based on the Slippage condition. If, during the transaction execution in one of the pools, the slippage exceeds the upper limit set by the user, the transaction will be interrupted, and the intermediate tokens will be credited to the user's address on the network where the interruption occurred.

    2. The operation is interrupted because the cross-chain call cannot be executed. If the infrastructure facilitating cross-chain interaction fails to execute the cross-chain call, the operation will be interrupted.

    The transaction interruption will be displayed as a message in the Transaction history, where the user will be provided with actions to handle the situation.

    Curve Knowledge Database

    "Curve Knowledge Database" is your comprehensive resource for all things related to Curve Finance.

    🥽Dive into expert insights on Curve's unique AMM system, liquidity pools, staking strategies, and yield optimization techniques. Whether you're a beginner seeking basics or an advanced user exploring in-depth mechanics, this knowledge base is equipped with tutorials, FAQs, analytics, and community wisdom to guide your decentralized finance journey on Curve. Stay informed, stay ahead.

    Balanced mode for larger sums and experienced users

  • Monitor pool balance when adding or removing liquidity to earn bonuses rather than incur penalties due to pool imbalances

  • Combine with EYWA locking to obtain additional rewards through yield boosts

  • Participate in voting for liquidity distribution between polls and vote for your pool (if beneficial, considering other opportunities for selling votes)

  • Claim portal interface
    Early farming program interface
    Farms Interface
    APR Calculator
    EYWA pool via Convex
    Locker Interface
    Vote Interface
    Incentives Interface
    Proposals Interface
    Working with the EYWA Locker contract in Arbiscan.
    Slippage condition
    Balanced liquidity provision
    Guide to transferring CRV from Fantom chain to Ethereum mainnet
    Disclamer

    Withdraw

    👇 Choose the mode to withdraw your funds

    Easy mode (Imbalanced)via Curve (Balanced)

    Pools/asset contracts

    Hubchain Pools and Assets💱Supported tokens

    via Curve (Balanced)

    Adding liquidity to pools on SonicAdding liquidity to pools on Taiko

    Outdated

    Early farming program

    ✅Launching new quest tasks on the website in March.

  • ✅Launching the Ambassador Program.

  • ✅Launching the Early farming program.

  • ✅Adding a new xSTABLE, xWETH and xBTC pools across 12 EVM chains: even lower slippages

  • ✅Undergoing a comprehensive third-party audit to enhance Consensus bridge security

  • ✅Expanding the KOL list for TGE & new partnerships

  • ✅Launching Season 2 of the Airdrop

  • ✅Introducing the long-term on-chain Ambassador Program

  • ✅Conducting Eywa token TGE on Arbitrum and token sales on launchpads.

  • Migrating to Eywa Consensus Bridge.

  • ✅Conducting the first cross-chain listing of a token

  • ✅Conducting a Community Round.

  • ✅Paying bribes to Curve and Convex via Stake DAO and Votium to attract incentives to the main pools.

  • ✅Launching EYWA DAO for EYWA token's main utility.

  • ✅Offering bond purchases, based on Bond Protocol.

  • ✅Migrating the EYWA NFT collection to Arbitrum, activating EYWA NFT functions - container, merge, vote boosting in EYWA DAO, and getting tokens locked in NFTs.

  • ✅Launching a vote-boosted farming program.

  • Creating the EYWA DAO bribery market.

  • ✅Integrating Convex, StakeDAO, and Yearn (cvxEYWA, sdEYWA, yEYWA markets) - launching staking for Eywa token.

  • Integrating into cross-chain bridge aggregators: Rubik, Li.Fi, etc.

  • ✅Receiving CEX confirmation for primary listing

  • Uniswap V2/V3 integration for cross-chain token listings

  • xWETH
    xBTC
    Early farming rEYWA
    CrossCurve
    CrossCurve DEX
    Llamaville
    CrossCurve.fi
    Eywa.fi
    and
    chains.
  • The CrossCurve team will send the Eywa token emission to the vesting contracts in accordance with the project’s tokenomics.

  • Token distribution begins after Listing date in a special section on app.crosscurve.fi which will become available after the TGE. On TGE, users will be able to connect their wallets and access their personal vesting safes, linked to their addresses. During the vesting period, Eywa tokens are unlocked according to the scheme defined in tokenomics, and owners can transfer the unlocked tokens to their wallets.

  • The Listing date will occur no later than 14 days after TGE.

  • smart contract
    Ethereum
    Arbitrum
    Arbitrum
    Arbitrum
    tokenomics
    Eywa NFTs
    NFT collection
    NFT marketplace
    Tofu marketplace
    OpenSea
    here
    BSC
    Fantom
    - Wrap the native token

    Liquidity Interface

    Liquidity Section and its Functionality

    To start working in the CrossCurve application, go to the Liquidity section, in the top right corner click “Connect wallet”, select a suitable wallet from the list and confirm the connection, making sure that you are on the original page https://app.crosscurve.fi/liquidity.

    1. After successfully connecting, in the Choose pool window, select the pool or asset you are interested in for working with liquidity.

    Once you have chosen the necessary asset, the interface will display the TVL in the selected pool, as well as a link to the original pool of the selected asset on , your Wallet Balance showing the amount of the asset, and the Estimated APR for Farming in the selected pool.

    1. The next step is to select the operation to be performed with the asset ( or ) and the method of execution, or .

    For convenience, a quick link to add the token to the wallet via the contract address has been added for correct balance display. By clicking on the “+”, a request will pop up to add a custom token. After signing, it will be displayed in the wallet.

    EYWA NFT Gallery

    The EYWA NFT collection can be found on the Aurora and Arbitrum blockchains.

    You can view your EYWA NFTs right on our website in the NFT->Gallery tab.

    The Gallery/Bridge tab allows you to see all the connected wallet’s NFTs on the Aurora chain available for bridging to the Arbitrum chain.

    The Gallery/Merge tab allows you to see all of the connected wallet’s NFTs on the Arbitrum chain available for rarity increase via merging.

    Gallery / Bridge interface in the Aurora chainGallery / Merge interface in the Arbitrum chain

    Overview of CrossCurve DAO

    CrossCurve DAO — is a democratic, transparent, and decentralized organization that makes strategic decisions, engages participants, and incentivizes their contributions.

    The goal of CrossCurve DAO is to create long-term incentives for attracting sustainable cross-chain liquidity, as well as to accumulate and manage the protocol’s own liquidity to ensure better conditions for cross-chain swaps in the market.

    DAO governance is based on locking the EYWA governance token into veEYWA, which grants voting power. This voting power allows veEYWA holders to participate in decision-making, receive incentives, and earn income from EYWA protocols.


    Advantages of veEYWA

    Balanced liquidity provision

    Example of obtaining the av3CRV LP token from the avDAI/avUSDC/avUSDT CrossCurve pool.

    Here is the pool , and the of supported tokens.

    1. To start, go to the Curve Finance website via the, or go to the Pools tab and enter the name of the pool you wish to find (avDAI/avUSDC/avUSDT) in the search bar. You need to select the network in which the liquidity pool is located where you want to deposit your tokens (liquidity). For this example, the Avalanche network will be used.

    Slippage condition

    The operation is interrupted based on the Slippage condition.

    If an interruption occurs in one of the pools in the cross-chain transaction chain due to the slippage condition, the tokens that were input into the pool will be credited to the sender's account, and the user will be prompted to continue the operation.

    If an operation is interrupted in the Stable swap pool system due to the slippage condition, the user's account will be credited with s-tokens. These tokens are backed by crypto assets locked in Portal smart contracts on supported CLP networks. Through CrossCurve DEX, you can exchange these s-tokens for stablecoins or any other asset available for swapping (full list

    Staking liquidity and earning rewards

    By providing liquidity in CrossCurve pools you can earn rewards in EYWA and/or CRV.

    Staking LP-tokens

    1. After successfully connecting your wallet, you will see all available pools for staking LP tokens.

    After selecting the desired liquidity pool and clicking “Lock LP and get rewards”, we will see a modal window for staking liquidity to earn EYWA and CRV.

    Sonic Upgrade Stages

    Migrating the hubchain to Sonic is a major system upgrade affecting the protocol’s architecture, mechanics, and economy. The principles of working with liquidity are changing, system resilience is increasing, and new earning opportunities are opening up for CrossCurve users. Below are the key stages of this transition:

    1. Deployment of Pools on Sonic✅

    Pools based on a new architecture—isolated pair pools—are being launched on Sonic. Previously, large multichain pools were used, combining up to 8 blockchains with synthetic derivatives. Now, each pool includes only the liquidity of one isolated blockchain and the hubchain – in this case, the liquid tokens of the Sonic blockchain.

    This approach enhances the system’s overall resilience and reduces imbalance risks. Individually, the pools will be less liquid, but the overall architecture will provide greater flexibility, resilience, and potentially higher returns for liquidity providers.

    Disclamer

    Attention!

    Curve pools are based on a specialized AMM formula for trading stablecoins with minimal slippage and stable prices. Differing from the standard AMM formula x * y = k, Curve applies a modification focusing on assets with similar prices, providing effective pricing and liquidity for closely correlated tokens. Pools are adapted to the market by adjusting the asset weights, allowing them to maintain stable exchange prices even with changing market volatility. Therefore, it is necessary to pay attention to the liquidity balance of each stablecoin in the Pool Details tab. Go to the original liquidity pool on Curve you are working with, and assess its balance. For example, let's consider the xCRVUSDC pool.

    The xCRVUSDC pool consists of six s-tokens, so the pool will be balanced if the share of each asset in the pool constitutes 100/6 = 16.6% of the total TVL of the pool.

    Gallery / Merge interface in the Arbitrum chain

    Merge interface description in the Arbitrum chain

    After successfully connecting your wallet in the «Gallery/Merge» tab, the gallery will show all the NFTs stored in the connected wallet, sorted by .

    For your convenience, use the NFT rarity filter to choose the rarity category you want to level up.

    Select the necessary number of NFTs for merging and rarity increase and click «Merge»:

    Team

    CrossCurve (ex EYWA) founders

    - CEO & Co-founder

    Boris Povar holds a degree in software technology and IT administration, and is a mathematician. Boris started to work in IT since 2009 and become a serial entrepreneur via launching his IT outsourcing company, and crypto start-ups. Boris has both great theoretical and practical experiences in mining, cloud mining, crypto trading, investing and crypto asset management. As an initial creator of the Blockchain Laboratory dedicated to researching the DeFi market, Boris comprises the complex deep knowledge and experience in DeFi and its corresponding matters.

    Technical Documentation for CrossCurve DAO Smart Contracts

    2. Whitelisting on Curve and Activation of CRV Incentives✅

    We are initiating a voting process in the Curve DAO to get whitelisted and connect the pools to protocol reward distribution. This will allow us to activate CRV incentives for our pools and increase yields for our liquidity providers. Since the voting takes about two weeks, we are starting the process in advance to launch reward distribution as quickly as possible after migrating our hubchain.

    3. Connecting Sonic Pools to Routing

    After deployment and basic setup, the Sonic pools will be connected to our routing system. At this stage, swaps through the new pools in Sonic will become available to CrossCurve users. To ensure a seamless transition, Sonic and Fantom pools will operate in parallel, allowing liquidity to flow between them without interrupting system functionality.

    4. Activation of CrossCurve DAO Incentives on New Pools✅

    After launching the pools and connecting them to the infrastructure, we will activate incentives from CrossCurve DAO – our first step in attracting liquidity to the new Sonic pools. External projects will be able to offer rewards to CrossCurve DAO participants in exchange for votes on specific liquidity pools, allowing users to start earning right away.

    5 Connecting Sonic Gems to Incentives on Fantom Pools✅

    As Sapphire-tier winners in the Sonic Boom program, we possess special airdrop points called Gems. These are distributed among applications based on product metrics and activity. We will direct all of them toward incentivizing liquidity in our pools in the form of the cmGEMS1 token, using it as a reward distribution mechanism within the protocol.


    WE ARE HERE


    6. Disabling Incentives on Fantom Pools

    As incentives are activated on Sonic pools, they will simultaneously be disabled on Fantom. However, CRV rewards will continue to be distributed for some time after deactivation due to the mechanics of Curve.

    7. Disconnecting Fantom Pools from Routing

    After most of the liquidity has been migrated to Sonic, Fantom pools will be disconnected from the routing system. Swaps through them will no longer be possible; the pools will remain accessible for withdrawals only. It is especially important for CrossCurve users to move their assets before this stage to avoid high slippage, as the majority of liquidity will have already been relocated.

    8. Connecting Sonic Points and Rings to New Pools

    At this stage, the pools will start generating Sonic Points and Rings, allowing liquidity providers to participate in additional reward programs, including all future airdrops. Thanks to the new pool architecture, half of the liquidity will be concentrated in Sonic blockchain assets, enabling our users to earn even more incentives

    9. Activation of $EYWA and $CRV Rewards via Votemarket

    After completing the Curve vote and configuring campaigns on Votemarket, we will activate the reward distribution in $EYWA and $CRV tokens – thus completing the migration of our hubchain to Sonic and fully launching most of the economic incentives in the new pools.

    Faraj Abutalibov - CBDO, Co-founder

    15 years experience in BD, VC & Corporate. Harvard Business School Executive Education. MBA from WBS (UK). Founder of the Crypto Executives community (2000+ c-level executives).

    Team

    Our team consists of 35+ members.

    Location

    We work remotely. The founders live in Turkey and UAE. The CrossCurve team is distributed all over the world: Turkey, UAE, Ukraine, Mexico, Russia, Israel, Latvia and etc.

    Boris Povar
    CalldataHelperV1
    DelegationManagerV1
    DelegationConditionValidatorV1
    EmissionManagerV1
    EscrowManager
    EscrowVoteManagerV1
    GaugeFactoryV1
    GaugeV1
    IncentiveRewardsDistributor
    LockHolderFactoryV1
    LockHolderV1
    ProposalManager
    RebaseRewardsDistributorV1
    RewardsDistributorFactoryV1
    Treasury
    Curve.finance
    Deposit
    Withdraw
    Balanced
    Easy mode

    Liquidity provision use cases

    Liquidity provision on CrossCurve offers the chance to contribute to the market stability of cross-chain assets. By staking tokens in liquidity pools like EYWAUSDT or CrossCurve frxUSD, providers earn trading fees from swaps occurring within the pool. This process not only provides a potential income stream through fees and rewards but also plays a crucial role in facilitating smooth cross-chain transactions.

    Savvy investors can leverage CrossCurve's advanced AMM algorithms to balance risk and return, optimizing their positions in a multi-token ecosystem. Always consider the associated risks and conduct due diligence before participating.

    👇 Learn how to deposit and withdraw liquidity from CrossCurve pools in the sections below. Use the sidebar for easy navigation between sections.

    DepositWithdrawCurve Knowledge Database

    Locking EYWA provides you with the following benefits:

    • Staking income

    • Voting rights and participation in DAO decision-making

    • Incentive earnings when voting for pools

    • Increased rewards for providing liquidity

    • A share of the platform’s fee revenue


    Locking EYWA (veEYWA)

    veEYWA stands for vote-escrowed EYWA. Users can lock their EYWA tokens for a maximum of 3 years, in exchange for veEYWA. The amount of veEYWA decreases linearly as the chosen lock duration elapses. veEYWA cannot be transferred directly, but can be transferred within an EYWA DAO NFT. The longer you lock, the more veEYWA you receive. For details, please see the lock formula, but the simple explanation is:

    • 1 EYWA, locked for 3 years = 1 veEYWA

    • 1 EYWA, locked for 2 years = 0.66(6) veEYWA

    • 1 EYWA, locked for 1.5 years = 0.5 veEYWA

    • 1 EYWA, locked for 1 year = 0.33(3) veEYWA

    The longer you lock your EYWA, the greater your voting power (expressed in veEYWA) and the higher the boost you can achieve.


    NFT Boosts

    Owning an EYWA NFT can affect the amount of veEYWA you receive and, therefore, your voting power. An NFT’s rarity is determined by two parameters - MV (multiplier for veEYWA), a multiplier applied to the veEYWA you receive; as well as CT (Capacity per NFT), the maximum number of EYWA tokens affected by the NFT’s influence. Check the table below for the characteristics of each rarity level:

    Rarity
    Multiplier for veEYWA (MV)
    Capacity per NFT (CT)

    common

    1.006

    500

    uncommon

    1.036

    3 000

    rare

    1.3

    25 000

    legendary

    2.8

    EYWA NFTs enhance your DAO voting power, increase returns from staking, incentives, and fees, and allow trading of locked tokens. They also attract investors due to their rarity and functionality.

    Here are some ways EYWA tokens benefit different types of users:

    For veEYWA holders - those who have locked their tokens to gain voting power:

    • Boosts voting power when making DAO decisions

    • Boosts the voting power that can be exchanged for incentives (to distribute EYWA inflation across CrossCurve pool gauges)

    • Boosts staking income for veEYWA holders

    • Boosts the voting power used for distributing $EYWA in CrossCurve pools

    • Boosts income from distributing the protocol’s fee revenue among veEYWA holders


    Staking Income

    Staking income is the reward for long-term holding and locking of EYWA tokens. The longer and larger the locked amount, the higher your staking rewards, which are credited at the end of each epoch.

    Also, staking yield depends on the total volume of locked EYWA: the more tokens locked, the lower the yield.

    You can view the detailed calculations at the following link.

    Using EYWA DAO NFT further increases your staking earnings.


    Voting Rights and DAO Decision-Making

    CrossCurve DAO functions include:

    1. Managing protocol contracts: bridges, new networks, contract deployments, fees, and permissions.

    2. Managing the DAO treasury: inflation (amount and rate), incentives for community development, expenses to attract customers and partners, emission to bonds, gauges, and grants.

    All of these functions are carried out through voting.

    CrossCurve DAO voting is divided into three main categories. Core voting affects the calculation of the voting coefficient for distributing staking rewards.

    Core voting addresses:

    • Changes/additions to DAO, CrossCurve, and EYWA functionality;

    • Incentives;

    • Inflation and directives;

    • Bonds;

    • Grants;

    • Gauges.

    Other voting topics:

    • Incentive proposals;

    • Incentive directions;

    • Gauge listings.

    Miscellaneous votings:

    Votings not included in the categories above.


    Increased Rewards for Providing Liquidity (up to x2.5)

    CrossCurve DAO allows certain pools to receive additional rewards from $EYWA token emissions.

    When $EYWA emissions are allocated to a pool, the interface displays a range of possible APR that users can earn by staking their LP position.

    The final APR boost depends on the user’s voting power (formed by locking veEYWA) and the ratio of your liquidity to the total liquidity, taking into account other participants’ boosts in a specific pool. A maximum boost can increase your yield by up to 2.5 times.

    Thus, holding veEYWA allows you to achieve higher returns when providing liquidity. Using EYWA DAO NFT further increases your yield boost in these pools.


    Voting for Pools and Receiving Incentives (Bribes)

    Locking EYWA tokens provides unique opportunities for additional income through receiving incentives for voting on certain pools. By voting, veEYWA holders determine the distribution of liquidity and rewards among CrossCurve pools. Projects seeking to attract liquidity offer veEYWA holders incentives (various tokens) in exchange for votes in their favor.

    Locking EYWA turns voting rights into a source of income: veEYWA holders choose the most profitable offers and receive rewards in tokens, cryptocurrencies, or other forms of income from the projects. The higher your veEYWA balance, the more profit opportunities you have.

    Using EYWA DAO NFT further increases your earnings when voting for pools.

  • On the pool page, connect your wallet to the site by clicking on "Connect Wallet".

  • 3. Choose the installed wallet (or use Wallet Connect) and confirm the connection, making sure you are on the original page https://curve.finance.

    4. On the pool page, interaction happens through the application highlighted in the screenshot; look for the Deposit tab.

    5. In the Pool Details tab, pay attention to which tokens (DAI.e, USDC.e, and USDT.e stablecoins) are part of the pool.

    The avDAI/avUSDC/avUSDT pool consists of three stablecoins; accordingly, the pool will be balanced if the share of each asset in the pool constitutes 100/3 = 33.3% of the total TVL of the pool. (more details here)

    6. We will demonstrate a balanced method of adding liquidity to the pool – you can use multiple assets so that your operation brings the pool into a balanced state. This method should be applied to avoid penalties and earn additional profit from Curve in cases where you work with large amounts relative to the total TVL of the pool, or when the pool is close to perfect balance.

    For balanced funding, in the Deposit tab, select "Add all coins in a balanced proportion" and the system will automatically distribute them in equal proportion. Indicating the amount, confirm spending (click on Approve Spending). In the Edit tab, you can edit the amount of funds available for spending (by default – unlimited)

    7. After successful confirmation, you will see a green button labeled Spending Approved. Then, click on Deposit. After confirming the transaction, you will see a green Deposit Complete button, and the balance of av3CRV LP tokens will be displayed in the Your Details tab.

    address
    list
    link
    ).

    Go to Transaction History and click Details next to the interrupted transaction.

    To continue a transaction that failed due to a slippage error, click Continue operation.

    After clicking the Continue operation button, the application will switch to the Continue operation mode. The difference between the Continue operation mode and Normal mode is that in the Continue operation mode, the User will be sent native tokens (if the User’s wallet doesn’t have the chain’s native token for completing the transaction) to pay the gas fee for continuing the transaction in the chain where the interruption occurred.

    After pressing the button, the user will be taken to the Swap interface with preselected assets:

    In the top FROM field, the "intermediate" tokens that were credited to the user's wallet on the network where the operation was interrupted will be selected.

    In the bottom TO field, the desired asset that the user initially wanted to receive but the operation was interrupted will be selected.

    Sequence of actions in the Continue operation mode window:

    • Review transaction details such as Slippage and exchange rate in the dropdown menu.

    • Give permission for the application to interact with the asset

    • Sign transaction.

    If a User changes values in the Source field, the application will switch to the standard Swap mode and no native asset will be transferred to the user's account to pay for the gas.

    Total Slippage is the total effective slippage applied across all networks where a swap occurred during a cross-chain transaction.

    It is calculated as the sum of slippage percentages for each individual network involved in the transaction (details here).

    The user will have one free attempt to continue the transaction with new fees and Slippage conditions. If for some reason you can not continue the operation, сontact support on Telegram / Discord and our support team will help you.

    here

    After specifying the LP amount, click Approve EYWAUSDT and confirm spending of LP tokens by singing the transaction in your wallet.

    Then click Stake, and sign the transaction in your wallet.

    After the transaction is successfully completed, the balance of staked LP tokens will be displayed on the page of the pool where you locked the funds in the Staked section.

    Unstaking LP Tokens

    Unstake LP tokens by clicking Unstake.

    After specifying the LP amount click Unstake and sign the transaction in the wallet.

    Receiving rewards

    For farming rewards in EYWA and CRV simultaneously, click Claim in all pools

    Confirm the transaction in Your wallet.

    Also you can go to the Merkl dashboard by clicking the link and claim the rewards manually

    After successfully connecting your wallet, go to the Claim section and follow the instructions on the Merkl website.

  • If you add one asset to the pool, the share of which is less than 16.6%, you will receive an additional bonus for balancing the pool.

    1. If you add one asset to the pool, the share of which is greater than 16.6%, you will receive a penalty in the form of slippage because this operation worsens the pool balance.

    1. If you withdraw one asset from the pool, the share of which is less than 16.6%, you will receive a penalty in the form of slippage because this operation worsens the pool balance.

    1. If you withdraw one asset from the pool, the share of which is greater than 16.6%, you will receive a bonus because this operation balances the pool.

    1. It should be noted that this example is not a financial strategy, and the imbalanced Easy mode is not always profitable (for example, if the pool is balanced) and also depends on the liquidity volume you are working with: the higher your volume relative to the total TVL of the pool, the more likely it is that the imbalanced method will be disadvantageous and you should use the Balanced mode. To avoid high losses of funds, always consider these factors and the condition of the pool before making a decision about the operation.

    Here is an example, how the volume of liquidity you work with can affect the final result when performing the operation.

    Note: The EYWA tokens attached to the NFT were detached from it during bridging. You can see their quantity in the Dashboard tab.

    Then, select a new image for the resulting NFT and click «Accept merge»:

    After selecting the new image, you will see information about the NFTs you’re merging and the total number of EYWA contained within them. To merge them, click «Merge» and confirm in the wallet:

    After the successful merge, you will get a notification along with a link to the hash of the transaction:

    rarity

    Voting

    Voting on Emission and Incentive Parameters

    Every three months (every 12 epochs), the project may initiate a vote to change the parameters of token emission distribution from the CrossCurve Treasure.

    During this voting, the following parameters are determined:

    1. The amount of emission per epoch: the total number of EYWA tokens allocated for the project’s development.

    2. The percentage allocated to pool rewards (Pools incentives).

    3. The percentage allocated to bond creation (Bonds incentives).

    4. The percentage allocated to grants (Grants incentives).

    5. The percentage allocated to attract external rewards to project pools (Bribes incentives).


    Voting Conditions and Restrictions

    Voting frequency: Once a voting is initiated, the next one can only occur after three months.

    Parameters for voting: All five parameters must be proposed for the voting:

    1. Emission amount per epoch.

    2. % for Pool incentives.

    3. % for Bond incentives.

    4. % for Grant incentives.

    Restrictions:

    • The sum of percentages for parameters 2-5 must total exactly 100%.

    • The emission per epoch cannot exceed the average emission since the DAO’s launch by more than 25%.

    • Reducing emission is not restricted and can be lowered to 0, if DAO participants support it.


    Initial DAO Parameters

    • Emission per epoch: 1 262 295 EYWA tokens.

      • 38% — Pool incentives.

      • 25% — Bond incentives.


    Emission Distribution Algorithm per Epoch

    1. Determining the total emission volume A certain emission amount E is allocated from the EYWA Treasure (for example, the initial 1 262 295 EYWA tokens or another value approved by the DAO).

    2. Calculating staking rewards: The amount of staking rewards S is calculated.

    3. Calculating token volumes for incentives After deducting the staking rewards, the remaining amount is distributed as follows:

    Note:

    • The sum of , ,and coefficients must be 100%.


    Voting for Pools

    All veEYWA holders can participate in weekly (every epoch) voting to distribute Pool incentives among the pools.

    What are Pool incentives?

    Pool incentives are EYWA tokens, allocated from the CrossCurve Treasury each epoch to attract liquidity providers to the project. DAO participants vote on how this amount is distributed among the pools.

    Benefit for Liquidity Providers

    The more votes directed to a pool where a provider’s liquidity is located, the higher their reward in the next epoch.

    List of Eligible Pools

    Only those pools connected to the CrossCurve project are eligible for Pool incentives distribution:

    1. Pools created by the project before the DAO launch.

    2. Pools added via a DAO vote.

    • Any DAO participant can initiate a vote to add a new pool.

    • To include a pool in the list, the proposal must receive more than 50% of the DAO votes.

    Voting Procedure

    Voting takes place on a separate page in the DAO section. To participate, a user must:

    1. Distribute all 100% of their votes among the available pools.

    2. Press the "Vote" button to confirm their voting choice.

    Before the end of the current epoch, a user can cancel their votes and vote again.


    Incentive Distribution Scheme Based on Voting Results

    1. Vote Counting Process:

    At the start of a new epoch, all veEYWA votes cast for pools in the previous epoch are counted. The percentages allocated by participants are converted into a specific number of EYWA tokens directed to each pool.

    1. Formula for Incentive Distribution:

    where:

    — the number of EYWA tokens allocated to pool X.

    — the total EYWA token amount allocated to all pools in the current epoch

    — the amount of veEYWA votes cast for pool X.

    — the amount of veEYWA votes cast for pool i out of all n pools

    Thus, the number of EYWA tokens allocated to a pool depends on the proportion of veEYWA votes that pool received relative to all votes.


    Reward Distribution to Liquidity Providers

    At this stage, all incentives allocated each epoch to attract liquidity providers to the project’s pools are distributed via service.

    Funds Flow Scheme:

    CrossCurve Treasure → Pools incentives → Gauge → Angle Merkl → Liquidity Providers

    Liquidity providers can claim their rewards:

    • Through the project’s pool interface.

    • Through the service interface.


    Boosting Liquidity Provider Income for DAO Participants

    If a liquidity provider is also a DAO participant, they receive increased rewards through a boost coefficient B.

    Boost Coefficient Formula:

    where:

    — the user’s boost coefficient (cannot exceed 2.5)

    D — the total sum of all deposits in the pool (in USD)

    d — the user’s deposit amount in the pool (USD).

    V — the total veEYWA of all users.

    v — the user’s veEYWA amount.

    Calculating the User’s Reward:

    A maximum boost of B=2.5 does not mean the reward is simply increased by 2.5 times. The total is divided among all liquidity providers taking into account their individual boost coefficient B.

    User Reward Formula:

    Where:

    — the user’s reward

    — the total amount of tokens allocated as liquidity rewards

    — the user’s boost coefficient

    — the user’s deposit size (USD).

    — the boost coefficient of user i.

    — the deposit size of user i (USD).

    Restrictions:

    • Maximum boost coefficient: 2.5.

    • Rewards are distributed proportionally, taking into account each user’s deposit and boost coefficient.

    This system incentivizes DAO participants to provide liquidity, increasing their returns thanks to holding veEYWA.

    Staking in CrossCurve

    Staking is the simplest way to earn passive income in CrossCurve. All you need to do is lock EYWA tokens (instructions available here), which automatically makes you a member of our DAO and enables you to receive rewards every epoch. You can boost your earnings through additional mechanics like longer lock durations, using NFTs, and participating in votes.

    How does staking work in CrossCurve?

    Each epoch, a portion of EYWA tokens from the DAO Treasury is allocated to incentivize protocol activity. Most of these tokens go to rewarding DAO participants.

    To receive these rewards, you must lock EYWA tokens in the DAO Locker. Once locked, you receive an NFT that records your voting power — veEYWA. The more veEYWA you hold, the larger your share of the rewards.

    Each epoch runs from Thursday 00:00 UTC to Wednesday 24:00 UTC. At the start of each new epoch, rewards from the previous one are .


    How to maximize your APR?

    Formulas:

    • veEYWA = ((EYWA amount × lock period in weeks) ÷ 156

    • User share = your veEYWA ÷ total veEYWA in DAO

    • Reward = User share × total reward pool (EYWA)

    • Weekly Return Rate (WRR) = Reward ÷ locked EYWA amount

    For example, if you lock 156 EYWA for 1 week, then you will get:

    • 1 veEYWA

    If total veEYWA in the DAO is 1 000, and the reward pool is 1 000 EYWA, then your reward is:

    • 0.1% of the pool = 1 EYWA

    Weekly return rate (WRR): 0.64%

    Your income depends directly on your share of veEYWA. To increase it, you can:

    1. Lock more EYWA tokens

    2. Extend your lock duration

    3. Use EYWA NFT with a

    These methods can be combined. Here are strategy examples:

    1. Increasing EYWA amount

    Locking 1560 EYWA for 1 week will get you:

    • 10 veEYWA (10 times more)

    If total veEYWA in DAO is 1009, then your share is:

    • 0.99% of the pool = 9.9 EYWA (9.9 times more)

    • Weekly return rate (WRR): 0.63% (almost no change)

    Increasing the amount boosts total rewards, but return per token remains almost the same.

    2. Increasing lock duration

    Locking 156 EYWA for 3 years (156 weeks) will get you:

    • 156 veEYWA (156 times more than when locking for 1 week)

    If total veEYWA in DAO is 1 155, and the reward pool equals to 1 000 EYWA, then your share is:

    • 13.5% of the pool = 135 EYWA (135 times more)

    • Weekly return rate (WRR): 86.5% (135 times higher)

    Locking for a longer period significantly boosts both rewards and returns — the most efficient strategy without extra spending.

    3. Using NFT with x3 multiplier

    Locking 156 EYWA for 1 week and using NFT with the x3 multiplier will get you:

    • 3 veEYWA (3 times more than without an NFT)

    If total veEYWA in DAO is 1002, and the reward pool equals to 1 000 EYWA, then your share is:

    • 0.29% of the pool = 2.9 EYWA (2.9 times more)

    • Weekly return rate (WRR): 1.9% (approximately 3 times higher)

    NFTs give an instant boost — same amount and duration, but 3x higher veEYWA and rewards. This is a great option to multiply your profits.

    4. Combined strategy: increasing lock duration + utilizing NFTs

    Locking 156 EYWA for 156 weeks and applying NFT x3 will get you:

    • 468 veEYWA (468 times more)

    If total veEYWA in DAO is 1467, and the reward pool equals to 1 000 EYWA, then your share is:

    • 31.9% of the pool = 319 EYWA (319 times more)

    Weekly return rate (WRR): 204.5% (319 times higher)

    Combining max lock duration and NFT multiplier creates a compounding effect, giving a 468x increase in veEYWA compared to the base case. This leads to significant return and relative profit growth.

    Note: All values are illustrative. Actual results depend on total veEYWA distribution across participants. However, the core logic of these calculations remains accurate.

    How other participants affect your APR

    In addition to the steps you can take to maximize your APR, it’s important to consider “external” conditions. In the section “How to increase staking income,” we looked at examples where the veEYWA volume of other DAO participants was static. But in reality, this figure is constantly changing. One important point: how other participants lock their EYWA also affects your final yield.

    Reward distribution specifics depending on veEYWA amounts

    Let’s consider a few simple scenarios with two DAO participants. Suppose that in the previous epoch, only two users participated in the DAO:

    Scenario 1: both locked 75 000 EYWA for the maximum term (3 years)

    • veEYWA of participant A = 75 000

    • veEYWA of participant B = 75 000

    • Total veEYWA = 150 000

    • Shares are equal — both participants receive 50% of the rewards

    Scenario 2: both have 75 000 EYWA, but:

    • Participant A locks for 3 years → 75 000 veEYWA

    • Participant B locks for 1 year → 25 000 veEYWA

    • Total veEYWA = 100 000

    • Participant A receives 75% of all rewards

    Based on the the total reward pool for the week (epoch) is 13 190.73 EYWA, therefore:

    • Reward A: (75 000 / 100 000) × 13 190.73 = 9 892.5 EYWA

    • Reward B: (25 000 / 100 000) × 13 190.73 = 3 297.5 EYWA

    Weekly Return Rate (WRR):

    • WRR A = (9 892.5 ÷ 75 000) × 100% = 13.19%

    • WRR B = (3 297.5 ÷ 75 000) × 100% = 4.37%

    APY calculation:

    • APY A = ((1 + 13.19% ÷ 100%)^52 – 1) × 100% ≈ 62 700%

    • APY B = ((1 + 4.37% ÷ 100%)^52 – 1) × 100% ≈ 824%


    “Compound” button and APY

    To receive staking rewards each epoch, you must press the “Compound” button. This action adds the accrued reward to the lock amount.

    Increasing the lock amount raises your veEYWA share and, accordingly, your reward in the next epoch. The yield displayed on the locker page (APY) is shown assuming regular use of Compound — based on the principle of bank compound interest.

    If you do not press Compound, your yield will be lower than what is shown in the interface. Therefore, to earn income that matches the displayed APY, you must manually add the reward to the lock each epoch.


    How to maximize earnings

    1. Lock EYWA for the maximum term

    2. Use NFTs with a high multiplier

    3. Press “Compound” each epoch

    4. Participate in incentive voting


    Conclusion

    Staking in CrossCurve is more than just passive income. It includes many mechanics that allow you to earn returns far beyond traditional staking.

    You’re not just earning — you’re helping shape the CrossCurve ecosystem and receiving real rewards for it.

    CrossCurve MetaPoints Program

    As part of Sonic’s Airdrop Season 2, CrossCurve has launched the CrossCurve MetaPoints program to reward active users of CrossCurve.

    Rules

    Participants:

    • Users who provide liquidity to participating pools* in the Farms tab by staking LP tokens in the CrossCurve app

    • Users swapping cross-chain via the Trade interface (as long the the swap’s route passes through the )

    Rewards:

    Participants receive MetaPoints. Also, their activity helps CrossCurve receive more , which will be swapped to $S tokens at the end of . All of the received $S tokens will be distributed among all the participants who got enough MetaPoints to receive at least one $S

    Rule subject to change on Sonic’s end as they publish the final algorithm of point accrual

    Pool marking:

    Pools participating* in the MetaPoints program will be marked with a special symbol .

    Point accrual mechanics for liquidity providers

    • Only the specially marked pools in Farms are included

    • Points accrue only for the volume of in the LP:

    ○ E.g., if the LP token only has 40% of its TVL is in s-tokens, then only this 40% counts towards accrual, not the other 60%.

    • Accrual formula:

    ○ 1 point = 1$ s-token left in the pool for 1 day

    • Accrual frequency:

    ○ daily at 00:00 UTC

    • Each pool could have an individual multiplier that increases or decreases the total amount of accrued points.

    Accrual mechanics for users moving liquidity

    • Only cross-chain swaps receive points (as long as the route passes through the ).

    • Swaps below $10 do not count.

    • Users get 100 MetaPoints for every $10 swapped

    Integration

    • Users can find MetaPoint accrual information on the Leaderboard in each relevant tab:

    - My MetaPoints — total MetaPoints earned by the connected wallet

    - In Farms — total MetaPoints earned by staking in Farms

    - In Swaps — total MetaPoints earned for cross-chain swaps in Trade

    - Total MetaPoints — total amount of MetaPoints earned by all the participants of the CrossCurve MetaPoints program

    • In the “Frams” LP staking interface, participating pools will have the icon next to them, alongside the point multiplier.

    • In the “Trade” interface, the expected point value of the swap will be reflected alongside points from .


    FAQ

    1. How do I earn $S tokens Swap on CrossCurve or provide liquidity to CrossCurve pools

    2. Which pools are participating in this program? Only the selected pools marked by the program’s icon in the interface

    3. Does my entire staking position accrue points? No, only the part reflecting the % of in the pool

    4. How is the value of the LP token determined? In USD based on the average daily value

    5. How frequently do the LP points accrue? Daily

    6. What can I do with MetaPoints? At the end of the , they will be converted into $S tokens

    Slippage settings

    Slippage is the price change caused by external market movements and not related to the user's operation within the pool. Slippage strongly depends on the liquidity volume inside the pool. If a token pool has low liquidity, significant changes in the exchange rate within the pool require less market movement.

    In the settings, you can specify slippage (by default, the parameter is set at 0.5%) Slippage is a change in price caused by external market movements and not related to the user's activity in the pool. Slippage highly depends on the liquidity volume inside the pool. If a token pool has low liquidity, significant rate changes within the pool require less market movement.

    CrossCurve users can configure the maximum permissible slippage for cross-chain operation:

    You can always see the exact total value in Routing details → Total slippage.

    When you set a slippage tolerance in the app, this value is treated as the maximum slippage for the entire route.

    Allocation rules:

    ● Stable pools always receive max / 10.

    ○ Example: if max = 1%, each first stable pool in a chain gets 0.1%.

    ○ Only the first stable pool in each chain applies slippage.

    ● Crypto pools receive the remaining slippage.

    ○ The remainder is evenly distributed across all chains that contain crypto pools.

    ○ Only the first crypto pool in each chain applies slippage.

    ● Other swaps in the same chain receive 0%.

    ● Therefore, total slippage ≤ your chosen max.

    Total Slippage is the total effective slippage applied across all networks where a swap occurs during a cross-chain transaction.

    It is calculated as the sum of slippage percentages for each individual network involved in the transaction.

    Slippage Allocation Examples (Max = 1%)

    You can find the rules for distributing slippage in the table below:

    Route (per chain)
    Allocation (per pool)
    Total Slippage

    Note: Only the first pool in each chain receives slippage. Stable pools always = max/10; the rest is evenly split across crypto pools.

    Change the slippage parameter only if you clearly understand why you are doing it.

    If you set the value too low, you will receive a warning and your transaction may fail due to low slippage:

    If you have set a value that is too high (e.g. 1%), which significantly exceeds the recommended value of 0.5%, the transaction may be executed at an unfavorable rate due to frontrun:

    Easy mode

    In Easy mode the application allows you to unbalancely add (Deposit) or withdraw (Withdraw) funds into the Curve liquidity pool with a single asset (assets that are part of the LP token or the LP tokens themselves), saving time by performing complex operations (without interacting with the Curve interface) in one click.

    Note that this method is not always advantageous due to the architecture features of Curve.

    1. After selecting the necessary operation (Deposit or Withdraw) in Easy mode and clicking next (Next),

    choose the network (different networks available in the CrossCurve pools, depending on the pool selected. For our example, these are: Polygon, BNB Chain, Arbitrum, Optimism, Ethereum, Base, Avalanche, and Gnosis for the xSTABLE pool.) and the token you need.

    1. After entering the desired amount of tokens, the system will calculate the number of LP tokens received and the gas fee. By clicking Routing details, Routing will be displayed - this interface provides a convenient graphical representation of the cross-network transaction, showing all associated transitions and fees step by step.

    1. Slippage Settings. In the settings, you can specify slippage (by default, the parameter is set at 0.5%)

    1. The first transaction requires allowing the USD₮0 spending by clicking «Approve USD₮0» and signing the transaction in the wallet. To sign the transaction, you must hold the native token of the network in which the transaction is being made to pay for the gas.

    1. After confirming the spending of USD₮0, a “Swap” button will appear. By pressing the "Swap" button, a request will be sent to the wallet to confirm the transaction

    1. For convenience, a quick link to add the token to the wallet via the contract address has been added for correct balance display. By clicking on the “+”, a request will pop up to add a custom token. After signing, it will be displayed in the wallet.

    There is also a method of adding liquidity to the pool – you can use multiple assets so that your operation brings the pool into a balanced state.

    should be applied to avoid losses/earn profit in cases where you work with large amounts relative to the total TVL of the pool, or when the pool is close to perfect balance.

    via Curve (Balanced)

    In Balanced mode the application allows adding liquidity (Deposit) in s-tokens or withdrawing (Withdraw) funds from s-tokens to the original assets of the EYWAUSDT, xCRV, xCRV2, CRV/USD, 3UNIT0, wFTMUSDC, CrossCurve frxUSD, CrossCurve frxETH, xsStable, xeWETH and xbBTC pools, CrossCurve liquidity pools with a single asset (assets that are part of the LP token or the LP tokens themselves), performing complex operations in one click.

    However, it requires working with pools on Curve.

    Part I Adding Liquidity

    1. After successfully connecting, in the Choose pool window, select the pool or asset you are interested in for working with liquidity.

    1. Next, select the operation to deposit (Deposit) and the Balanced method of execution.

    Proceeding further by pressing Next, a step-by-step mini-guide will appear:

    • Check the liquidity pool on Curve to find the most profitable strategy

    • Obtain the necessary s-tokens here on CrossCurve

    • Deposit liquidity in a balanced way and earn additional income on Curve

    1. Follow the .

    Part II Withdrawing Liquidity

    1. After successfully connecting, in the Choose pool window, select the pool or asset you are interested in for working with liquidity.

    1. Next, choose the withdrawal (Withdraw) operation and the Balanced option.

    Proceeding further by clicking Next, a step-by-step mini-guide will appear:

    • Check the liquidity pool on Curve to find the most profitable strategy

    • Withdraw liquidity in a balanced manner and earn additional income on Curve

    • Convert s-tokens into original assets in this window

    1. Follow the .

    APR Calculator

    To get started with the CrossCurve app. navigate to the APR calculator page in the Yield section. Click Connect wallet, select the appropriate wallet from the list, and confirm the connection, ensuring you are on the official page: https://app.crosscurve.fi/farm?&calculator=1.

    After successfully connecting to the wallet, select the desired pool from the list.

    The application will display information about the selected pool:

    Your vAPR - total APR in the pool including the boost

    Pool TVL - The total value locked in the pool

    Total veEYWA - The total amount of veEYWA

    To calculate the required amount of tokens for obtaining a boost, enter the desired amount of LP tokens for locking in the selected pool in the Your deposit field and adjust the slider to the desired boost level. The Your vAPR line will calculate the obtained with the selected boost.

    After entering the amount of LP tokens to be locked and the desired boost, the application will calculate the required amount of tokens to achieve the boost and the desired

    Your vAPR - The projected with the selected boost

    You have - The balance in the connected wallet

    Need for boost -The required amount of to achieve the selected boost

    To obtain the necessary amount of tokens, use the by clicking Get veEYWA for BOOST.

    Gallery / Bridge interface in the Aurora chain

    Bridge interface description in the Aurora chain

    To interact with the bridge in the CrossCurve app, go to the NFT section and select the «Gallery / Bridge» tab. Click «Connect wallet», select the right wallet from the list, and confirm the connection. Make sure that you’re on the official CrossCurve page: https://app.crosscurve.fi/nft-bridge.

    After successfully connecting the wallet in the «Bridge» tab, you will see all the available NFTs in your wallet, their level of rarity, and the number of EYWA tokens within the containers.

    In the top right corner, you can toggle between list and icon view options:

    To migrate them to the Arbitrum chain, select up to 20 NFTs* and click «Bridge»:

    * During peak hours, the Aurora network can be unstable: if you can't transfer 20 NFTs, try transferring 10 to 15 NFTs in a single transaction or try again.

    In the first transaction, confirm migrating the NFTs by clicking «Approve selected NFTs»:

    Then, to migrate them into Arbitrum, click «Bridge» and confirm in the wallet:

    After it’s confirmed on-chain, you will receive a notification about the successful bridging of your NFTs to Arbitrum:

    NOTE: After migrating your NFTs to , their copies on will be burned.

    Don’t worry — all your EYWA tokens contained in those NFTs will be detached and merged if bridging multiple NFTs at once. You can always check your balance in the “.”

    After the TGE, tokens will be claimable in the Claim Portal and can again be placed inside an NFT container if you so desire.

    EYWA NFT Collection

    Unique NFTs from Eywa!

    NFT collection description

    EYWA NFT Characters

    The Eywa NFT collection includes 53 996 unique NFTs. Their number diminishes as they are merged.

    The collection represents four mythical characters: Magician, Dryad, Ant, and Spider. EYWA NFTs are an example of generative art where each character features randomized attributes that grant it uniqueness.

    Dashboard interface

    Description of the Dashboard interface

    To get started with the CrossCurve app, visit the Dashboard page. Click Connect wallet, choose your preferred wallet from the list, and confirm the connection, making sure you are on the official page:

    Upon successfully connecting your wallet, the Dashboard page will display detailed information:

    Farms section

    Easy mode (Imbalanced)

    Adding Liquidity

    Example of using Easy mode for adding liquidity of the USD₮0 token into the xSTABLE LP token

    To start working in the CrossCurve application, go to the section. After successfully connecting your wallet, in the Choose pool window, select the xSTABLE pool. This mode allows you to exchange a single stablecoin into the liquidity token without interacting with the liquidity pool interface on Curve.

    Sonic Incentives on CrossCurve MetaLayer

    Introduction

    CrossCurve is launching Sonic with an updated pool architecture built on the principle of isolated connections: each network connects to a universal asset within Sonic.

    For example, the sxEthereum pool with the universal token xfrxUSD and the s-token с sUSDC_arb

    This not only enhances the system's resilience but also opens direct access to all key drop programs of the Sonic ecosystem.

    Early farming program interface

    To begin using the CrossCurve application, go to the Early Farming Program page in the Vesting section. Click «Connect wallet», select the appropriate wallet from the list, and confirm the connection, making sure you are on the official page:

    After successfully connecting your wallet, to display the rEYWA balance in your wallet, you must switch the network to Fantom by clicking Switch chain and confirming the network change in your wallet.

    Once connected to the Fantom network, the application will display the rEYWA token balance in your wallet. To exchange rEYWA for the Vesting safe with EYWA, you need to move your rEYWA tokens to the Arbitrum network by clicking Bridge rEYWA to Arbitrum and singing the transaction in your wallet.

    CrossCurve SuperDVN

    Overview

    CrossCurve SuperDVN is a verification module (DVN, Decentralized Verification Network) compatible with the LayerZero . It leverages the CrossCurve Consensus Bridge as its internal mechanism for cross-chain message verification and transmission.

    SuperDVN serves as a sovereign data verification layer for cross-chain applications, providing a decentralized, secure, and resilient environment for communication between blockchains.

    Easy mode (Imbalanced)

    Withdrawing Liquidity

    Example of using Easy mode for withdrawing liquidity of the EUSD LP token into the USDT stablecoin

    To start working in the CrossCurve application, go to the section. After successfully connecting your wallet, in the Choose pool window, select the EUSD pool. This mode allows you to exchange the liquidity token into a single stablecoin without interacting with the liquidity pool interface on Curve.

    via Curve (Balanced)

    Withdrawing Liquidity

    Step 1. Go to on Curve and analyze the optimal way to withdraw funds from the pool:

    A balanced method of withdrawing liquidity from the pool is recommended – you will receive s-tokens in proportion from several assets so that your operation brings the pool into a balanced state.

    Step 2. After connecting the wallet, go to the Withdraw/Claim tab and use the Balanced mode. After entering the amount to be withdrawn, the AMM will distribute the s-tokens in proportion to the pool's balance from the total TVL.

    LockHolderFactoryV1

    Overview

    LockHolderFactoryV1 This is an upgradeable contract that deploys new LockHolder contracts on the blockchain. It is integrated with the DelegationManager contract.

    Key Roles and Features:

    1. Access Control: Restricts setAssuranceLockParameters and

    DelegationConditionValidatorV1

    Overview

    DelegationConditionValidatorV1 This is an upgradeable contract that allows you to set additional conditions for delegating locks. It is integrated with EscrowManager, which allows you to know the current status of the lock when delegating it.

    Key Roles and Features:

    1. Access Control: Restricts setAssuranceLockParameters

    Now, every CrossCurve user can earn three types of rewards just by interacting with the app.

    Currently, Sonic incentives are provided for all paired pools on Sonic and for the 3UNIT0 pool.

    Season 1

    Sonic Points — Rewards for Users

    This is the core drop mechanism from Sonic, focused on end users. Points are awarded for holding whitelisted assets and come in two types: passive (for storing assets in a wallet) and active (for using assets in third-party apps, such as CrossCurve), which earn double the passive rate.

    Thus, farming Sonic Points through CrossCurve is twice as profitable!

    The following assets offer different boosts:

    • scUSD — 6x

    • scETH, scBTC — 4x

    At the end of the drop, Sonic Points will be converted into NFT-safes, from which $S tokens will gradually unlock. All information is displayed in the dashboard: my.soniclabs.com/points

    For CrossCurve users, this means simply providing liquidity to CrossCurve pools — points are credited automatically, and they will enter the main phase of $S distribution.


    Sonic Gems (cmGEMS1) — Rewards for Applications

    This is a separate program for protocols and the second part of the Sonic drop. During the first season, 1 680 000 Gems will be distributed. 262 500 have already been pre-allocated to the winners of Sonic Boom. CrossCurve, as one of the winners in the Sapphire tier, has already received 8750 Gems. The remaining 1 417 500 Gems will be distributed based on user activity and multipliers. For CrossCurve as a bridge, a 5x multiplier applies.

    We’ve decided to tokenize these as cmGEMS1 and allocate 100% of these tokens as rewards to liquidity providers in the project’s pools.

    What is required from CrossCurve users? - Provide liquidity to the project’s isolated Sonic pools on Sonic - Rewards will be distributed through Merkl and will account for your veEYWA boost, if you have one. This can boost your yield up to 2.5x. The instructions to this particular step can be found here.

    But perhaps the main advantage of cmGEMS1, unlike Points, is that they can be directly exchanged for $S.


    Rings Points — Points from Token Issuer on Sonic

    Rings Protocol is the issuer of the stablecoins scUSD, scETH and scBTC, which are present in the Sonic pools on CrossCurve. The protocol has its own drop program — Rings Points, which are awarded automatically, similar to Sonic’s own.

    Like Gems, Rings Points can be directly exchanged for $S at the end of the season.


    Season 2

    Sonic Points — Rewards for Users

    This is the core drop mechanism from Sonic, focused on end users. Points are awarded for locking whitelisted assets in CrossCurve pools.

    The following assets offer different boosts:

    • scUSD — 6x

    • scETH, scBTC — 4x

    All information is displayed in the dashboard: my.soniclabs.com/points

    For CrossCurve users, this means simply providing liquidity to CrossCurve pools — points are credited automatically, and they will enter the second phase of $S distribution.


    Conclusion

    CrossCurve’s transition to Sonic is not just an upgrade, but a real expansion of economic opportunities for our liquidity providers. With the new pool architecture, almost every provider can receive triple incentive accrual - not counting CrossCurve’s own rewards.

    Sonic incentives apply to all paired pools in the Sonic network, as well as the UNIT0 pool.

    APY = 7 906%
    Participant B — 25%
    distributed
    veEYWA multiplier
    table
    Balanced
    This method
    step-by-step mini-guide
    step-by-step mini-guide
    Hubchain
    Sonic Gems
    Sonic’s airdrop season 2
    s-tokens
    Hubchain
    page
    Season 2 of Sonic’s airdrop
    s-tokens
    Sonic’s Airdrop Season 2
    later
    Arbitrum
    Aurora
    Dashboard

    Stable → Crypto

    0.1% → 0.9%

    1%

    Stable → Stable → Crypto (3 chains)

    0.1% → 0.1% → 0.8%

    1%

    Crypto → Crypto → Crypto (3 chains)

    0.33% → 0.33% → 0.33%

    1%

    Crypto → Crypto → Stable (3 chains)

    0.45% → 0.45% → 0.1%

    1%

    Stable → Crypto (2nd chain)

    0.1% → 0.9%

    1%

    Stable → Crypto → Stable (3 chains)

    0.1% → 0.8% → 0.1%

    1%

    Stable

    0.1%

    0.1%

    Crypto

    1%

    1%

    Stable, Stable (same chain)

    0.1% → 0%

    0.1%

    Stable → Stable (2 chains)

    0.1% → 0.1%

    0.2%

    250 000

    infinity

    3

    1 500 000

    setMinLockVeEywa
    calls to the
    owner
    of contract(
    owner()
    ).
  • Upgradeable via UUPS: Uses UUPSUpgradeable and OwnableUpgradeable patterns, restricting contract upgrades to the owner.


  • Inherited Contracts and Interfaces

    • UUPSUpgradeable (OpenZeppelin): Provides upgrade functionality under the UUPS proxy pattern, restricted to the contract owner.

    • OwnableUpgradeable (OpenZeppelin): Manages ownership, allowing only the owner to modify critical parameters and authorize upgrades.

    • ILockHolderFactoryV1: Defines core methods (e.g., createLockHolder) and events for this contract.

    Additional External References:

    • ERC1967Proxy (OpenZeppelin): A proxy implementation that stores the logic contract address in storage per EIP-1967.

    • LockHolderV1: LockHolder contract.


    State Variables

    • s_escrowManager (address) Address of the EscrowManager contract.

    • s_escrowVoteManager (address) Address of the EscrowVoteManager contract.

    • s_delegationManager (address) Address of the DelegationManager contract.

    • s_incentiveRewardsAggregator (address) Address of the IncentiveRewardsAggregator contract.


    Constructor

    • Description: Disables contract initializers to prevent re-initialization in a UUPS proxy context.


    External Functions (Defined by ILockHolderFactoryV1)

    initialize(...)

    Description: Configures ownership, references, and initial state:

    • References the EYWA NFT, escrow manager, escrow vote manager and delegation manager.

    Parameters:

    • owner_: The address of the contract owner.

    • escrowManager_: The address of the escrow manager contract.

    • escrowVoteManager_: The address of the escrow vote manager contract.

    • delegationManager_: The address of the delegation manager contract.

    • incentiveRewardsAggregator_: The address of the incentive rewards aggregator contract.


    createLockHolder()

    Description: The function deploys and initializes an upgradable LockHolder contract. Returns the address of the LockHolder contract.

    Checks:

    • sender must be a DelegationManager contract. Otherwise, UnauthorizedCaller() is thrown.

    Events:

    • Emits LockHolderCreated(m_lockHolder, m_implementation).


    Events

    • LockHolderCreated(address indexed lockHolder, address indexed implementation)) Emitted when a new LockHolder is created.


    Errors

    • UnauthorizedCaller() Thrown when the caller is not the delegation manager.


    Summary

    LockHolderFactoryV1 contract is an important part of the lock delegation architecture. It deploys a new LockHolder contract for each delegator-delegate pair, which provides the ability to reliably track the movement of delegated locks, manage them, and receive and distribute rewards.

    and
    setMinLockVeEywa
    calls to the
    owner
    of contract(
    owner()
    ).
  • Upgradeable via UUPS: Uses UUPSUpgradeable and OwnableUpgradeable patterns, restricting contract upgrades to the owner.


  • Inherited Contracts and Interfaces

    • UUPSUpgradeable (OpenZeppelin): Provides upgrade functionality under the UUPS proxy pattern, restricted to the contract owner.

    • OwnableUpgradeable (OpenZeppelin): Manages ownership, allowing only the owner to modify critical parameters and authorize upgrades.

    • IDelegationConditionValidatorV1: Defines core methods (e.g., validateDelegations) and events for this contract.

    Additional External References:

    • IDelegationManagerV1: Management of delegated locks

    • IEscrowManagerExtended: Holds locked token data and checks voting power and freeze logic.


    State Variables

    • s_escrowManager (IEscrowManagerExtended) IEscrowManager interface for the EscrowManager contract.

    • s_delegationManager (IDelegationManagerV1) IDelegationManagerV1 for the DelegationManager contract.


    Constructor

    • Description: Disables contract initializers to prevent re-initialization in a UUPS proxy context.


    External Functions (Defined by IDelegationConditionValidatorV1)

    initialize(...)

    Description: Configures ownership, references, and initial state:

    • References the escrow manager and delegation manager.

    Parameters:

    • owner_: The address of the contract owner.

    • escrowManager_: The IEscrowManager interface for the EscrowManager contract.

    • delegationManager_: The IDelegationManagerV1 for the DelegationManager contract.


    validateDelegations(address delegator_, address delegatee_, uint256[] calldata tokenIds_)

    Description: The function performs checks and determines whether delegation of tokenIds_ from delegator_ to delegatee_ is possible.

    Parameters:

    • delegator_: The address of the contract owner.

    • delegatee_: The IEscrowManager interface for the EscrowManager contract.

    • tokenIds_: The IDelegationManagerV1 for the DelegationManager contract.

    Checks:

    • sender must be a DelegationManager contract. Otherwise, UnauthorizedCaller() is thrown


    Errors

    • UnauthorizedCaller() Thrown when the caller is not authorized to perform the action.


    Summary

    DelegationConditionValidatorV1 Being updatable in the long run can provide the opportunity for varied and flexible customization for delegated locks.

    constructor() {
        _disableInitializers();
    }
    function initialize(
        address owner_, 
        address escrowManager_,
        address escrowVoteManager_,
        address delegationManager_,
        address incentiveRewardsAggregator_
    ) external initializer;
    function createLockHolder() external returns (address);
    constructor() {
        _disableInitializers();
    }
    function initialize(
        address owner_,
        IEscrowManagerExtended escrowManager_,
        IDelegationManagerV1 delegationManager_
    ) external initializer;
    function validateDelegations(
        address delegator_,
        address delegatee_,
        uint256[] calldata tokenIds_
    ) external view returns(bool);
    % for Bribe incentives.

    0% — Grant incentives.

  • 37% — Bribe incentives.

  • These parameters can be changed by DAO participants through voting.
    Poolsincentives=ratioPools∗(E−S)Pools_{incentives}=ratio_{Pools}∗(E−S)Poolsincentives​=ratioPools​∗(E−S)
    Bondsincentives=ratioBonds∗(E−S)Bonds_{incentives}=ratio_{Bonds}∗(E−S)Bondsincentives​=ratioBonds​∗(E−S)
    Grantsincentives=ratioGrants∗(E−S)Grants_{incentives}=ratio_{Grants}∗(E−S)Grantsincentives​=ratioGrants​∗(E−S)
    Bribesincentives=ratioBribes∗(E−S)Bribes_{incentives}=ratio_{Bribes}∗(E−S)Bribesincentives​=ratioBribes​∗(E−S)
    EpoolX=VpoolX∑i=1nVpooli∗PoolinsentivesE_{pool X} = \frac{V_{pool X}}{\sum^n_{i=1}V_{pool i}} * Pool_{insentives}EpoolX​=∑i=1n​Vpooli​VpoolX​​∗Poolinsentives​
    Buser=1.5∗D∗vd∗V+1B_{user} = 1.5 * \frac{D*v}{d*V} + 1Buser​=1.5∗d∗VD∗v​+1
    Rewarduser=Buser∗duser∑i=1nBi∗di∗RewardallReward_{user} = \frac{B_{user}*d_{user}}{\sum^n_{i=1}B_{i}*d_{i}}*Reward_{all}Rewarduser​=∑i=1n​Bi​∗di​Buser​∗duser​​∗Rewardall​
    Angle Merkl
    Angle Merkl
    Eywa NFT Characters

    The characters in the collection are unique creations, drawing inspiration from beloved science fiction universes.

    The Magician Crafted from leaves and various flora types, the magician is inspired by the Star Wars universe and Elemental creatures, as well as ancient Roman and Greek mythology.

    The Dryad This character is inspired by ancient Greek myths, aliens, and the golden era of science fiction, presenting a stunning fusion of a wood nymph with a World of Warcraft (WoW) hero.

    The Ent Assembled from tree bark and roots, the Ent is inspired by the Ents from the Lord of the Rings (LOTR) universe, Swamp Thing from DC Comics, and Groot from Marvel.

    The Spider The spider character embodies an aggressive, dynamic figure, combining an arachnid with a trickster — a mix of Baal from Diablo II, Monsters, Inc., and other characters, infused with elements of insects and alien life forms.

    We have deliberately directed our design team to embrace a “fairytale” aesthetic in the creation of our characters' likenesses. Regardless of age, we all cherish a touch of magic in our lives.

    Echoing the words of Steve Jobs: “Follow your heart, stay hungry, stay foolish!” we are committed to developing the finest cross-chain product on the market. Thank you for your support!

    The collection is broken down into five levels of rarity: Common, Uncommon, Rare, Legendary, and Infinity. The rarest of all are the Magician Infinity NFTs, of which there are only 193 in the entire EYWA NFT collection.

    Common
    Uncommon
    Rare
    Legendary
    Infinity

    Currently, the collection is available on the Aurora and Arbitrum networks:

    On the Aurora network, the collection is available for trading within our Telegram communities (Links to Telegram chats for trading Eywa NFTs: English speaking region CIS region).

    On the Arbitrum network, the collection is available for trading on OpenSea.

    Here is the Eywa NFT collection address in Aurora and Arbitrum.

    The utility of EYWA NFTs

    The EYWA NFT collection is composed of ERC-721 tokens with the following unique functions:

    • Container function for storing up to 1 500 000 EYWA tokens

    • Merge function that allows you to increase the size of the container and the rarity of the NFT by combining multiple NFTs of one level into one rarer NFT

    • CrossCurve DAO vote multiplier function via veEYWA

    Container

    Each NFT in the collection functions as a container for EYWA tokens. You can attach both unlocked and locked in vesting safes* tokens to the NFT. This allows the user to sell blocked EYWA tokens at any time.

    * Vesting safes are objects containing EYWA tokens that are blocked for a certain period of time based on the rules of the funding round (detailed information about the rules of each round and vesting periods are available here).

    The capacity of each NFT is the maximum number of EYWA tokens it can contain and depends on the rarity of the NFT. The highest capacity — 1 500 000 EYWA — is reserved for the Infinity rarity level NFTs. In the Aurora chain, you can see your current balance of token in the container. Once migrated to the Arbitrum chain, the tokens will be separated from the NFT and can be received as vesting safes via the Claim portal after the TGE.

    For details, see the table below:

    common

    500

    uncommon

    3 000

    rare

    25 000

    legendary

    250 000

    infinity

    1 500 000

    Merge

    Several NFTs of the same type can be merged to create a single NFT with a higher rarity level. This will also merge all of the tokens contained in the source NFTs.

    Multiplier table for NFT merging:

    Rarity
    Merge multiplicator

    common

    5

    1 uncommon

    uncommon

    7

    1 rare

    rare

    9

    1 legendary

    legendary

    n/a

    n/a

    veEYWA voting multiplier

    To vote in the CrossCurve DAO, users must lock EYWA tokens — the longer the lock period, the more voting power the user gets. Using EYWA NFTs can also increase voting power. Each NFT can increase the number of available votes by the maximum number of tokens it can contain.

    For details, see the table below:

    Rarity
    Maximum amount of tokens for boost
    Multiplier for veEYWA votes

    common

    500

    1.006

    uncommon

    3 000

    1.036

    rare

    25 000

    1.3

    legendary

    250 000

    For example, a user with 100,000 EYWA tokens can use one Legendary NFT to give his votes a 2.8 multiplier, since a Legendary NFT type can cover up to 250,000 tokens, or 4 Rare NFTs a 1.3x multiplier each (since each Rare NFT can only cover 25,000). Users can use any number and combination of NFTs for veEYWA vote multipliers to cover all of their holdings of EYWA.

    Migration to Arbitrum

    After the NFT collection is migrated to the Arbitrum chain, all of the above functions will become available. Before the TGE, we will open up a bridge to move the NFTs from Aurora to Arbitrum, as well as the NFT Manager to fully engage with all of the functions of the NFTs.

    The NFT Manager will ensure access to tokens contained in the NFTs, which will be separated from their containers after the migration to Arbitrum and be put together in each user’s wallet. Users will be able to put tokens into vesting safes and keep rEYWA in the NFTs.

    Farms - shows your liquidity provided in CrossCurve pools and farming rewards earned.

    It also presents statistics for pools you've joined:

    • Pool - pool name

    • Staked - quantity of LP tokens you've staked

    • APR - current pool yield

    • Earn - farming rewards earned

    To collect your rewards, click Claim and sign the transaction in your wallet, or navigate to the Farms page via the Go to Farms link to manage liquidity and earn rewards on Angle Merkl

    Vested section

    • Vested - displays EYWA tokens in vesting safes, locked in DAO, and tokens available for claiming upon vesting completion.

    • Claimable safes section shows the number of safes ready to be claimed and total token amount inside. To claim these vesting safes, click Get your safes and confirm the transaction in your wallet.

    • Vested safes section shows the total number of vesting safes and the token amount contained. Ready to claim displays EYWA tokens with completed vesting periods, available for claiming. To receive these tokens, visit the Claim Portal.

    • Early Farming Program section shows the amount of rEYWA tokens earned from early liquidity provision in CrossCurve pools (more details here). To exchange rEYWA tokens for EYWA, follow the Go to rEYWA link in the Early Farming Program section.

    • Locked in DAO displays your DAO locks, total tokens locked, and the nearest lock expiration date. For a full list of locks in the Locker, click View.

    DAO Rewards section

    • DAO Rewards - shows rewards earned from DAO participation.

    The Incentives section shows rewards received for your votes on CrossCurve pools. To claim these rewards, click Claim and sign the transaction in your wallet.

    NFT section

    • NFT - displays EYWA tokens contained within EYWA NFT containers pending vesting, and the number of EYWA NFTs in the connected wallet.

    • Aurora-NFT-detached EYWA tokens, post-bridging to Arbitrum - displays EYWA tokens detached from EYWA NFTs after bridging from Aurora to Arbitrum (more details here). These EYWA tokens can be claimed as vesting safes by clicking Claim and signing the transaction in your wallet.

    • In wallet - shows the number of EYWA NFTs and the EYWA token amount within NFT containers. Click View to see detailed information.

    • In lock - indicates the number of NFTs in locks. Click View to go to NFT Manager for detailed information.

    https://app.crosscurve.fi/dashboard
    1. Having selected the Deposit operation and Easy mode, proceed to the exchange modal window by pressing Next.

    1. Next, select the USD₮0 token (or any other available asset participating in the xSTABLE pool) to add the liquidity and choose the preferred network of the received original asset.

    1. After entering the desired amount of tokens, the system will calculate the number of LP tokens received and the gas fee. By clicking Routing details, Routing will be displayed - this interface provides a convenient graphical representation of the cross-network transaction, showing all associated transitions and fees step by step:

    1. The first transaction requires allowing the USD₮0 spending by clicking «Approve USD₮0» and signing the transaction in the wallet. To sign the transaction, you must hold the native token of the network in which the transaction is being made to pay for the gas.

    After confirming the spending of USD₮0, a “Swap” button will appear.

    1. By pressing the "Swap" button, a request will be sent to the wallet to confirm the transaction of depositing the USD₮0 token into the xSTABLE pool on Curve.

    1. After signing the transaction, a notification about the sending, the ongoing exchange, and the estimated waiting time will be received. The status and progress will be displayed in the top right corner.

    If in Easy mode you see high losses, consider other assets for acquisition or use the Balanced mode of liquidity deposit

    Liquidity

    To use the bridge and transfer your rEYWA from the Fantom network to Arbitrum, you must have FTM in your Fantom wallet to sign the transaction and pay the gwei in the Fantom network.

    After successfully transferring rEYWA from Fantom to Arbitrum, the application will display the balance of the transferred tokens. To start the 90-day vesting period and receive EYWA tokens in exchange for rEYWA, click Start vesting, specify the amount of rEYWA you want to vest, and confirm the transaction in your wallet.

    To place your rEYWA in the Arbitrum network into vesting, you must have ETH in your Arbitrum wallet to sign the transaction and pay the gwei in the Arbitrum network.

    After placing rEYWA into vesting, the application will display detailed information:

    • Vested - amount of rEYWA tokens that have completed vesting

    • Current vesting - the total amount of rEYWA currently in vesting

    In the table, you will see detailed information about ongoing vesting periods:

    • Amount - the amount of rEYWA tokens for each vesting period

    • Date - the vesting end date and the number of remaining days. Complete means completed vesting periods.

    • Penalty - the amount of penalty* in rEYWA tokens for early termination of vesting

    * You can find detailed information by following the link or by clicking

    1. To receive rEYWA tokens after the vesting period ends, select the vesting safe and click Withdraw, then confirm the transaction in your wallet.

    1. To end the vesting period early and receive rEYWA tokens minus the penalty*, click Exit and confirm the transaction in your wallet.

    * The penalty amount is calculated using the following formula:

    Where:

    V early - number of rEYWA tokens received on the day T

    T - number of vested days passed since the rEYWA claim

    V all - total number of rEYWA tokens available on the 91st day, after the vesting period is completed

    * You can find detailed information by following the link or by clicking

    https://app.crosscurve.fi/reywa-vesting
    Vearly=T2912∗VallV_{early}=\frac{T^2}{91^2}∗V_{all}Vearly​=912T2​∗Vall​
    Architecture

    LayerZero uses DVNs to achieve decentralized verification of cross-chain message transfers. However, ensuring robust security requires two or more independent DVNs.

    For developers, SuperDVN appears as a single DVN, but internally it contains a consensus layer composed of multiple messaging protocols, combining their verification capabilities for enhanced reliability and trustlessness.

    Message Flow:

    • The OApp application sends a message on the source network to the LayerZero Endpoint contract.

    • The LayerZero protocol processes the message in its standard way and forwards it for verification to the CrossCurve DVN contract.

    • The CrossCurve DVN prepares and sends the verification data to the CrossCurve Gatekeeper.

    • The Gatekeeper dispatches this data through multiple messaging protocols.

    • Each protocol, following its standard cross-chain messaging procedure, independently delivers the data to the CrossCurve Receiver contract.

    • The Receiver collects the incoming message instances and emits events upon receipt.

    • The external service CrossCurve Pusher monitors these events. Once the original message and a sufficient number of verification confirmations are detected, it submits an execution transaction to the CrossCurve Receiver contract.

    • Upon receiving the transaction from CrossCurve Pusher, the Receiver checks that the original message and all required protocol confirmations are present.

    • If verification succeeds, the data is passed back to the CrossCurve DVN, which forwards the verification data to the ReceiveLib contract to complete the verification process and allow LayerZero to proceed with message delivery.

    Integration with LayerZero

    SuperDVN is fully compliant with the LayerZero DVN Standard, which provides:

    Ability to connect as a primary DVN for cross-chain messaging between networks using LayerZero.

    Support for custom DVN, allowing SuperDVN to be used for specific applications.

    Compatibility with the LayerZero ecosystem without the need to modify smart contracts.

    Supported Protocols

    SuperDVN leverages CrossCurve Consensus Bridge to enhance verification security.

    Currently, the Consensus Bridge supports the following messaging protocols:

    • CrossCurve Oracle Network

    • LayerZero

    • Axelar

    • Router Protocol

    Connection and Integration

    To integrate SuperDVN into an OApp, you need to configure the ULN as specified in the LayerZero documentation.

    Here is an example configuration for using a single SuperDVN:

    SuperDVN.address — the address of the SuperDVN contract on the OApp network that sends the message.

    Contracts

    To configure the OApp, use the following contract addresses:

    Network
    CrossCurve SuperDVN Address

    Ethereum Sepolia Testnet

    Arbitrum Sepolia Testnet

    DVN standard

    Having selected the Withdraw operation and Easy mode, proceed to the exchange modal window by pressing Next.

    1. Next, select the USDT stablecoin (or any other available asset participating in the EUSD pool) to withdraw liquidity and choose the preferred network of the received original asset.

    1. After entering the amount of tokens to be withdrawn, the system will calculate the number of LP tokens received and the gas fee. By pressing Routing details, the Routing will be displayed.

    1. The first transaction requires allowing the spending of EUSD by pressing “Approve EUSD” and signing the transaction in the wallet. For signing the transaction, you must hold the native token of the network in which the transaction is being conducted to pay for the gas.

    After confirming the spending of EUSD, a “Swap” button will appear.

    1. By pressing the "Swap" button, a request will be sent to the wallet to confirm the transaction of exchanging the EUSD LP token from the EUSD pool to the USDT stablecoin on the Arbitrum network.

    6. After signing the transaction, a notification about the transaction sending, the ongoing exchange, and the estimated waiting time will be received. The status and progress will be displayed in the top right corner.

    If in Easy mode you see high losses, consider other assets for acquisition or use the Balanced mode of liquidity withdrawal

    Liquidity

    This method should be applied to avoid penalties and earn additional profit on Curve in cases when you are working with large sums relative to the total TVL of the pool, or when the pool is close to perfect balance. After pressing Withdraw, confirm the operation in the wallet. After completing the operation, the system will issue a Withdraw Complete message.

    Step 3. Convert the required s-tokens in the CrossCurve interface.

    On the Pool Details page, there is a link for quick access to the CrossCurve interface to convert s-tokens into original assets.

    1. In the Input window, select the s-token for conversion and specify the amount of s-tokens to be converted.

    2. In the Output window, select the token for conversion, approve the spending of the s-token by clicking Approve scrvUSDC_o, and confirm the transaction in the wallet.

    1. After approving the spending of scrvUSDC_o, a Swap button will appear.

    4. By pressing the "Swap" button, a request will be sent to the wallet to confirm the transaction of exchanging the scrvUSDC_o s-token for the selected crvUSDC LP.

    5. After signing the transaction, a notification about the transaction sending, the ongoing exchange, and the estimated waiting time will be received. The status and progress will be displayed in the top right corner.

    xCRVUSDC pool
    veEYWA
    APR
    veEYWA
    APR
    APR
    veEYWA
    veEYWA
    veEYWA
    Locker

    How to trade

    CrossCurve provides a user-friendly experience for conducting operations between different blockchains. All cross-chain transactions, such as token transfers, cross-chain stablecoin exchanges, and cross-chain buying and selling of assets, can be performed from a single interface.

    Step 1. To access CrossCurve DEX, go to https://app.crosscurve.fi/.

    Step 2. Go to the Trade section.

    Step 3. Connect your wallet by clicking the Connect wallet button in the top right corner.

    Step 4. In the FROM field, specify the token and the network from which you are sending. This can be done in a special modal window that appears when you click on the network or token icon.

    Step 5. In the TO field, specify the token and the receiving network.

    Step 6. In the FROM field, enter the amount of tokens you are sending. The amount of tokens you will receive in the TO field will be calculated automatically.

    Step 7. Review the details of the cross-chain operation. In the dropdown menu, you can review the key details of the cross-chain operation:

    • Routing details - full information about all cross-chain swaps for the selected transaction (details here)

    • Expected amount - approximate amount you will receive after taking out the fee

    • Total slippage - total effective slippage applied across all networks where a swap occurs during a cross-chain transaction, calculated as the sum of slippage percentages for each individual network involved in the transaction

    Gas cost reflects the gas fee in Gwei (details ). Expected transfer time indicates the time the transaction is expected to take. The “You’ll get” line shows the amount of points you will receive in the loyalty programs of Airdrop Season 2 and MetaPoints (details and ).

    Step 8. Give the CrossCurve application Approve or Permit permission for the CrossCurve smart contracts to interact with the assets you are sending, as specified in the FROM field.

    Step 9. Click the Swap button to execute the cross-chain operation.

    If the transaction has a high price impact, an additional window will appear before signing the transaction, where you will need to confirm the operation. This is to prevent accidental loss of user funds.

    Step 10. Sign the transaction in the wallet connected to the app.crosscurve.fi application.

    After submitting a cross-chain transaction, you can track the progress of the cross-chain operation in the Transaction history:

    Each cross-chain operation consists of multiple stages. In the Transaction history section, users can track the status of its execution and review its component transactions.

    If a cross-chain operation was interrupted for any reason, you will see an appropriate notification in the Transaction history. The interface will provide options for further actions. For more detailed information, you can refer to the Error in Cross-Chain Operation section.

    Modal window for selecting networks and tokens

    A modal window is used for selecting networks and tokens:

    On the left side, click on the desired network. The right side will display all available tokens for sending/receiving in that network. You can use the search function to find a specific token by its name or smart-contract address.

    For your convenience, you can Search by name of the token’s ticker or by its smart-contract address.

    Hovering over any token will show a quick link for adding that token to your wallet and a link to that token’s smart-contract address on the scanner.

    When entering Advanced mode, you’ll see a filter for sorting tokens as: All, USD, ETH, BTC, Other

    Guide to transferring CRV from Fantom chain to Ethereum mainnet

    1. Open the Curve DAO Token (CRV) contract in FTMScan:

    https://ftmscan.com/token/0xe6c259bc0fce25b71fe95a00361d3878e16232c3?a=0xbcd3e2e841cc6140ede73c9ad8ad86ec7e423f52

    1. Go to the Contract tab, choose Write Contract, and connect your wallet by clicking Connect to Web3.

    1. Expand the approve submenu for the Curve DAO Token (CRV) contract and make sure the _spender address is the following bridge contract:

    Enter the number of tokens to approve for moving (in Wei format, meaning that you need to add 18 zeroes to the end of the amount or click and choose the right format).

    Here is an example for approving 10,000 CRV tokens:

    1. Click and sign the Token Approval transaction in your wallet.

    2. After a successful Token Approval transaction, find the Layer Zero Bridge contract for Curve DAO Token (CRV) in FTMScan:

    1. Go to the Contract tab, then Read Contract.

    1. Click on the 1. quote tab, after which you will see the current Wei cost of the transfer. Click on that to open the converter. Copy the FTM (1) value.

    1. Go to the Write Contract tab and connect your wallet by clicking Connect to Web3.

    1. Click on the 1. bridge (0xc3de453d) tab, after which you’ll see a form with 3 fields to be filled out as follows:

    • In the bridge field, enter the value you copied from 1. quote.

    • In the _receiver (address), enter the receiving Ethereum address (your own, if sending to yourself).

    • In the _amount (uint256) field, enter the number of tokens (in Wei format: add 18 zeroes to the end of the amount or click and choose the right format).

    Example of filling out the fields for transferring 10,000 CRV tokens:

    Click and sign the Bridge transaction in your wallet. Your transfer has now been sent. You can find the status and other details of the transfer here:

    EYWA NFT Manager interface

    EYWA NFT Manager interface description

    In the EYWA NFT Manager, users can see information about the number of EYWA tokens in each NFT container and vesting periods simply by entering the ID of any NFT in the collection. After connecting their wallet, users can also manage their vesting safes* and add EYWA tokens to NFT containers**.

    * Vesting safes are objects containing EYWA tokens that are blocked for a certain period of time based on the rules of the funding round (detailed information about the rules of each round and vesting periods are available here).

    ** Container - each NFT in the collection functions as a container for EYWA tokens. You can attach both unlocked and locked in vesting safes tokens to the NFT. This allows the user to sell blocked EYWA tokens at any time.

    To find an NFT’s container and vesting information using its ID, one should go into the «» section, connect his wallet, and enter the number into the «NFT ID» field:

    Search for NFT ID

    To find the NFT ID, go to the collection page for EYWA NFTs, making sure that the address matches the original address of the collection:

    Choose an NFT of interest and go to its page.

    You will see the NFT ID in the name of the selected NFT.

    To quickly get into the app, use the View website link in the More menu.

    After entering the NFT ID into the search bar, the EYWA NFT Manager will show you information about the found NFT:

    EYWA NFT Manager interface description

    On the EYWA NFT Manager page, you can use the “search via NFT ID” function or choose one of your NFTs from the My NFTs gallery.

    After selecting the NFT, the search window will show detailed information:

    • NFT rarity and remaining space in the container

    • Total number of tokens in the safe

    • Rounds in which the EYWA tokens were received and their vesting period: total number of received tokens in each round, number of unlocked tokens, and when the vesting of the locked tokens ends

    Detailed information about rounds and visiting periods can be found.

    Attention! If you buy NFT with EYWA tokens in a container, we recommend using the Buy now function to avoid detaching EYWA tokens before confirming the purchase. If you are buying on an Auction by sending your Offer or on an OTC marketplace - there is a possibility of falling for an unscrupulous seller who may detach the tokens from the container before sending the NFT to the buyer. The Buy now instant purchase feature on significantly reduces this risk.

    To manage your NFTs in the CrossCurve app, you need to go to the Manager page in the NFT section. In the top right corner, click on «Connect wallet», select the right wallet from the list, and confirm the connection, making sure that you are on the official page:

    After successfully connecting the wallet, in the «Total in wallet» tab you will see your total EYWA token balance (wallet Balance plus vesting safes) as well as information about rounds where these tokens were received and their vesting period:

    • Total number of tokens received in the round

    • Number of unlocked tokens

    • End of vesting period for locked tokens

    In the My NFTs section, you’ll see all the EYWA NFTs from the connected wallet with detailed information about each one:

    • ID

    • Rarity

    • Number of EYWA tokens in the NFT container

    Removing tokens from the NFT container

    • To remove tokens from the NFT container, enter the number of tokens and click «Detach from NFT». Then confirm in your wallet:

    After the on-chain confirmation of the transaction, you will receive a notification that the NFT safe was successfully updated:

    Attaching tokens to the NFT safe

    • To attach tokens to an NFT safe, enter the number of EYWA tokens, select the vesting safes that contain those tokens, and click «Attach to NFT». Then confirm in your wallet:

    When adding tokens to NFTs, safes of the same type and vesting period are merged.

    Keep in mind the maximum capacity of each NFT (based on rarity). If all of the tokens do not fit into the NFT, you will need to use additional NFTs or decrease the number of tokens in the safe after they are vested.

    After the on-chain confirmation of the transaction, you will receive a notification that the NFT safe was successfully updated:

    Incentives Interface

    Incentives Interface Description

    Incentives interface provides access to the ve(3,3) mechanism in the CrossCurve DAO for external projects and protocols, as well as for veEYWA holders.

    «ve(3,3)» is a mechanism used in DeFi protocols that combines (3,3) from game theory (mutually beneficial cooperation) and ve (vote escrow, i.e., token locking for voting), creating a tokenomics model where everyone benefits from acting in the protocol’s best interests, generating overall synergy.

    Now, owners of locked EYWA tokens (veEYWA) can receive additional rewards for participating in votes for specific liquidity pools, significantly expanding the earning opportunities within the ecosystem. Meanwhile, external projects can acquire liquidity, gain visibility, and secure their status in the cross-chain space.

    To get started in the CrossCurve application, go to the Incentives page in the DAO section. Click “Connect wallet”, select a suitable wallet from the list, and confirm the connection, making sure you are on the official page:

    On the Incentives page, detailed information will be displayed:

    • Current voting round ends in - remaining time until the voting period ends in this epoch

    • Farm pools - pool name and its statistics:

    • Basic Volatile - pool type*

    * CrossCurve offers two distinct liquidity pools to users: the Stable Pool and the Volatility Pool.

    Volatility Pools consist of liquidity (Curve pools) for asset pairs with volatile prices, typically experiencing divergence. For example, USDT vs. EYWA or ETH vs. BTC.

    Volatile pairs are formed by combining uncorrelated assets and utilize Curve's unique impermanent loss compensation mechanism for pools containing volatile assets.

    Stable Pools are pools of stable liquidity (Curve pools) between assets whose prices are pegged to each other. For example, USDT vs. USDC.

    Another case involves derivative assets, such as wstETH and rETH. Although rETH is considered a volatile asset, the trading pair between wstETH and rETH is classified as a stable pool because the price of wstETH does not significantly fluctuate relative to rETH.

    • Votes - number of veEYWA votes cast and the percentage of total votes received by this pool among all pools participating in the vote

    • Chain - the network in which the pool operates

    • TVL - total value locked in the pool

    • Volume (24h) - trading volume in the pool over 24 hours

    Attention: The Incentives function is mainly used by protocols. Please ensure that you understand how it works before using it, as any transaction is final and cannot be reversed. For more detailed information, follow the Read docs link.

    For easier navigation, use the filter icon to search for a specific network or token within a pool.

    To propose a reward for all CrossCurve DAO participants in exchange for their votes in the next epoch, select the pool to which you want to allocate rewards. At the beginning of the next epoch, these rewards will be evenly distributed among all those who voted for that pool.

    In the modal window that appears, select the token in which you want to add rewards and enter the amount to be allocated.

    To proceed with adding the selected rewards to the pool, you must give consent by checking the box, as any transaction is final and cannot be reversed, meaning the allocated tokens cannot be refunded.

    After confirming your agreement with the reward allocation terms, click Add Incentive and sign the transactions to approve spending (Approve) and add the rewards (Add Incentive)

    By navigating to the page in the DAO section, you can view the amount of allocated rewards for DAO participants in the current and upcoming epochs:

    Estimated EYWA emission in the next epoch - average amount of rewards allocated for the next epoch in EYWA tokens

    Estimated CRV emission in the next epoch - average amount of rewards allocated for the next epoch in CRV tokens

    Estimated incentives available in the current epoch - average amount of rewards allocated for the current epoch in USD equivalent

    The reward amounts allocated to voters for each pool are displayed in the Incentives column.

    On the page in your personal statistics, rewards are calculated in the Incentives section. At the end off the epoch, rewards become available for claiming. To claim your rewards, click Claim and sign the transaction(s) in your wallet.

    Claim portal interface

    To start using the CrossCurve app, navigate to the Claim portal page in the Vesting section. Click «Connect wallet», select the appropriate wallet from the list, and confirm the connection, ensuring that you are on the official page: https://app.crosscurve.fi/vesting

    After successfully connecting your wallet, the app will verify your wallet address against the criteria for eligible EYWA tokens to claim. Please wait for the request to be processed.

    If, after the wallet verification request, you see a message stating that the wallet address was not found on the token claim list, please verify the accuracy of the connected wallet address. If you believe an error has occurred, contact support to repeat the verification process:

    • for private round participants, e-mail;

    • for public round participants, .

    After successful verification, you will see all vesting safes available for your wallet address, containing EYWA tokens received in each distribution round. To manage vesting safes, click Get your vesting safes and confirm the transaction in your wallet.

    Read more about rounds .

    After successfully confirming the transaction, all vesting safes available for the connected wallet will be displayed.

    In each type of vesting safe, the following information is displayed:

    • All vested tokens - the number of tokens in the safe that are in vesting

    • Amount to claim - the available amount of tokens to claim

    • Already claimed - the number of tokens already claimed from the vesting safe

    • Time remaining until next claim - the remaining vesting time before tokens can be claimed from the safe

    If you have multiple vesting safes for a single round, their number will be displayed in the upper right corner of the safe.

    To view detailed information about grouped safes received in one round, hover your cursor over that safe.

    Attention! If you see the Claim button inactive - don't worry, it will become active immediately after the listing of EYWA token on CEX. The vesting timer will also start counting from the listing date.

    1. To claim available tokens, select the safe and click Claim, then confirm the transaction in your wallet.

    1. To claim available tokens from grouped safes, click Open to claim.

    Choose the safe to claim tokens from, click Claim and confirm the transaction in your wallet.

    Early farming program

    Introducing «Early Farming» — a farming program for early liquidity providers!

    How it works

    For providing liquidity in CrossCurve pools, the participants will receive rewards in rEYWA tokens. rEYWA — a non-transferable reward token (reward EYWA) that after the listing can be traded for the EYWA token on a 1:1 basis. Participants receive the rewards based on the rules of the Early Farming program, based on the volume of liquidity provided and the pool selected:

    Available pools and their earning potential:

    Pool
    Target Pool TVL, $
    rEYWA APR*, %
    Incentives per month, rEYWA
    Monthly yield, %

    Base income calculations include the assigned incentives for the 3 pools and the TVL in each pool.

    These pools allow the participants to receive earnings (Net APY) that combines the base rEYWA earnings per the above table + vAPY in .

    *The rEYWA APR is calculated at the EYWA price of $0.14. You can use this calculator to simulate your earnings with different EYWA prices:

    rEYWA claim and vesting schedule

    rEYWA tokens have a 90-day vesting period starting from the claim, which can be done at any time. Once the vesting period is over, rEYWA can be converted to regular EYWA tokens 1:1. Exchanging rEYWA to EYWA is possible only after the listing.

    If a participant wishes to do this exchange prior to the completion of the vesting period, he will be able to convert only those rEYWA that have vested based on the vesting schedule. The rest of his rEYWA will be returned to the CrossCurve DAO’s treasury.

    The formula for exchanging rEYWA for EYWA before the 90-day vesting period ends is as follows:

    Where:

    V early - number of rEYWA tokens received on the day T

    T - number of vested days passed since the rEYWA claim

    V all - total number of rEYWA tokens available on the 91st day, after the vesting period is completed

    Participants can choose to wait until the vesting period is over or take part of their tokens earlier based on their needs and strategy.

    An example with 10 000 rEYWA converted on Day 21 after the claim:

    Where:

    T = 21 (vesting days since the claim),

    V all = 10,000 rEYWA (total number of rEYWA tokens that could be claimed on day 91).

    Therefore, on day 21, the participant would only receive 500 rEYWA out of 10,000. These are the tokens he would be able to exchange for EYWA after the listing. The remaining 9,500 tokens would be returned to the DAO's treasury.

    Farms Interface

    Farms Section and Its Functionality

    To start working in the CrossCurve app, go to the Farms page in the Yield section. There, click “Connect wallet” in the top right corner, choose a suitable wallet from the list, and confirm the connection, making sure you are on the original page https://app.crosscurve.fi/farms.

    1. After successfully connecting, you will see all available pools for staking LP tokens in the selected network to earn EYWA or/and CRV.

    • Farm Pool - Pool name

    • Chain - Network where the pool is located

    • TVL - Total volume of funds in the pool

    • Volume - Trading volume in the pool for the past 24 hours

    By clicking on the APR Calculator icon, you will see a modal window to calculate your actual vAPR and boost for your deposit based on veEYWA ownership and the resulting EYWA NFT boost. More details you can find here.

    By clicking on the vAPR icon you will see detailed information about the rewards in the selected pool.

    • Current vAPR - Current “Variable Annual Percentage Rate”: it is the interest you'd earn on your deposits for a whole year, and it's variable because it depends on today's trading activity in this pool, the price of the assets you deposit, the price of the assets you're rewarded with, and the current rewards rates.

    • Base pool vAPR - “Base pool vAPR” accrues within the CrossCurve pool: this yield does not require claiming; it is automatically accumulated within your LP token.

    • CRV cAPR - “CRV vAPR” is distributed separately and can be claimed on the “Farms” page in the “Farming rewards” section. The amount of this yield depends on your veCRV boost.

    1. By expanding the details window of the selected pool, you can find a link to obtain the LP token via CrossCurve, or through Curve pools and Pool Contract (leads to the pool's LP token contract). You can also find a direct link to rewards dashboard.

    In the Farming rewards window, accrued earnings from farming are displayed.

    Staked shows the balance of LP tokens locked for earning EYWA and CRV.

    1. By clicking ‘Stake LP and get rewards’ we will see a modal window of steaking to get EYWA and CRV.

    In the field for entering the amount of LP tokens to be deposited, enter the desired amount. By clicking the Get LP link, you can obtain additional tokens on CrossCurve.

    1. The top menu allows sorting the display of pools:

    By relevance

    By type (Stablecoin, crypto or any pools)

    By Popularity, APR, TVL, Liquidity Utilisation and Volume

    Swap interface

    Introducing the CrossCurve User Interface

    By visiting the main page at , you enter the CrossCurve Application Interface, where you can see three main sections: the Interface for executing token exchange transactions between different networks ( tab), the user interface for interacting with the , , and ( tab), the statistics page along with referral count ( tab), the Interfaces for working with liquidity and yield strategies on CrossCurve ( menu), and the menu for interacting with Vesting Safes and rEYWA ( menu). There is also a quick link to the where yields are reflected ( tab) and a menu for quick purchasing of $EYWA

    Proposals Interface

    Proposals provides the CrossCurve DAO community with tools to manage and guide the protocol's development:

    - A platform for managing and voting on proposals impacting the CrossCurve protocol

    - Decentralized decision-making by token holders

    DAO members actively participate in shaping the CrossCurve protocol by:

    • Creating proposals: members can introduce initiatives such as protocol parameter adjustments or fund allocation.

    Adding liquidity to pools on Sonic

    To provide liquidity to Sonic pools:

    • Select the pool where you want to transfer liquidity, e.g., xsArbitrum.

    • Determine the required token amounts.

    CalldataHelperV1

    Overview

    CalldataHelperV1 is an upgradeable contract that assists with decoding and slicing transaction calldata. It extracts critical parameters such as method-specific calldata, a target address, and a chain identifier from a given input. This functionality is useful in scenarios where cross-chain calls or proxy calls need to parse custom-encoded calldata.

    By implementing ICalldataHelperV1, the CalldataHelperV1 contract ensures a standardized interface for:

    LockHolderV1

    Overview

    LockHolderV1 is an upgradeable contract integrated with DelegationManager, EscrowManager, EscrowVoteManager, IncentiveRewardsAggregatorV1. For each delegator-delegate pair, a different LockHolder contract is deployed, with delegated locks in the balance. Through the LockHolder contract the proxied call of functions of EscrowManager, EscrowVoteManager counters, as well as collection and distribution of incentive rewards takes place.

    Key Roles and Features:

    Vote Interface

    Vote Interface Description

    Voting for pools and earning incentives

    tokens provides unique opportunities to earn additional income by receiving on specific . holders use their votes to direct across CrossCurve pools. Projects seeking liquidity offer incentives (various tokens) to holders in exchange for their votes.

    tokens transforms voting rights into income streams: veEYWA holders select the most beneficial proposals and receive rewards in tokens, cryptocurrencies, or other forms of income from participating projects. The higher your veEYWA balance, the greater your potential rewards.

    RewardsDistributorFactoryV1

    Overview

    RewardsDistributorFactoryV1 is an upgradeable contract (using UUPS) that deploys new instances of IncentiveRewardsDistributor. It restricts calls to createRewardsDistributor such that only the escrow vote manager can request a new distributor, thus ensuring controlled creation of additional reward distribution contracts.

    Key Roles and Features:

    Treasury

    Overview

    Treasury is a minimal yet crucial smart contract that securely stores and allows controlled withdrawals of both native ETH and ERC20 tokens. Owned by a single address, it enforces strict access control on asset movements via onlyOwner and mitigates re-entrant calls through nonReentrant. This design ensures that only the contract owner can authorize withdrawals and that no re-entrancy exploits can siphon funds.

    Key Attributes:

    const ulnConfig = {
        confirmations: 1,
        requiredDVNCount: 1,
        optionalDVNCount: 0,
        optionalDVNThreshold: 0,
        requiredDVNs: [SuperDVN.address],
        optionalDVNs: []
      };
    
    
      const encodedUlnConfig = ethers.utils.defaultAbiCoder.encode(
        ["tuple(uint64 confirmations, uint8 requiredDVNCount, uint8 optionalDVNCount, uint8 optionalDVNThreshold, address[] requiredDVNs, address[] optionalDVNs)"],
        [ulnConfig]
      );

    Utilization - Liquidity Utilization rate = 24h trading volume / Liquidity

  • Net APY - annual interest rate

  • Earned - number of earned EYWA or/and CRV tokens for the whole staking period

  • EYWA DAO vAPR by Merkl - “EYWA DAO vAPR by Merkl” is distributed separately and can be claimed on the “Farms” page in the “Farming rewards” section or directly in Merkl app. The amount of this yield depends on your veEYWA boost.

    Angle Merkl
    0xA8e6c5932fc3F0BBd4532e911BC1e14db78F35e9
    0x2245F56774fa53966643bCeC94F916cBd16AA854
    Fee
    - the sum of all fees for the swap transaction, including the bridge fee, DEX fee, and aggregator fee
    here
    here
    here

    infinity

    n/a

    n/a

    2.8

    infinity

    1 500 000

    3

    Access Control: Restricts setAssuranceLockParameters and setMinLockVeEywa calls to the owner of contract(owner()).

  • Upgradeable via UUPS: Uses UUPSUpgradeable and OwnableUpgradeable patterns, restricting contract upgrades to the owner.


  • Inherited Contracts and Interfaces

    • UUPSUpgradeable (OpenZeppelin): Provides upgrade functionality under the UUPS proxy pattern, restricted to the contract owner.

    • OwnableUpgradeable (OpenZeppelin): Manages ownership, allowing only the owner to modify critical parameters and authorize upgrades.

    • ILockHolderV1: Defines core methods (e.g., boost, deboost, extend) and events for this contract.

    Additional External References:

    • SafeERC20, IERC20 (OpenZeppelin): Handles secure ERC20 operations for distributing and approving token transfers.

    • IIncentiveRewardsAggregatorV1: Aggregates lists of reward tokens.

    • IEscrowVoteManagerV1: Receives gauge emission amounts and coordinates gauge reward distribution.

    • IEscrowManager: Holds locked token data and checks voting power and freeze logic.


    Constants

    • PRECISION: The divisior for percentage math.


    State Variables

    • s_delegationManager (address) address of the delegation manager contract.

    • s_escrowVoteManager (IEscrowVoteManagerV1) IEscrowVoteManagerV1 interface for the escrow vote manager contract.

    • s_incentiveRewardsAggregator (IIncentiveRewardsAggregatorV1) IIncentiveRewardsAggregatorV1 Interface for the incentive rewards aggregator contract.


    Constructor

    • Description: Disables contract initializers to prevent re-initialization in a UUPS proxy context.


    External Functions (Defined by ILockHolderV1)

    initialize(...)

    Description: Configures ownership, references, and initial state:

    • References the EYWA NFT, escrow manager, escrow vote manager and delegation manager.

    Parameters:

    • owner_: The address of the contract owner.

    • delegationManager_: The address of the delegation manager contract.

    • escrowManager_: The address of the escrow manager contract.

    • escrowVoteManager_: The address of the escrow vote manager contract.

    • incentiveRewardsAggregator_: The address of the incentive rewards aggregator contract.


    claimIncentives(address delegator_, address delegatee_, uint256 percentIncentive_)

    Description: Function for claim and distributing incentives. The function queries arrays with the addresses of the reward tokens and the size of the reward for each of them on the IncentiveRewardsAggregatorV1 contract Then for each IncentiveRewardsDistributor it claim incentives, calculates on the basis of percentIncentive_ what parts of it should be received by delegator_ and delegatee_ and distributes incentives between them.

    Parameters:

    • delegator_: The delegator's address.

    • delegatee_: The delegate's address.

    • percentIncentive_: The percentage of the incentive reward received by the delegate.

    Checks:

    • The function must be called by the DelegationManager contract. Otherwise, UnauthorizedCaller() is thrown.


    Errors

    • UnauthorizedCaller() Thrown when the caller is not authorized to perform the action.


    Summary

    LockHolderV1 contract is an important and necessary part of the lock delegation and self-delegation architecture. It allows for diverse and flexible interaction and integration with all contracts in the system.

    uint256 private constant PRECISION = 100_000;
    constructor() {
        _disableInitializers();
    }
    function initialize(
        address owner_,
        address delegationManager_,
        IEscrowManager escrowManager_,
        IEscrowVoteManagerV1 escrowVoteManager_,
        IIncentiveRewardsAggregatorV1 incentiveRewardsAggregator_
    ) external initializer;
    function claimIncentives(
        address delegator_, 
        address delegatee_, 
        uint256 percentIncentive_
    ) external;

    Stable pairs on CrossCurve are designed for correlated assets and aim to maintain a 1:1 transfer ratio between them as closely as possible.

    APR - yield in the pool

  • Total incentives - total rewards allocated for the epoch in USD equivalent

  • https://app.crosscurve.fi/incentives
    Vote
    Dashboard

    xBTC

    $10 000 000

    25%

    1 489 к

    2,08%

    xSTABLE

    $10 000 000

    50%

    2 978 к

    4,16%

    xWETH

    $10 000 000

    25%

    1 489 к

    2,08%

    Vearly=T2912∗VallV_{early}=\frac{T^2}{91^2}∗V_{all}Vearly​=912T2​∗Vall​
    Vearly=T2912∗VallV_{early}=\frac{T^2}{91^2}∗V_{all}Vearly​=912T2​∗Vall​
    Vearly=212912∗10000=500V_{early}=\frac{21^2}{91^2}∗10000=500Vearly​=912212​∗10000=500
    Curve pools
    tokens (
    menu).

    Swap Section and its Functionality

    To start, in the top right corner click “Connect wallet”, select a suitable wallet from the list and confirm the connection, making sure that you are on the original page app.crosscurve.fi/swap

    After successfully connecting, select the required network (twenty one networks available in the CrossCurve pools: Sonic, Fantom, Polygon, BNB Chain, Arbitrum, Optimism, Ethereum, Avalanche, Base, Gnosis, Blast, Fraxtal, Mantle, Linea, Taiko, Mode, Unit Zero, Celo, Kava, Manta, Metis) by clicking the icon next to the wallet address.

    Basic interface elements

    The interface consist of basic elements, such as:

    1. Wallet section

    If you click on this section pop-up window will appear:

    Here you can change network, copy wallet address, see your native token balance in the chosen network, go to transaction history, and disconnect your wallet.

    1. Transaction History

    Here you can see status of your transactions, if your transaction has failed the icon will have red mark.

    Transaction history can be viewed in the log. By clicking on Details, links to the network scanner where the transaction was made will appear, providing detailed on-chain information.

    Maximum transaction time: 30 minutes. If the maximum time is exceeded, please contact our support team in our official Telegram / Discord channel

    1. New tokens available today

    Open the New Tokens Today tab and see the full list of recently added supported tokens and their networks.

    1. Earn bonus points

    Open the Earn Bonus Points tab and browse currently active trading competitions and/or user reward programs to earn additional points.

    1. Slippage settings.

    In the settings, you can specify slippage (by default, the parameter is set at 0.5%) Slippage is a change in price caused by external market movements and not related to the user's activity in the pool. Slippage highly depends on the liquidity volume inside the pool. If a token pool has low liquidity, significant rate changes within the pool require less market movement.

    CrossCurve users can configure the maximum permissible slippage for cross-chain operation (details here):

    1. Source and destination input.

    Here you can change network and token.

    When you click on source/destination input, then Chains/Token menu opens.

    app.crosscurve.fi
    Trade
    Dashboard
    DAO
    Farming
    NFTs
    Dashboard
    Airdrop Points
    Leaderboard
    Yield
    Vesting
    Locker
    DAO
    Staking APY
    Buy EYWA
    Voting: users vote For/Against proposals using their veEYWA tokens (vote weight corresponds to veEYWA balance).
  • Status tracking: displays proposals categorized by active, completed, and pending, along with their outcomes.

  • To begin interacting with proposals in the CrossCurve app, visit the Proposals page at https://app.crosscurve.fi/proposal under DAO → Vote, then click Connect wallet.

    The Proposals page lists DAO proposals, each showing:

    • Proposal title and a brief summary

    • Current status:

      • - Pending voting start

      • - Proposal approved

      • - Proposal rejected

      • - Insufficient quorum

      • - Active voting

    - - Link to the proposal author

    - - Date of creation

    Voting progress is shown in the status bar, displaying:

    • Number of votes For and Against

    • Required quorum in veEYWA tokens

    For detailed information, navigate to the specific Proposal page.

    To participate in voting, connect your wallet by clicking Connect wallet

    • If the Proposal status is , the required quorum and voting start time will be shown.

    • If the Proposal status is , current voting progress will be displayed Yes or No.

    After voting, await voting completion.

    • Once voting concludes, results are shown clearly:

      • - Proposal approved, with a vote weight of 64% Yes

    • - Proposal rejected, with a vote weight of 74% No

    • - Insufficient quorum achieved

    For the Arbitrum example, you need 25% frxUSD and 25% scUSD to obtain 50% xfrxUSD and 50% sUSDC_arb (percentages are based on the total liquidity you plan to transfer to the xsArbitrum pool).
    • Obtain the synthetic token for this direction, in this case, sUSDC_arb.

    • For USD pools, acquire xfrxUSD tokens. For example, deposit an equal amount of frxUSD and scUSD into the CrossCurve frxUSD pool.

    • Deposit the universal token and the directional (synthetic) token into the paired pool.

    Let's examine each step:

    1. Obtaining xfrxUSD via the Curve App interface

    To obtain the LP token xfrxUSD, you need to provide liquidity in the CrossCurve frxUSD pool: https://curve.finance/dex/sonic/pools/factory-stable-ng-25/deposit/.

    Go to the CrossCurve frxUSD pool page and connect your wallet.

    Enter the desired deposit amount on the Deposit tab. To avoid losses due to slippage, it’s recommended to deposit funds in a balanced manner by clicking Add all coins in a balanced proportion (learn more here).

    In the first transaction, confirm the spending of funds by clicking Approve Spending and signing the transaction in your wallet.

    In the second transaction, deposit the funds by clicking Deposit and signing the transaction in your wallet.

    After the transaction is successfully confirmed on-chain, your wallet will display the amount of received xfrxUSD LP tokens.

    If your wallet doesn’t support automatic token addition, add it manually as a custom token with the contract address 0xf1232a1ab5661abdd6e02c6d8ac9940a23bb0b84 on the Sonic network.

    2. Obtaining sUSDC_arb

    sUSDC_arb tokens on the Sonic network can be swapped from any available asset in the xsArbitrum pool via the CrossCurve app.

    1. Navigate to the Liquidity tab in the Yield section. Select the Balanced mode and click Next.

    Enter the desired amount to swap, approve the spending by clicking Approve, and sign the transaction in your wallet.

    Click Swap to execute the exchange and confirm the transaction in your wallet.

    1. If you know the swap direction, the exchange can be performed in the Trade tab using Advanced mode with any available asset.

    Note: Some directions may experience high slippage!

    3. Adding liquidity to xsArbitrum pool via Curve

    Navigate to the CrossCurve Stable ARB pool page: https://curve.finance/dex/sonic/pools/factory-stable-ng-73/deposit/ and connect your wallet.

    Enter the desired deposit amount in the Deposit tab. To avoid losses due to slippage, it’s recommended to deposit using the balanced method by clicking Add all coins in a balanced proportion (more details here).

    In the first transaction, approve the spending by clicking Approve Spending and sign the transaction in your wallet.

    In the second transaction, deposit the funds by clicking Deposit and sign the transaction in your wallet.

    After the transaction is confirmed on-chain, the amount of received xsArbitrum LP tokens will appear in your wallet and in the Your Details tab.

    If your wallet doesn’t automatically add the token, manually add it as a custom token using the contract address 0x440bcab62d629ba60ca56b80e565636e0c404e60 on the Sonic network.

    Initializing ownership through an upgradeable pattern.
  • Decoding calldata to separate out function-specific parameters from overhead bytes (e.g., selectors).

  • Validating slicing operations to prevent out-of-bounds data reads.


  • Inherited Contracts and Interfaces

    • UUPSUpgradeable (OpenZeppelin): Provides functions for upgrading this contract in a UUPS proxy setup, ensuring only the owner can authorize upgrades.

    • OwnableUpgradeable (OpenZeppelin): Implements ownership-related logic, allowing only the contract owner to perform certain actions.

    • ICalldataHelperV1: Declares the initialize and decode functions, as well as the InvalidSliceParameters error.


    Constants and State Variables

    This contract does not introduce new constants besides those inherited or implied from the interface. It also does not maintain any additional state variables beyond upgradeability and ownership structures provided by OpenZeppelin libraries.


    Constructor

    • Description:

      • Disables initializers to ensure this upgradeable contract cannot be re-initialized after deployment, following best practices for UUPS proxy pattern.


    External Functions

    initialize(address owner_)

    • Description:

      • Initializes the contract in an upgradeable context.

      • Sets up ownership by transferring ownership to the specified owner_.

      • Can only be called once due to the initializer modifier from OpenZeppelin.

    • Parameters:

      • owner_: The address of the contract owner.

    • Effects:

      • Calls __UUPSUpgradeable_init() and __Ownable_init(owner_), configuring the contract for UUPS upgradeability and ownership management.


    decode(bytes calldata calldata_)

    • Description:

      • Decodes the provided calldata to extract three main elements:

        1. m_calldata: The method-specific or function-specific bytes of calldata.

        2. m_target: The address the calldata is meant to target.

        3. m_chainId: The chain identifier for cross-chain or multi-chain scenarios.

      • Skips the first 4 bytes, typically used as a selector or prefix.

    • Parameters:

      • calldata_: The full calldata to decode, where the first 4 bytes are not part of the relevant data for extraction.

    • Return:

      • m_calldata: The extracted method calldata (bytes).

      • m_target: The extracted target address (address).

    • Logic:

      • Calls the private _slice function to remove the first 4 bytes.

      • Uses abi.decode(...) with a tuple (bytes, address, uint64, address) to decode the relevant fields (although the last address is ignored in this particular decode pattern).


    Internal and Private Functions

    _authorizeUpgrade(address)

    • Description:

      • Restricts contract upgrades so that only the owner may authorize them, protecting upgrade logic from unauthorized calls.


    _slice(bytes memory data_, uint256 start_, uint256 length_)

    • Description:

      • Extracts a slice from data_ starting at offset start_ for length_ bytes.

      • Reverts with InvalidSliceParameters if out-of-bounds.

      • Used internally by decode to remove the first 4 bytes (or any other arbitrary slice).

    • Parameters:

      • data_: The original bytes array to slice.

      • start_: The offset in data_ to begin slicing.

    • Return:

      • result_: A newly allocated bytes array of size length_, containing the requested slice.

    • Errors:

      • InvalidSliceParameters(): Thrown if start_ + length_ exceeds the length of data_.


    Errors

    InvalidSliceParameters()

    • Description: Indicates that the requested slice exceeds the bounds of the original array (start_ + length_ > data_.length).


    Summary

    CalldataHelperV1 provides a lightweight, upgradeable solution for parsing transaction calldata and extracting specific parameters like function-specific calldata, target addresses, and chain IDs. It integrates with standard libraries for safe upgradeability (UUPSUpgradeable) and ownership control (OwnableUpgradeable), ensuring secure and maintainable deployment. By strictly enforcing slice parameter checks and skipping the initial 4 bytes, CalldataHelperV1 simplifies the process of handling custom-encoded transaction data in cross-chain or proxied contexts.

    Using EYWA DAO NFTs further enhances your earnings when voting on pools.

    To start using the CrossCurve application, navigate to the Vote page under the DAO section. Click «Connect wallet», select your wallet from the list, and confirm the connection, ensuring you are on the official page: https://app.crosscurve.fi/vote-pools

    After successfully connecting your wallet, open the Pools tab to participate in pool voting.

    You will see the following details:

    • Current voting round ends in - Countdown timer indicating when the current voting round concludes

    • Total voting power available for this epoch - Combined voting power of all DAO participants for the current epoch

    • You have - Number of your locks and their voting power in veEYWA tokens

    • Voted - Number of your locks and the total veEYWA voting power you have already allocated this epoch

    • Ready for voting - Number of locks available for voting and their total veEYWA voting power

    • Estimated EYWA emission in the next epoch - Estimated EYWA token rewards allocated for the upcoming epoch

    • Estimated CRV emission in the next epoch - Estimated CRV token rewards allocated for the upcoming epoch

    • Estimated incentives available in the current epoch - Estimated incentives from partners allocated in the current epoch (in USD equivalent)

    In the window displaying participating voting pools, the following information appears:

    • Pools - Pool name and type (Stable pool**, Volatility pool*)

    • Chain - Network of the pool

    • Incentives - Amount of incentives allocated for votes on each pool during the current epoch

    • vAPR - Projected yield metric for the next epoch, calculated based on current pool votes and TVL

    • Select % vote - Select the percentage of your voting power allocated to the chosen pool

    • Votes sent - Percentage of voting power you have already allocated to each pool

    • Est. rewards - Estimated reward amount in USD equivalent

    CrossCurve offers two distinct liquidity pools to users: the Stable Pool and the Volatility Pool:

    * Volatility Pools consist of liquidity (Curve pools) for asset pairs with volatile prices, typically experiencing divergence. For example, USDT vs. EYWA or ETH vs. BTC. Volatile pairs are formed by combining uncorrelated assets and utilize Curve's unique impermanent loss compensation mechanism for pools containing volatile assets. ** Stable Pools are pools of stable liquidity (Curve pools) between assets whose prices are pegged to each other. For example, USDT vs. USDC.

    Another case involves derivative assets, such as wstETH and rETH. Although rETH is considered a volatile asset, the trading pair between wstETH and rETH is classified as a stable pool because the price of wstETH does not significantly fluctuate relative to rETH.

    Stable pairs on CrossCurve are designed for correlated assets and aim to maintain a 1:1 transfer ratio between them as closely as possible.

    To participate in voting, select the pool you're interested in, adjust the percentage of your voting power to allocate, and click Vote. Then, sign the transaction in your wallet.

    The total of your votes across all pools must equal 100% for the Vote button to become active.

    You can view detailed information about your submitted votes by expanding the Votes sent menu.

    To cancel your current vote for a specific pool, click Reset. To remove all your votes across all pools, click Reset all.

    When confirming vote cancellation, all your votes for the selected pool will be withdrawn. To proceed, click Ok and sign the transaction in your wallet.

    Locking EYWA
    incentives for voting
    pools
    veEYWA
    liquidity distribution and rewards
    veEYWA
    Locking EYWA
    Factory Pattern: It centralizes the instantiation of IncentiveRewardsDistributor contracts, simplifying the process of creating new distributors for different escrow managers.
  • Access Control: Only the escrow vote manager can call createRewardsDistributor, preventing unauthorized distribution contract creation.

  • Upgradeable via UUPS: Ensures the factory contract can be upgraded over time, with ownership-based control on upgrades.

  • By implementing IRewardsDistributorFactoryV1, RewardsDistributorFactoryV1 provides a standard interface for deployment logic and event transparency (though no new custom events are declared here beyond the interface's contract structure).


    Inherited Contracts and Interfaces

    • UUPSUpgradeable (OpenZeppelin): Provides the upgrade mechanism under the UUPS proxy standard, restricting upgrades to the contract owner.

    • OwnableUpgradeable (OpenZeppelin): Establishes ownership logic, allowing the owner to authorize upgrades and potentially modify other aspects of the factory (not used extensively here but available if needed).

    • IRewardsDistributorFactoryV1: Declares the initialize and createRewardsDistributor functions, along with an InvalidCaller error.

    Additional External References:

    • IncentiveRewardsDistributor: The contract being deployed by this factory. It manages incentive reward distributions for an escrow manager and is constructed with references to the escrow vote manager and escrow manager.


    State Variables

    • s_escrowVoteManager (address): The address of the escrow vote manager contract. Only this address may invoke createRewardsDistributor on the factory.


    Constructor

    • Description: Disables contract initializers to ensure initialize() can only be called once. A standard pattern for UUPS upgradeable contracts.


    External Functions

    1. initialize(address owner_, address escrowVoteManager_)

    • Description: Configures the factory contract by assigning ownership (owner_) and storing the escrow vote manager address. This function can be called only once due to the initializer modifier.

    • Parameters:

      • owner_: The address to be assigned as the owner of this factory contract.

      • escrowVoteManager_: The address of the escrow vote manager responsible for orchestrating new distributor creations.

    • Logic and Effects:

      1. Invokes __UUPSUpgradeable_init() and __Ownable_init(owner_) for upgrade and ownership setup.

      2. Sets s_escrowVoteManager = escrowVoteManager_.


    2. createRewardsDistributor(address escrowManager_)

    • Description: Creates and returns a new IncentiveRewardsDistributor contract instance, linking it to the calling escrow vote manager (msg.sender) and the provided escrowManager_. The call reverts if not invoked by s_escrowVoteManager.

    • Checks:

      • Must be called by s_escrowVoteManager. Otherwise, it reverts with InvalidCaller().

    • Logic:

      1. If msg.sender != s_escrowVoteManager, revert with InvalidCaller().

      2. Deploys a new IncentiveRewardsDistributor by calling its constructor:

    • Return:

      • address: The address of the newly created incentive rewards distributor contract.


    Internal Functions

    1. _authorizeUpgrade(address newImplementation)

    • Description: Restricts upgrades of this factory to the contract’s owner, following the UUPS standard. This ensures that only the owner can deploy a new logic implementation for this factory contract.


    Errors

    • InvalidCaller() Thrown if createRewardsDistributor is called by an address other than s_escrowVoteManager.


    Summary

    RewardsDistributorFactoryV1 provides a straightforward pattern for creating new IncentiveRewardsDistributor instances. By restricting calls to its createRewardsDistributor function to the escrow vote manager, it ensures that only authorized processes can spin up new distributor contracts. Coupled with UUPS upgradeability, the factory is future-proofed, allowing for modifications to how distributors are instantiated if the protocol’s requirements evolve over time.

    Custody of Funds: Holds ERC20 tokens and ETH in a secure manner.

  • Restricted Withdrawals: Only the contract’s owner can withdraw funds, specifying the token address, amount, and recipient.

  • Non-Reentrant Calls: Uses ReentrancyGuard to prevent complex re-entrancy exploits during withdrawals.

  • By implementing the ITreasury interface, Treasury provides a standardized API (the withdraw function) and emits an event (TokenWithdrawn) whenever funds are moved out.


    Inherited Contracts and Interfaces

    • Ownable (OpenZeppelin) Allows the contract to have an owner who can perform restricted operations. In this case, only the owner can call withdraw.

    • ReentrancyGuard (OpenZeppelin) Protects critical functions from re-entrancy attacks. The withdraw function uses the nonReentrant modifier.

    • ITreasury (Custom Interface) Declares the withdraw function signature and TokenWithdrawn event. The contract implements these specifications.

    Additional External References:

    • SafeERC20, IERC20 (OpenZeppelin): Used to safely transfer ERC20 tokens in the withdraw function.

    • Address (OpenZeppelin): Provides the sendValue method for securely transferring ETH.


    State Variables

    The Treasury contract does not introduce mutable storage variables beyond those inherited from its parent classes. However, it defines:

    • owner (Ownable.sol) A variable inherited from Ownable indicating the contract owner. Managed internally by the Ownable library’s _owner storage variable.

    No other custom state variables are defined. The contract relies on the OpenZeppelin libraries for ownership tracking and reentrancy control.


    Constructor

    • Description: The constructor takes a single parameter, owner_, which designates the address to be assigned as the contract owner via Ownable. This ownership implies exclusive access to withdraw.

    • Parameters:

      • owner_: The address that will be granted ownership of the contract upon deployment.

    • Effects:

      • Calls Ownable(owner_) constructor to set the provided owner_ as the owner.

      • No additional logic is performed here.


    Fallback Function

    • Description: A receive fallback function that allows the contract to accept native ETH transfers (e.g., via send or transfer with no calldata). This function does not store or otherwise process the ETH, aside from receiving it into the contract’s balance.


    External Functions

    withdraw(address token_, uint256 amount_, address recipient_)

    • Description: Allows the contract owner to withdraw either an ERC20 token or native ETH from the treasury to a specified recipient_. If token_ is the zero address (address(0)), it indicates a withdrawal of ETH. Otherwise, it withdraws the specified ERC20 token using a safe transfer.

    • Parameters:

      • token_: The address of the ERC20 token to withdraw. If address(0), the function sends ETH instead of tokens.

      • amount_: The amount of tokens (or ETH) to withdraw.

      • recipient_: The address that will receive the withdrawn tokens or ETH.

    • Checks & Effects:

      1. The function uses onlyOwner to ensure only the contract’s owner can invoke it.

      2. Uses nonReentrant from ReentrancyGuard to prevent nested re-entrant calls.

    • Events:

      • Emits TokenWithdrawn(token_, amount_, recipient_) upon a successful withdrawal, logging details for transparency.


    Events

    TokenWithdrawn(address indexed token, uint256 indexed amount, address indexed recipient)

    • Emitted When: The withdraw function completes successfully, whether removing ETH or ERC20 tokens.

    • Parameters:

      • token: The address of the token being withdrawn. Zero address if ETH.

      • amount: The quantity of tokens or ETH withdrawn.

      • recipient: The address that received the withdrawn funds.


    Summary

    Treasury acts as a straightforward contract for securely holding and releasing ETH or ERC20 tokens under the CrossCurve ecosystem. With Ownable restricting withdraw calls to the contract owner and ReentrancyGuard ensuring robust security, the Treasury provides a trustworthy store for tokens:

    1. Secure Custody: Only an authorized owner can move assets out.

    2. Versatile Withdrawals: Supports both ETH and arbitrary ERC20 tokens using standardized SafeERC20 operations.

    3. Transparent Logging: The TokenWithdrawn event ensures on-chain traceability of funds outflow.

    This minimal approach ensures clarity, security, and traceable control over treasury assets within the CrossCurve framework.

    https://ftmscan.com/address/0x7ce8aF75A9180B602445bE230860DDcb4cAc3E42
    https://layerzeroscan.com/?srcChainKey[0]=fantom
    EYWA NFT Manager
    OpenSea
    https://opensea.io/collection/eywa-nft-4
    EYWA NFT Manager
    here
    OpenSea
    https://app.crosscurve.fi/nft-manager
    e-mail
    here

    Working with the EYWA Locker contract in Arbiscan.

    Creating a lock for a vesting safe

    How to find the claimed safe:

    1. Open , and enter the wallet address that received the vesting safe in the search bar, or enter the link in the format {wallet address}, replacing {wallet address} with your wallet address.

    In the list of , filter by the “Claim” function under Method.

    1. In the filtered list, find the claim transaction. To locate the safe addresses, open Transaction Details by clicking on the chosen transaction.

    1. Find the safe address in the Transaction Action or ERC-20 Tokens Transferred, checking the amount of EYWA tokens in that safe.

    1. To copy the safe address, click on it and copy it to your clipboard.

    Make sure you remember the address(es) of the safe(s) that you plan to deposit into the .

    How to create a lock for a safe whose address you already know

    1. Go to the EYWA Locker contract page: 0xdCa5d16ac3708658ECc971d3AeE5d5CD6e5E1faD , choose and connect your wallet by clicking

    1. Expand the 5t line, createLock, and fill in the fields:

    lockDuration_(unit256) - the lock duration in seconds

    recipient_(address) - the wallet address of the lock’s owner (it’s important that you have access to this wallet)

    vestingWallets_(address[]) - the array of safe addresses*

    * for locking a single safe, enter the safe address [address] in the square brackets in the field vestingWallets_(address[]). For two safes, [address1, address2], and so on.

    1. After the filling in the required fields, click the button and sign the transaction in your wallet.

    Once the transaction is successfully processed on-chain, you will receive an EYWA DAO NFT in your wallet.

    To later boost your votes, remember the ID (EYWA DAO NFT ID) of the created lock.

    1. Go to your wallet page and expand the TOKEN HOLDINGS list in the Overview tab.

    1. Find the EYWA DAO NFT you received after creating the lock and open its token page.

    1. Find your EYWA DAO NFT ID in the transaction list under the Item column or on the Transaction Details page in the ERC-721 Tokens Transferred section.

    Boosting votes by adding an NFT.

    To receive a boost, you must have the EYWA DAO NFT on the same address that you created the lock from, and you must know its ID.

    1. Go to the EYWA NFT contract address 0x33b98A477512A34Af0D311DA5F59FC5341693962 page: and confirm the lock for this NFT in the contract.

    Select and then click

    1. Expand the “approve” first line and fill in the fields:

    to - address of the Locker contract 0xdca5d16ac3708658ecc971d3aee5d5cd6e5e1fad

    tokenid(unit256) - The ID of the NFT to receive the boost. (If you need boosts for multiple NFTs, repeat this operation for each NFT)

    Voting boost

    1. Go the the EYWA Locker contract address page 0xdca5d16ac3708658ecc971d3aee5d5cd6e5e1fad

    2. Select then clickand connect your wallet by pressing

    1. Expand the “boost” second line and fill in the fields:

    tokenid_(unit256) - The ID of the lock (EYWA DAO NFT ID), to be boosted.

    collectionTokenIds_(unit256) - the ID(s) of the NFT(s), that will provide the voting boost (If you have only one NFT, enter [id]. For multiple NFTs, [id1, id2], and so on).

    1. After entering the information, click the button and sign the transaction in your wallet. To see your updated voting power, go to the interface.

    EYWA NFT

    NFT collection description

    The Eywa NFT collection includes 53 996 unique NFTs. Their number diminishes as they are merged.

    The collection represents four mythical characters: Magician, Dryad, Ant, and Spider. EYWA NFTs are an example of generative art where each character features randomized attributes that grant it uniqueness.

    Eywa NFT Characters

    EYWA pool via Convex

    Curve inflation is directed to EYWA pools on Convex, and now liquidity providers receive incentives in CRV

    For example, the yield in the is currently as follows:

    Base Curve vAPR: 2.69%

    CRV vAPR (incl. 2.5x boost): 212.07%

    Total vAPR: 214.76%

    GaugeFactoryV1

    Overview

    GaugeFactoryV1 is an upgradeable factory contract responsible for deploying and initializing Gauge contracts within the CrossCurve ecosystem. These gauges are used to manage and distribute rewards for various liquidity pools or other vote-driven incentives. The factory integrates with an Escrow Vote Manager to ensure that only the authorized vote manager can create new gauges, thus maintaining a secure and controlled environment for gauge deployments.

    Key Roles and Features:

    constructor() {
        _disableInitializers();
    }
    function initialize(address owner_) external initializer
    function decode(bytes calldata calldata_) external pure returns (
        bytes memory m_calldata,
        address m_target,
        uint64 m_chainId
    )
    function _authorizeUpgrade(address) internal override onlyOwner
    function _slice(
        bytes memory data_, 
        uint256 start_, 
        uint256 length_
    ) private pure returns (bytes memory result_)
    address public s_escrowVoteManager;
    constructor() {
        _disableInitializers();
    }
    function initialize(address owner_, address escrowVoteManager_) external initializer
    function createRewardsDistributor(address escrowManager_) external returns (address)
    function _authorizeUpgrade(address) internal override onlyOwner
    constructor(address owner_) Ownable(owner_) {}
    receive() external payable {}
    function withdraw(
        address token_,
        uint256 amount_,
        address recipient_
    )
        external
        onlyOwner
        nonReentrant
    0x7ce8aF75A9180B602445bE230860DDcb4cAc3E42

    m_chainId: The extracted chain identifier (uint64).

    length_: Number of bytes to copy into the new array.
    If token_ == address(0), uses Address.sendValue to send amount_ of ETH to recipient_.
  • Otherwise, calls safeTransfer on IERC20(token_) to transfer amount_ tokens to recipient_.

  • Returns the newly created contract’s address.
    new IncentiveRewardsDistributor(msg.sender, escrowManager_)

    The characters in the collection are unique creations, drawing inspiration from beloved science fiction universes.

    The Magician Crafted from leaves and various flora types, the magician is inspired by the Star Wars universe and Elemental creatures, as well as ancient Roman and Greek mythology.

    The Dryad This character is inspired by ancient Greek myths, aliens, and the golden era of science fiction, presenting a stunning fusion of a wood nymph with a World of Warcraft (WoW) hero.

    The Ent Assembled from tree bark and roots, the Ent is inspired by the Ents from the Lord of the Rings (LOTR) universe, Swamp Thing from DC Comics, and Groot from Marvel.

    The Spider The spider character embodies an aggressive, dynamic figure, combining an arachnid with a trickster — a mix of Baal from Diablo II, Monsters, Inc., and other characters, infused with elements of insects and alien life forms.

    We have deliberately directed our design team to embrace a “fairytale” aesthetic in the creation of our characters' likenesses. Regardless of age, we all cherish a touch of magic in our lives.

    Echoing the words of Steve Jobs: “Follow your heart, stay hungry, stay foolish!” we are committed to developing the finest cross-chain product on the market. Thank you for your support!

    The collection is broken down into five levels of rarity: Common, Uncommon, Rare, Legendary, and Infinity. The rarest of all are the Magician Infinity NFTs, of which there are only 193 in the entire EYWA NFT collection.

    Common
    Uncommon
    Rare
    Legendary
    Infinity

    Currently, the collection is available on the Aurora and Arbitrum networks:

    On the Aurora network, the collection is available for trading within our Telegram communities (Links to Telegram chats for trading Eywa NFTs: English speaking region CIS region).

    On the Arbitrum network, the collection is available for trading on OpenSea.

    Here is the Eywa NFT collection address in Aurora and Arbitrum.

    The utility of EYWA NFTs

    The EYWA NFT collection is composed of ERC-721 tokens with the following unique functions:

    • Container function for storing up to 1 500 000 EYWA tokens

    • Merge function that allows you to increase the size of the container and the rarity of the NFT by combining multiple NFTs of one level into one rarer NFT

    • CrossCurve DAO vote multiplier function via veEYWA

    Container

    Each NFT in the collection functions as a container for EYWA tokens. You can attach both unlocked and locked (in vesting safes*) tokens to the NFT. This allows the user to sell blocked EYWA tokens at any time.

    * Vesting safes are objects containing EYWA tokens that are blocked for a certain period of time based on the rules of the funding round (detailed information about the rules of each round and vesting periods are available here).

    The capacity of each NFT is the maximum number of EYWA tokens it can contain and depends on the rarity of the NFT. The highest capacity — 1 500 000 EYWA — is reserved for the Infinity rarity level NFTs. In the Aurora chain, you can see your current balance of token in the container. Once migrated to the Arbitrum chain, the tokens will be separated from the NFT and can be received as vesting safes via the Claim portal after the TGE.

    For details, see the table below:

    Rarity
    Capacity per NFT

    common

    500

    uncommon

    3 000

    rare

    25 000

    legendary

    250 000

    infinity

    1 500 000

    Merge

    Several NFTs of the same type can be merged to create a single NFT with a higher rarity level. This will also merge all of the tokens contained in the source NFTs.

    Multiplier table for NFT merging:

    Rarity
    Merge multiplicator
    You will receive

    common

    5

    1 uncommon

    uncommon

    7

    1 rare

    rare

    9

    1 legendary

    legendary

    n/a

    veEYWA voting multiplier

    To vote in the EYWA DAO, users must lock EYWA tokens — the longer the lock period, the more voting power the user gets. Using EYWA NFTs can also increase voting power. Each NFT can increase the number of available votes by the maximum number of tokens it can contain.

    For details, see the table below:

    Rarity
    Maximum amount of tokens for boost
    Multiplier for veEYWA votes

    common

    500

    1.006

    uncommon

    3 000

    1.036

    rare

    25 000

    1.3

    legendary

    250 000

    For example, a user with 100,000 EYWA tokens can use one Legendary NFT to give his votes a 2.8 multiplier, since a Legendary NFT type can cover up to 250,000 tokens, or 4 Rare NFTs a 1.3x multiplier each (since each Rare NFT can only cover 25,000). Users can use any number and combination of NFTs for veEYWA vote multipliers to cover all of their holdings of EYWA.

    Migration to Arbitrum

    After the NFT collection is migrated to the Arbitrum chain, all of the above functions will become available. Before the TGE, we will open up a bridge to move the NFTs from Aurora to Arbitrum, as well as the NFT Manager to fully engage with all of the functions of the NFTs.

    The NFT Manager will ensure access to tokens contained in the NFTs, which will be separated from their containers after the migration to Arbitrum and be put together in each user’s wallet. Users will be able to put tokens into vesting safes and keep rEYWA in the NFTs.

    To achieve this yield, you need to complete a few simple steps:

    Purchasing the EYWA token

    You can purchase the EYWA token on CEX or DEX. The list of available exchanges can be viewed here: https://www.coingecko.com/en/coins/eywa

    or here: https://coinmarketcap.com/currencies/eywa/#Markets

    CrossCurve DEX

    Let’s consider an example of purchasing the EYWA token with USDT on the CrossCurve DEX.

    EYWA tokens can be purchased on CrossCurve for any assets available in the app (USDT, USDC, crvUSD, DAI, ETH, BTC etc.)

    Attention! Be aware of possible high slippage before making an exchange to avoid loss of funds.

    To purchase EYWA with USDT, you need to have USDT in your wallet on the Arbitrum network and ETH in the Arbitrum network to pay for transaction gas in Gwei (gas cost can be checked here - https://arbitrum.blockscout.com/gas-tracker).

    Go to https://crosscurve.fi and use the quick link Buy EYWA → Buy on CrossCurve and click Connect wallet

    Select the wallet installed in your system and confirm the connection to the application in your wallet

    After successfully connecting the wallet, the application will direct you to the EYWA - USDT trading pair on the Arbitrum network. Enter the desired amount for exchange and click Approve USDT

    Sign the USDT spending transaction in your wallet

    To complete the exchange, click Swap

    Sign the exchange transaction in your wallet

    Wait for the on-chain transaction to complete

    Providing liquidity in the USDT+EYWA pool

    Go to the Liquidity page in the Yield section

    In the Choose pool list, select EYWAUSDT pool, the Deposit operation, the Easy mode operation type, and click Next

    Enter the amount of EYWA tokens and click Approve EYWA

    Sign the EYWA spending transaction in your wallet

    To complete the transaction, click Swap

    Sign the exchange transaction in your wallet

    Wait for the on-chain transaction to complete

    Go to the Stake page in the Curve section on https://curve.convexfinance.com/stake and connect your wallet

    In the Stake Curve LP Tokens section, select Arbitrum One chain, enter EYWA in the Search pools field and the application will display USDT+EYWA pool

    Enter the amount of EYWAUSDT LP tokens and click Approve

    Sign the EYWAUSDT LP spending transaction in your wallet

    To stake EYWAUSDT LP, click Deposit & Stake

    Sign the depositing & staking transaction in your wallet

    After the on-chain transaction is completed, the provided liquidity will be displayed in the My Deposits field, and the accrued rewards will be displayed in the Claimable field

    USDT+EYWA pool
    Gauge Deployment: Deploys a new GaugeV1 instance as an upgradeable proxy (using ERC1967Proxy), specifying an implementation, an owner, and initial parameters for reward distribution campaigns.
  • Access Control: Restricts createGauge calls to the escrow vote manager (s_escrowVoteManager).

  • Upgradeable via UUPS: Uses UUPSUpgradeable and OwnableUpgradeable patterns, restricting contract upgrades to the owner.

  • By implementing IGaugeFactoryV1, GaugeFactoryV1 provides a standardized interface and event structure for gauge creation, enabling other contracts in the CrossCurve ecosystem to request new gauges securely.


    Inherited Contracts and Interfaces

    • UUPSUpgradeable (OpenZeppelin): Provides upgrade functionality using the UUPS proxy pattern. Only the owner can authorize upgrades.

    • OwnableUpgradeable (OpenZeppelin): Establishes ownership and restricts certain critical functions (like upgrades) to the contract owner.

    • IGaugeFactoryV1: Declares functions (initialize and createGauge) and the GaugeCreated event. Also defines the InvalidCaller error.

    Additional External References:

    • ERC1967Proxy (OpenZeppelin): A proxy implementation that stores the logic contract address in storage per EIP-1967.

    • IDistributionCreator.CampaignParameters: Used to initialize reward distribution parameters for newly created gauges.

    • GaugeV1: The gauge implementation contract being deployed as a proxy.


    State Variables

    • s_escrowVoteManager (address): The address of the escrow vote manager contract authorized to create new gauges. Only s_escrowVoteManager can call the createGauge function.


    Constructor

    • Description: Disables initializers to prevent re-initialization in a UUPS upgradeable setup. Ensures the initialize function can only be called once.


    External Functions

    initialize(...)

    • Description: Initializes the factory contract by setting the contract owner (owner_) and the escrow vote manager (escrowVoteManager_). This function can only be called once due to the initializer modifier.

    • Parameters:

      • owner_: The address designated as the owner of this factory.

      • escrowVoteManager_: The address of the authorized escrow vote manager contract.

    • Effects:

      • Calls __UUPSUpgradeable_init() to set up the UUPS upgrade mechanism.

      • Calls __Ownable_init(owner_), assigning ownership to owner_.


    createGauge(...)

    • Description: Deploys and initializes a new GaugeV1 contract as an ERC1967Proxy, passing in the gauge implementation address, initialization arguments, and returning the newly created gauge address.

    • Parameters:

      • owner_: The address that will become the owner of the new gauge contract.

      • eywa_: The address of the EYWA token the gauge will handle for reward distribution.

      • campaignParameters_: A struct of parameters (e.g., schedule, amounts) used by the gauge for reward distribution.

    • Checks:

      • The caller must be s_escrowVoteManager. Otherwise, InvalidCaller() is thrown.

    • Logic:

      1. Deploys a new GaugeV1 implementation contract.

      2. Instantiates an ERC1967Proxy pointing to that implementation.

      3. Encodes the constructor arguments (owner, escrow vote manager address, EYWA token address, campaign parameters) for the gauge’s

    • Return:

      • address: The newly deployed gauge proxy contract.

    • Events:

      • GaugeCreated(m_gauge, m_implementation): Indicates a new gauge contract was created.


    Internal Functions

    _authorizeUpgrade(address)

    • Description: Restricts the contract’s upgrade function (in a UUPS proxy context) to the owner, ensuring unauthorized parties cannot upgrade the factory logic.


    Events

    GaugeCreated(address indexed gauge, address indexed implementation)

    • Emitted When: A new gauge contract is deployed via createGauge.

    • Parameters:

      • gauge: The address of the newly created gauge (proxy).

      • implementation: The address of the gauge implementation contract used for the new proxy.


    Errors

    InvalidCaller()

    • Description: Thrown if createGauge is called by an address other than s_escrowVoteManager. Ensures gauge creation is limited to the authorized escrow vote manager.


    Summary

    GaugeFactoryV1 securely and upgradeably deploys GaugeV1 contracts under the control of the escrow vote manager. By enforcing that only the designated manager can call createGauge, it prevents unauthorized deployments while still allowing flexible, time-extended reward distribution campaigns. The combination of UUPS upgradeability, ownership checks, and a standardized creation event (GaugeCreated) supports a robust, maintainable environment for launching new gauges in the CrossCurve ecosystem.

    Arbiscan
    https://arbiscan.io/address/
    Locker
    https://arbiscan.io/address/0xdca5d16ac3708658ecc971d3aee5d5cd6e5e1fad#writeContract
    https://arbiscan.io/address/0x33b98A477512A34Af0D311DA5F59FC5341693962
    https://arbiscan.io/address/0xdca5d16ac3708658ecc971d3aee5d5cd6e5e1fad#writeContract
    Locker

    Obtaining veEYWA and Calculating the Boost

    In order to become a participant in CrossCurve DAO, you need to lock your EYWA tokens or EYWA NFT along with them.

    Users can lock EYWA tokens for up to 3 years, receiving veEYWA — their voting power in the DAO. The longer the lock duration and the higher the NFT rarity, the greater the participant’s voting power (influence) in the DAO and the more incentives and benefits they gain.

    Voting power decreases as the token unlock time approaches unless the lock is extended. This encourages long-term commitment, strengthens the project’s stability, and allows participants to actively influence its development.

    EYWA NFTs multiply veEYWA, increasing voting power, income, and a user's influence in the DAO. To do this, you must attach EYWA tokens or one or more Vesting Safes containing EYWA tokens to an EYWA NFT.

    A Vesting Safe is a special contract from the CrossCurve team that stores locked EYWA tokens. The tokens in the safe unlock according to an algorithm matching the type of round in which they were received.

    The Locker is a smart contract where owners lock their EYWA tokens for various durations. The purpose of locking is to obtain voting power in the form of veEYWA. Voting power depends on the lock duration: the longer the lock, the greater the voting power for the same number of locked tokens.

    • Maximum lock duration: 3 years (156 weeks), providing the maximum ratio: 1 locked token = 1 vote.

    • Minimum lock duration: a few days (until the end of the current epoch). For example, 2 days give 2/1092 of a vote.

    Example: 156 tokens locked for one week give 1 vote.

    The formula for the linear relationship between lock time and voting power boost is:

    Where T is the lock time in weeks (Formula 1)


    Features of setting lock time in a smart contract when creating a lock

    When working with the smart contract, note that the contract automatically "rounds" the submitted lock date to the end of the previous epoch (Thursday 00:00 UTC). This means that if a date falls on a Friday, Saturday or Monday, the smart contract will set the lock time to the preceding Thursday.

    To accommodate this behavior, the website interface for interacting with the sends a especially calculated date, to the smart contract:

    where:

    - the current time,

    - time remaining until the end of the current epoch,

    - the duration of one epoch (1 week),

    n - the number of weeks the user wants to lock tokens.

    Additionally, the total lock time cannot exceed 156 epochs (weeks).

    Due to these mechanics, achieving a value equal to 1 is nearly impossible. The closest approximation can only occur if a locking transaction is sent for 156 weeks immediately after the start of a new epoch, such as Thursday at 00:00:01 UTC. In that case:

    However, time constantly moves forward, and even a minute later:

    Whether or not to continuously update the lock time, and at what intervals, is a decision each DAO participant must make individually based on their own objectives and intentions.

    The total votes a token holder has are calculated using the formula:

    Where:

    • is the number of tokens locked by the owner i, considering NFT boosts,

    • is the lock-time coefficient for user i,

    • n is the number of users who have locked their EYWA tokens

    (Formula 2)


    EYWA DAO NFT

    EYWA DAO NFT is an ERC-721 NFT created when EYWA tokens are locked in the .

    Key features:

    • Attaching assets: Each EYWA DAO NFT can have EYWA tokens, Vesting Safes, and other EYWA NFTs attached to it.

    • Obtaining veEYWA: The obtained veEYWA is automatically tired to the corresponding EYWA DAO NFT.

    • Multiple ownership: A user can own an unlimited number of EYWA DAO NFT.

    • Summation of veEYWA: The total amount of a user’s veEYWA is equal to the sum of the veEYWA of all their EYWA DAO NFTs.

    Thus, EYWA DAO NFT serves as a hub for managing your locked assets and voting power in the DAO, providing flexibility and scalability in project governance.


    Creating an EYWA DAO NFT

    When creating an EYWA DAO NFT in the Locker, you can lock EYWA tokens in various states When transferring to the Locker:

    1. EYWA tokens (standard ERC-20)

    • Ownership is transferred to the contract.

    1. Vesting Safe contracts with direct ownership (held in the user’s wallet)

    • Ownership of the Vesting Safe contract is transferred to the Locker.

    1. Vesting Safe contracts with ownership via an NFT (Vesting Safe contracts attached to an EYWA NFT)

    • The Vesting Safe is detached from an EYWA NFT and transferred to the Locker.

    • The EYWA NFT ownership is also transferred to the Locker.

    1. ERC-20 EYWA tokens with ownership via an NFT (EYWA tokens attached to an EYWA NFT)

    • Tokens are detached from an EYWA NFT and transferred to the Locker.

    • Ownership of an EYWA NFT is also transferred to the Locker.

    Calculating veEYWA:

    The calculates the amount of veEYWA based on the total number of EYWA tokens locked, including both standard ERC-20 tokens and those in the Vesting Safe.

    Restrictions when creating an EYWA DAO NFT

    • You cannot create an EYWA DAO NFT by adding an empty EYWA NFT to the Locker.

    • You can attach no more than 100 Vesting Safes and 100 EYWA NFTs to one EYWA DAO NFT.


    Modifying an EYWA DAO NFT

    You can modify an EYWA DAO NFT in several ways:

    Adding additional EYWA tokens:

    • You can lock more EYWA tokens in any of the ways described above at the time of creating an EYWA DAO NFT.

    Adding/attaching empty EYWA NFTs:

    • You can attach additional empty EYWA NFTs to an existing EYWA DAO NFT.

    Removing/detaching EYWA NFTs:

    • You can detach an EYWA NFT from an EYWA DAO NFT, returning them to the user’s ownership.

    Extending the lock duration of tokens:

    • You can extend the lock duration of already locked EYWA tokens to increase voting power.


    Increasing veEYWA using EYWA NFTs

    EYWA NFT Collection

    A released collection EYWA NFTs allows users to increase their voting power in the DAO. To do this, you must attach your NFTs from this collection in the. When sending NFT tokens, they are locked under different conditions than standard EYWA tokens.

    Attaching and Detaching EYWA NFTs

    • Attaching EYWA NFTs:

      • When one or more EYWA NFTs are added to an EYWA DAO NFT, a boost is applied to the locked EYWA tokens, increasing voting power.

    • Detaching EYWA NFTs:


    NFT Rarity Types and Their Characteristics

    Rarity
    Multiplier for veEYWA (MV)
    Capacity per NFT (CT)

    MV (Multiplier for veEYWA): A multiplier that increases veEYWA.

    CT (Capacity per NFT): The maximum number of EYWA tokens affected by an NFT.


    Calculating the NFT Boost to Increase Voting Power

    total number of tokens locked by the owner

    number of tokens of the same rarity locked by the owner

    - this is the total number of tokens that can be affected by NFT boosts (Formula 3)

    If is greater than or equal to , then the overall boost formula is:

    (Formula 4)

    If is greater than , it means the volume of tokens that could theoretically be influenced by the NFT boost is greater than the owner’s tokens. Therefore, we must fairly allocate the available token volume for the greatest results. For that, we use the following algorithm:

    1. =*1500000

    2. If is less than or equal to , then = *3;

    3. Else: = *3; =-

    4. =*250000

    The final is then used to determine the amount of veEYWA votes owned by the token holder.

    Examples of NFT Boost Calculations

    1. Example: 1 000 000 tokens and one Legendary NFT are locked (=1). Using the Formula 3: =0*500+ 0*3000+0*25000+1*250000+0*1500000 = 250000

    Since is greater than , we shall use the Formula 4:=1000000-250000+0*500*1.006+ 0*3000*1.036++0*25000*1.3+1*250000*2.8+0*1500000*3 = 750000+700000=1450000

    1. Example. 1 000 000 tokens and ten Legendary NFTs are locked (=10). Using the Formula 3: =0*500+ 0*3000+0*25000+10*250000+0*1500000 = 2500000

    Since is less than , we cannot use the Formula 4. Therefore, we shall use the following algorithm:

    ==1 000 000

    =*1500000=0

    is greater than , therefore

    = *3=0; =- = 1 000 000

    =*250000 = 10* 250 000 = 2 500 000

    If is less than or equal to , therefore the final calculations are equal to: =+ *2.8 = 0+1 000 000 *2.8 = 2 800 000

    1. Example. 2 000 000 tokens,1 Infinity NFT ( =1) and 10 Legendary NFTs are locked(=10). Using the Formula 3, we get: =0*500+ 0*3000+0*25000+10*250000+1*1500000 = 4 000 000

    Since is less than , we cannot use the Formula 4. Therefore, we shall use the following algorithm:

    ==2 000 000

    =*1500000 =1*1 500 000

    is greater than , therefore

    = *3=4 500 000; =-=2 000 000 -1 500 000 = 500 000

    =*250000=10*250 000 = 2 500 000

    is less than , therefore the final calculations are equal to: =+ *2.8=4 500 000 + 500 000*2.8 = 5 200 000


    Maximum Possible Number of Votes

    The CrossCurve protocol provides a unique system that allows reaching a maximum number of votes — 2 820 221 429. This figure is achieved through a combination of EYWA tokens and NFT multipliers, as well as their optimal distribution according to capacity.


    Protection Against Front-Running Front-running is a practice in which someone (usually a trader or bot) gains information about an upcoming transaction and uses it to execute a trade earlier, thereby gaining an advantage.

    In the new version of our NFT collection, a “freeze” mechanism has been introduced. After detaching tokens from an NFT, a 4-hour period is activated during which the NFT cannot be moved. This prevents the aforementioned unscrupulous practice: if a user attempts to detach tokens from an NFT being sold. They cannot finalize the deal since the NFT cannot be transferred to the buyer. As a result, only buyers who possess tokens will be able to purchase the NFT, reducing the risk of front-running.

    Furthermore, the mechanism also applied to cases where tokens are locked in the DAO Locker. This means that when locking an NFT in the Locker, the same 4-hour “freeze” applies. This delay is necessary to ensure the system’s security and prevent abuse. Users should keep this feature in mind to avoid misunderstandings. It’s important to plan NFT-related actions with a “freeze” period in mind.

    Adding liquidity to pools on Taiko

    To provide liquidity in the or pool on the Taiko network, you need to obtain or LP tokens. These LP tokens consist of two assets: the stablecoin and the synthetic derivative, or and , respectively.

    Since the CrossCurve Stable and CrossCurve WETH pools have migrated from the Sonic network to the Taiko network, you need to acquire the assets on the new network in order to receive the LP tokens.

    You must hold ETH

    GaugeV1

    Overview

    GaugeV1 is an upgradeable contract used to manage reward distributions for a particular pool or strategy in the CrossCurve ecosystem. The contract primarily integrates with the Escrow Vote Manager (s_escrowVoteManager) to authorize reward notifications and uses a Distribution Creator (DISTRIBUTION_CREATOR) for executing reward distribution campaigns.

    Key features include:

    address public s_escrowVoteManager;
    constructor() {
        _disableInitializers();
    }
    function initialize(address owner_, address escrowVoteManager_) external initializer
    function createGauge(
        address owner_,
        address eywa_,
        IDistributionCreator.CampaignParameters calldata campaignParameters_
    ) 
        external 
        returns (address)
    function _authorizeUpgrade(address) internal override onlyOwner

    Sets s_escrowVoteManager to escrowVoteManager_.

    initialize
    function call via the proxy.
  • Emits the GaugeCreated event with the new gauge’s proxy address and the gauge implementation address.

  • n/a

    infinity

    n/a

    n/a

    2.8

    infinity

    1 500 000

    3

    • If an EYWA DAO NFT did not participate in pool voting in the current epoch:

      • EYWA NFTs can be attached at any time.

    • If an EYWA DAO NFT participated in pool voting in the current epoch:

      • The attached EYWA NFTs involved in voting cannot be detached

      • To detach them, you must cancel the vote for the pools.

    Infinity

    3

    1 500 000

    If is less than or equal to , then: =+ *2.8;

  • Else: = + ; =-

  • =*25000

  • If is less than or equal to , then =+ *1.3;

  • Else: = + ; =-

  • =n*3000

  • If is less than or equal to , then =+ *1.036;

  • Else: = + ; =-

  • =*500

  • The overall results are equal to =+ *1.006

  • G=T156G=\frac{T}{156}G=156T​
    Tlockoutend=Tnow+Tendcurrentepoch+n∗Tepoch+24hourT_{lockout end} = T_{now} + T_{end current epoch} + n * T_{epoch} + 24 hourTlockoutend​=Tnow​+Tendcurrentepoch​+n∗Tepoch​+24hour
    G=156∗7∗24∗60−1156∗7∗24∗60G = \frac{156*7*24*60-1}{156*7*24*60}G=156∗7∗24∗60156∗7∗24∗60−1​
    G=156∗7∗24∗60−61156∗7∗24∗60G = \frac{156*7*24*60-61}{156*7*24*60}G=156∗7∗24∗60156∗7∗24∗60−61​
    VveEYWA=∑i=1nVi∗GiV_{veEYWA} = \sum^n_{i=1}V_{i}*G_{i}VveEYWA​=i=1∑n​Vi​∗Gi​

    Common

    1,006

    500

    Uncommon

    1,036

    3 000

    Rare

    1,3

    25 000

    Legendary

    2,8

    Vrarity=Ncommon∗500+Nuncommon∗3000+Nrare∗25000+Nlegendary∗250000+Ninfinity∗1500000V_{rarity} = N_{common}*500+N_{uncommon}*3000+N_{rare}*25000+N_{legendary}*250000+N_{infinity}*1500000Vrarity​=Ncommon​∗500+Nuncommon​∗3000+Nrare​∗25000+Nlegendary​∗250000+Ninfinity​∗1500000
    Vresult=Vall−Vrarity+Ncommon∗500∗1.006+Nuncommon∗3000∗1.036++Nrare∗25000∗1.3+Nlegendary∗250000∗2.8+Ninfinity∗1500000∗3V_{result} = V_{all}-V_{rarity}+N_{common}*500*1.006+ N_{uncommon}*3000*1.036+ +N_{rare}*25000*1.3+N_{legendary}*250000*2.8+N_{infinity}*1500000*3Vresult​=Vall​−Vrarity​+Ncommon​∗500∗1.006+Nuncommon​∗3000∗1.036++Nrare​∗25000∗1.3+Nlegendary​∗250000∗2.8+Ninfinity​∗1500000∗3
    Vtemp=VallV_{temp} = V_{all}Vtemp​=Vall​
    Locker
    Locker
    EYWA Locker
    Locker
    Locker
    Locker

    250 000

    on the
    Taiko
    network in your wallet to pay the gas fees.

    Swapping assets from Sonic to Taiko

    If you previously participated in the CrossCurve Stable TAI or CrossCurve WETH TAI pools on the Sonic network, you need to perform a number of steps to obtain the new assets on the Taiko network:

    xsTaiko → xsoTaiko

    If you hold xsTaiko LP tokens on the Sonic network, you need to go to the pool page: https://www.curve.finance/dex/sonic/pools/factory-stable-ng-78/withdraw/ and perform a Withdraw of the LP tokens, receiving xfrxUSD and s2Pool_t for the CrossCurve Stable TAI pool.

    We recommend performing the Withdraw in Balanced mode to reduce loss risk due to slippage.

    The xfrxUSD and s2Pool_t tokens from the xsTaiko pool on the Sonic network can be exchanged for USDC and sxfrxUSD_s on the Taiko network, respectively:

    Go to the Liquidity tab in the Yield section on the xsTaiko pool page: https://app.crosscurve.fi/liquidity?pool=0xedcf9ef9b389a8f52e81958d8212faf6fbd758ae&type=curve&action=withdraw&input=0x54f0055f387e7dcbfa060eaed81ea8bf1f6c808f&output=0x07d83526730c7438048d55a4fc0b850e2aab6f0b&chainIn=146&chainOut=167000

    Select the Withdraw action in Balanced mode and click Next.

    Enter the amount of s2Pool_t tokens and perform the Swap to USDC.

    Go to the Liquidity tab in the Yield section on the xsoTaiko pool page: https://app.crosscurve.fi/liquidity?pool=0xa17aa5ee656849221c8d9d062894e1145cbda864&type=curve&action=deposit&input=0xf1232a1ab5661abdd6e02c6d8ac9940a23bb0b84&output=0xb1712abdaf3f2959c0d5063e827ddb8183145f11&chainIn=146&chainOut=167000

    Select the Deposit action in Balanced mode and click Next.

    Enter the amount of xfrxUSD tokens and perform the Swap to sxfrxUSD_s.

    xeTaiko → xeoTaiko

    If you hold xeTaiko LP tokens on the Sonic network, you need to go to the pool page: https://www.curve.finance/dex/sonic/pools/factory-stable-ng-99/withdraw/ and perform a Withdraw of the LP tokens to receive xfrxETH and sWETH_t for the CrossCurve WETH TAI pool.

    We recommend using the Balanced mode when withdrawing to minimize losses due to slippage.

    xfrxETH and sWETH_t tokens from the xeTaiko pool on the Sonic network can be exchanged for sxfrxETH_s and WETH on the Taiko network respectively: Go to the Liquidity tab in the Yield section on the xeTaiko pool page: https://app.crosscurve.fi/liquidity?pool=0x6d9f0ff2b7f1397ee731f6370d8e4699ffad7bc5&type=curve&action=withdraw&input=0x8af98914c95a3ec6e790d79e9ef9072e307fc086&output=0xa51894664a773981c6c112c43ce576f315d5b1b6&chainIn=146&chainOut=167000 Select the Withdraw action in Balanced mode and click Next.

    Enter the amount of sWETH_t tokens and perform the swap to WETH.

    Go to the Liquidity tab in the Yield section on the xeoTaiko pool page: https://app.crosscurve.fi/liquidity?pool=0xe16ab7fb5d2c7c1b69f7ce58d390b78ab59e44ae&type=curve&action=deposit&input=0x346704605c72d9f5f9f02d651e5a3dcce6964f3d&output=0xa494f19b34f6aa77ce6d968c752b6321d7b069b3&chainIn=146&chainOut=167000 Select the Deposit action in Balanced mode and click Next.

    Enter the amount of xfrxETH tokens and perform the swap to sxfrxETH_s.

    Obtaining sxfrxUSD_s

    sxfrxUSD_s tokens on the Taiko network can be obtained by exchanging them for assets available in the xsoTaiko pool in the CrossCurve application.

    1. Go to the Liquidity tab in the Yield section. Select the Deposit action in Balanced mode, then click Next.

    Choose the desired asset and enter the amount you want to exchange, then confirm the spend by clicking Approve, and sign the transaction in your wallet.

    Click Swap to exchange and confirm the transaction in your wallet.

    2. If you know the exchange direction, you can perform the swap in the Trade tab for any available asset using the Advanced mode .

    Note: in some directions, high slippage may occur!

    Obtaining sxfrxETH_s

    sxfrxETH_s tokens on the Taiko network can be swapped into from any available asset in the xeoTaiko pool in the CrossCurve application.

    1. Go to the Liquidity tab in the Yield section. Select the Deposit action in Balanced mode, then click Next.

    Choose the desired asset and enter the amount you want to exchange, then confirm the spend by clicking Approve, and sign the transaction in your wallet.

    Click Swap to exchange and confirm the transaction in your wallet.

    1. If you know the exchange direction, you can perform the swap in the Trade tab for any available asset using the Advanced mode .

    Attention: in some directions, high slippage may occur!

    Adding liquidity to xsoTaiko pool via Curve

    Go to the CrossCurve Stable pool page https://www.curve.finance/dex/taiko/pools/factory-stable-ng-5/deposit/ and connect your wallet.

    Enter the desired deposit amount in the Deposit tab. To avoid losses due to slippage, it is recommended to deposit funds using the balanced method by clicking Add all coins in a balanced proportion (more details here).

    With the first transaction, confirm the spend by clicking Approve Spending and signing the transaction in your wallet.

    With the second transaction, deposit the funds by clicking Deposit and signing the transaction in your wallet.

    After successfully confirming the transaction on-chain, the amount of received xsoTaiko LP tokens will be reflected in your wallet and in the Your Details tab.

    If your wallet does not support automatic token addition, add it manually as a custom token using the contract address 0xA17aa5eE656849221C8d9d062894e1145CbdA864 on the Taiko network.

    CrossCurve Stable
    CrossCurve WETH
    xsoTaiko
    xeoTaiko
    USDC
    sxfrxUSD_s
    WETH
    sxfrxETH_s

    Upgradeable (UUPS Pattern): The contract can be updated while preserving state.

  • Owner-Based Access Control: Critical functions (like upgrading the contract and updating campaign parameters) are restricted to the owner.

  • Reward Notification: The notifyRewardAmount function can only be invoked by the authorized escrow vote manager, ensuring a controlled flow of rewards.

  • Campaign Parameters: The gauge uses dynamic campaign parameters (s_campaignParameters) to manage reward distribution schedules and amounts, which can be updated by the owner if needed.

  • By implementing IGaugeV1, GaugeV1 provides a standardized interface for initializing, updating campaign parameters, and receiving new reward amounts within the CrossCurve ecosystem.


    Inherited Contracts and Interfaces

    • UUPSUpgradeable (OpenZeppelin): Enables upgradeability under the UUPS (Universal Upgradeable Proxy Standard) pattern, restricted to the contract owner.

    • OwnableUpgradeable (OpenZeppelin): Provides ownership logic, limiting certain state changes (e.g., upgrading, updating parameters) to the contract owner.

    • IGaugeV1: Interface defining core functions (e.g., initialize, updateCampaignParameters, notifyRewardAmount) and events (RewardNotified, CampaignParametersUpdated) for the gauge contract.

    Additional External References:

    • SafeERC20, IERC20 (OpenZeppelin): Library and interface for safe ERC20 token transfers.

    • IEscrowVoteManagerV1: Tracks and authorizes reward notifications, ensuring that only the designated manager can call notifyRewardAmount.

    • IDistributionCreator: Contract on Arbitrum that actually creates or schedules distribution campaigns (Merkl distributions).

      • The contract uses DISTRIBUTION_CREATOR with a known address (0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd) on Arbitrum.


    Constants

    • EPOCH_DURATION: The duration of an epoch (1 week). Used to align reward distribution campaigns with discrete time intervals.

    • DISTRIBUTION_CREATOR: The address of the Merkl distribution contract on Arbitrum. This contract is responsible for orchestrating reward distributions once campaigns are created.


    State Variables

    • s_escrowVoteManager (address) Address of the escrow vote manager contract, which is authorized to call notifyRewardAmount.

    • s_eywa (address) The EYWA token address used for rewards distribution.

    • s_campaignParameters (IDistributionCreator.CampaignParameters) Holds the current campaign parameters for distributing rewards. These parameters include data like amount, duration, start timestamp, and distribution logic, which can be updated by the owner.


    Constructor

    • Description: Disables contract initializers to prevent multiple initializations. Enforces that initialize can be called only once in a UUPS upgradeable context.


    External Functions

    initialize(...)

    • Description:

      • Initializes the gauge contract by setting the owner, escrow vote manager, EYWA token address, and the initial campaign parameters for rewards.

      • Can only be called once, marked by the initializer modifier from OpenZeppelin upgradeable patterns.

    • Parameters:

      • owner_: The address designated as the contract owner.

      • escrowVoteManager_: The address of the escrow vote manager, authorized to call notifyRewardAmount.

      • eywa_: The address of the EYWA token used for distributing rewards.

    • Effects:

      • Calls __UUPSUpgradeable_init() and __Ownable_init(owner_) to set up UUPS upgrade and ownership.

      • Assigns s_escrowVoteManager and s_eywa references.


    updateCampaignParameters(...)

    • Description:

      • Allows the contract owner to update the gauge’s campaign parameters.

      • The newly provided parameters (newCampaignParameters_) overwrite the existing ones in s_campaignParameters.

    • Parameters:

      • newCampaignParameters_: The updated distribution parameters (e.g., new schedule or amounts) for this gauge.

    • Events:

      • Emits CampaignParametersUpdated(address(this), oldCampaignParameters, newCampaignParameters_) to log the changes.


    notifyRewardAmount(uint256 amount_)

    • Description:

      • Notifies the gauge of a newly available amount_ of EYWA tokens to be distributed as rewards.

      • Can only be called by s_escrowVoteManager.

      • The function transfers amount_ from the caller to this gauge, checks if the resulting balance is sufficient to meet the minimum distribution threshold, and if so, triggers the distribution campaign via DISTRIBUTION_CREATOR.createCampaign(...).

    • Parameters:

      • amount_: The amount of EYWA tokens to be added for distribution.

    • Checks & Logic:

      1. Verifies msg.sender == s_escrowVoteManager, otherwise reverts with UnauthorizedCaller().

      2. Transfers amount_ of EYWA from the caller to the contract.

    • Events:

      • RewardNotified(amount_) logs the newly notified reward amount.


    Internal and Private Functions

    _authorizeUpgrade(address)

    • Description:

      • Ensures that only the contract owner can authorize upgrades.

      • Enforced by the UUPSUpgradeable pattern.


    Events

    1. RewardNotified(uint256 indexed amount)

      • Emitted when new rewards are notified to the gauge, indicating the total tokens added.

    2. CampaignParametersUpdated( address indexed gauge, IDistributionCreator.CampaignParameters oldCampaignParameters, IDistributionCreator.CampaignParameters newCampaignParameters )

      • Logged when the owner updates the gauge’s distribution campaign parameters.


    Errors

    • UnauthorizedCaller()

      • Thrown if a function restricted to s_escrowVoteManager or onlyOwner is called by an unauthorized address.


    Summary

    GaugeV1 is an upgradeable contract that manages reward distributions for a specific pool or strategy within the CrossCurve ecosystem. By connecting to an Escrow Vote Manager, it ensures only authorized parties can add new rewards (notifyRewardAmount). Through DistributionCreator on Arbitrum, it transforms these rewards into time-bound distribution campaigns. The contract owner can update campaign parameters if needed, while all major functionalities (initialization, upgrade, parameter updates) remain protected by ownership and authorized checks.

    CrossCurve Consensus Bridge

    Overview

    CrossCurve Consensus Bridge (CCB) is a cross-chain communication protocol that enables reliable data and asset transfers between networks without relying on centralized intermediaries.

    The system is built on a consensus mechanism among independent cross-chain messaging services, ensuring the authenticity of cross-chain messages received on the destination network.

    The goal of CCB is to provide developers with a secure way to connect their dApps, DeFi protocols, DAOs, and Infrastructure Services to a multi-network ecosystem using a standardized API and a minimal set of dependencies.

    Architecture

    Basic cross-chain schema

    The fundamental model of cross-chain interaction has been used in various forms for quite some time.

    In blockchain A, a contract calls a bridge contract function to send data to blockchain B. The bridge contract emits an event, which is picked up by its off-chain service. This service then creates a transaction containing the necessary data for the corresponding bridge contract on blockchain B. Upon receiving the transaction, the bridge contract verifies its validity and then invokes the target contract function, passing along the data received from blockchain A.

    One of the core challenges lies in the fact that the bridge service operates outside the blockchain environment and therefore cannot be verified on-chain. Different bridge protocols address this issue in different ways.

    CrossCurve Consensus Bridge, however, introduces a more comprehensive approach. It is not meant to replace existing protocols - instead, it integrates and leverages their mechanisms, creating a unified and verifiable cross-chain communication layer.

    Consensus Bridge schema

    • The sender initiates a message in the source network by calling the CrossCurve Gatekeeper contract.

    • Depending on the destination chain, the Gatekeeper prepares and executes parallel message dispatches through multiple supported protocols. One of these protocols transmits the full message payload, while the others send verification proofs to confirm message authenticity.

    • Each protocol, following its standard cross-chain messaging process, independently delivers its data to the CrossCurve Receiver contract in the destination network.

    Advantages

    Security

    CrossCurve Consensus Bridge provides a truly secure mechanism for cross-chain messaging.

    Its minimal configuration requires three sovereign cross-chain protocols.

    Even in this base setup, an attacker would need to gain simultaneous control over at least two out of the three protocols to compromise a message — making unauthorized interference practically infeasible.

    Censorship Resistance

    Decentralization is one of the most effective defenses against censorship.

    However, in many cross-chain systems, services are often built on specific infrastructure stacks, which introduces potential points of control and censorship.

    CrossCurve Consensus Bridge eliminates this issue by leveraging sovereign protocols that operate independently from one another.

    For an adversary to block or alter message delivery through the bridge, they would need to control more than 50% of the protocols participating in the message channel (in the minimal setup, that means controlling two out of three).

    Resilience

    The consensus of independent protocols ensures not only security but also fault tolerance in message transmission. Even in its minimal configuration, if one of the three protocols becomes temporarily unavailable, the remaining two are sufficient to keep the CrossCurve Consensus Bridge fully operational.

    In the rare event of a deadlock — when one or more bridges within the consensus experience prolonged downtime, potentially locking assets that relied on the consensus bridge — the situation remains recoverable. The can replace the affected protocols in the consensus bridge of the impacted chain by approving a dedicated governance proposal.

    Governance Protection

    The CrossCurve Consensus Bridge is engineered for maximum security through the use of consensus among independent bridge protocols for data transmission.

    Yet even the most secure systems can face potential vulnerabilities. The most common vector of attack targets governance mechanisms — an adversary might attempt to alter the composition of participating bridges, making it easier to compromise a single one.

    In CrossCurve Consensus Bridge, such a scenario is structurally impossible.

    Bridge configuration across all chain pairs is managed exclusively by the CrossCurve DAO. Any modification requires explicit community approval. The voting process lasts 7 days, and even after a proposal passes, the new configuration takes effect only after 24 hours, providing an additional safeguard and ensuring transparent governance.

    This underlines the critical role of the CrossCurve DAO in maintaining decentralization across cross-chain messaging.

    We believe that greater decentralization and resilience can be achieved when ecosystem participants — those advocating for transparency, stability, and security — become active members of the CrossCurve DAO. Their participation strengthens governance integrity and makes malicious decisions significantly harder to pass.

    Capabilities

    Cross-Chain Messaging

    This is the foundation for building advanced cross-chain applications.

    Through the Consensus Bridge, dApps gain a reliable communication layer between their instances deployed across different blockchains - or with APIs of other applications operating in separate networks.

    Cross-Chain Token Transfers

    Cross-chain token transfer applications using any combination of lock/mint or burn/mint models can rely on the Consensus Bridge as a trustless verification layer.

    It provides accurate and verifiable information about token locking, minting, unlocking, or burning events across different blockchains.

    Foundation for SuperDVN

    The Consensus Bridge integrates seamlessly into the LayerZero cross-chain verification system.

    This is achieved through a wrapper module called SuperDVN, which externally behaves like a standard DVN but internally performs multi-protocol consensus verification for enhanced security and reliability.

    Supported Protocols

    Currently, the CrossCurve Consensus Bridge supports the following messaging protocols:

    • CrossCurve Oracle Network

    Integration and Connection

    The integration with the Consensus Bridge is planned to be permissionless. However, the protocol is currently operating in an experimental mode. If you’d like to connect, please contact us

    To send a message to a recipient on another chain, you need to:

    1. Prepare the calldata for the target contract function with the required parameters.

    2. Call the sendData function on the CrossCurve Gatekeeper contract:

    Contracts

    To configure the bridge, use the following contract addresses.

    For proper operation, the contracts must be deployed on both the source and destination blockchains.

    Network
    CrossCurve Receiver Address
    CrossCurve Gatekeeper Address

    uint256 public constant EPOCH_DURATION = 1 weeks;
    IDistributionCreator public constant DISTRIBUTION_CREATOR = IDistributionCreator(0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd);
    constructor() {
        _disableInitializers();
    }
    function initialize(
        address owner_,
        address escrowVoteManager_,
        address eywa_,
        IDistributionCreator.CampaignParameters calldata campaignParameters_
    ) 
        external
        initializer
    function updateCampaignParameters(
        IDistributionCreator.CampaignParameters calldata newCampaignParameters_
    ) 
        external 
        onlyOwner
    function notifyRewardAmount(uint256 amount_) external
    function _authorizeUpgrade(address) internal override onlyOwner

    campaignParameters_: Initial set of campaign parameters (amount, duration, schedule, etc.) used in distribution campaigns.

    Stores s_campaignParameters from input.

    If the new balance (multiplied by 1 hour / EPOCH_DURATION) meets the rewardTokenMinAmounts(...) requirement of DISTRIBUTION_CREATOR, the contract approves DISTRIBUTION_CREATOR to spend its entire balance and initiates a campaign:

    • Sets m_campaignParameters.amount to the new gauge balance.

    • Sets startTimestamp = uint32(block.timestamp).

    • Sets duration = uint32(EPOCH_DURATION) (one week).

    • Calls createCampaign(...) on DISTRIBUTION_CREATOR.

  • Emits RewardNotified(amount_).

  • The Receiver collects the received message instances and emits events as they arrive.
  • The external service CrossCurve Pusher monitors these events. Once the original message and a sufficient number of verification confirmations are detected, it submits an execution transaction to the CrossCurve Receiver contract.

  • Upon receiving the transaction from CrossCurve Pusher, the Receiver verifies the existence of the original message and all required confirmations from other protocols.

  • If validation is successful, the verified message is then delivered to its designated recipient.

  • Ethereum Sepolia Testnet

    0xE98Fd4eF563dCDfC535755f1FBCC0942a8e63517

    0xAB2f5D5A675F9004FEfcA7DC462e3C919a03E892

    Arbitrum Sepolia Testnet

    0x962EDA2C1b103539cC13eF28951274d21291BC68

    0xde6724F8E4Ce4698c0096c58554e44F8aCE28600

    BNB Smart Chain (BSC) Testnet

    0xC07642337453820d51Bc60D7f39A53B202E691b8

    0xFA36e2B52b8a21347eB6c46401b210D547e7a4cA

    Sonic Testnet

    0x1992D29b2251F85A3f46B9da95b3A9DdD31CaED1

    CrossCurve DAO
    Layer Zero
    Axelar
    Router Protocol
    [email protected]

    EmissionManagerV1

    EmissionManagerV1

    Overview

    EmissionManagerV1 is an upgradeable contract that orchestrates weekly EYWA token emissions to various distribution streams, such as rebase rewards, gauge rewards, bonds, grants, and incentives. It integrates with the Escrow Manager to evaluate locked token balances and applies distinct emission formulas depending on whether the total locked tokens exceed a specified threshold. The contract also enforces constraints on weekly emissions, such as cooldown periods, maximum percentage increases, and valid distribution percentages.

    Key Features:

    • Epoch-Based Emissions: Emissions occur in discrete one-week epochs, with a configurable weekly emission amount.

    • Distribution Percentages: Tokens are split among rebase rewards, bonds, grants, and incentives, each receiving a percentage of the weekly emission.

    • Threshold-Based Adjustments: If total locked tokens exceed a s_lockThreshold, alternate base rates and multipliers are applied to rebase calculations.

    By implementing the IEmissionManagerV1 interface, EmissionManagerV1 provides a clear set of functionalities and events essential for managing the emission process in the CrossCurve ecosystem.


    Inherited Contracts and Interfaces

    • UUPSUpgradeable (OpenZeppelin): Enables the contract to be upgradeable via a UUPS proxy pattern, ensuring only the owner can perform upgrades.

    • OwnableUpgradeable (OpenZeppelin): Provides ownership functionality, restricting sensitive actions (like parameter updates) to the owner.

    • IEmissionManagerV1: Interface declaring all essential methods (e.g., initialize, updateEpoch) and events for managing emissions.

    Additional External References:

    • SafeERC20, IERC20 (OpenZeppelin): Used for secure ERC20 operations.

    • IEscrowVoteManagerV1: Receives gauge emission amounts and coordinates gauge reward distribution.

    • IEscrowManager: Provides total locked token data for rebase emission calculations.

    • ITreasury: Manages treasury funds from which weekly emissions are withdrawn.


    Constants

    • EPOCH_DURATION: Duration of each emission epoch (1 week).

    • TOTAL_SUPPLY: Total EYWA token supply (1 billion).

    • MAXIMUM_EMISSION_INCREASE_PERCENTAGE: Maximum allowed percentage by which the weekly emission can increase, scaled by PRECISION.


    State Variables

    Emission Parameters

    • s_currentWeeklyEmission (uint256): Current weekly emission amount in EYWA tokens.

    • s_totalDistributedEmission (uint256): Accumulated amount of EYWA tokens distributed across all epochs.

    Distribution Percentages

    • s_gaugeEmissionPercentage (uint256): Percent of weekly emission allocated to gauge rewards, scaled by PRECISION.

    • s_bondEmissionPercentage (uint256): Percent allocated to bond rewards, scaled by PRECISION.

    • s_grantEmissionPercentage (uint256)

    Threshold and Rates

    • s_lockThreshold (uint256): The threshold of total locked tokens determining which emission formula to apply.

    • s_baseRateBelowThreshold (uint256): Base rate for rebase emission if locked tokens < s_lockThreshold.

    • s_baseRateAboveThreshold (uint256): Base rate if locked tokens ≥ s_lockThreshold

    Inflation Rates

    • s_initialInflationRate (uint256): Inflation rate applied when locked tokens are below threshold.

    • s_secondaryInflationRate (uint256): Inflation rate used when locked tokens are above threshold.

    Epoch Management

    • s_currentEpochStart (uint256): Timestamp marking the start of the current emission epoch.

    • s_lastChangeEpochStart (uint256): Timestamp marking the start of the epoch during the last emission state change (used for cooldown enforcement).

    • s_epochCounter (uint256): Number of completed epochs.

    Addresses

    • s_treasury (address): Address holding the EYWA tokens (treasury).

    • s_rebaseRewardsDistributor (address): Distributor for rebase rewards.

    • s_bondEmissionDistributor (address): Distributor for bond emissions.


    Constructor

    • Description: Disables contract initializers to prevent re-initialization in a UUPS proxy context.


    External Functions

    initialize(...)

    Description: Initializes the contract for the first time, setting the owner, treasury, emission distributors, and references to external managers/tokens. Configures initial weekly emission, distribution percentages, threshold-based rates, and inflation rates.

    Parameters:

    • owner_: Contract owner address.

    • treasury_: Address of treasury holding EYWA tokens.

    • rebaseRewardsDistributor_: Distributor contract for rebase rewards.

    Effects:

    • Calls __UUPSUpgradeable_init() and __Ownable_init(owner_).

    • Sets initial values for emission rates, thresholds, and inflation parameters.

    • Marks the start of the current epoch.


    updateTreasury(address newTreasury_)

    Description: Updates the treasury address from which emissions are withdrawn.

    Events:

    • Emits TreasuryUpdated(newTreasury_).


    updateEmissionDistributors(...)

    Description: Updates the addresses for bond, grant, and incentive emission distributors. Only callable by the owner.

    Parameters:

    • newBondEmissionDistributor_: New bond emission distributor address.

    • newGrantEmissionDistributor_: New grant emission distributor address.

    • newIncentiveEmissionDistributor_: New incentive emission distributor address.

    Events:

    • Emits EmissionDistributorsUpdated.


    updateWeeklyEmissionState(...)

    Description: Adjusts the weekly emission amount and distribution percentages. Enforces a cooldown (EPOCH_COOLDOWN_PERIOD) since the last change and forbids increases above the allowed percentage limit.

    Checks & Constraints:

    • Must have at least 1 epoch (s_epochCounter > 0).

    • Enforces cooldown: block.timestamp must be ≥ s_lastChangeEpochStart + EPOCH_COOLDOWN_PERIOD * EPOCH_DURATION.

    • newWeeklyEmission_ must not exceed historical average times MAXIMUM_EMISSION_INCREASE_PERCENTAGE / PRECISION

    Events:

    • Emits WeeklyEmissionStateUpdated.


    updateParameters(...)

    Description: Updates threshold-based emission parameters, including base rates, rate multipliers, and inflation rates used in rebase calculations.

    Events:

    • Emits ParametersUpdated with the updated values.


    updateEpoch()

    Description: If a new epoch has started (block.timestamp >= s_currentEpochStart + EPOCH_DURATION), the contract calculates distributions for the new week and transfers tokens to the various distributors.

    Logic:

    1. Withdraws s_currentWeeklyEmission from s_treasury.

    2. Calculates rebase emission portion with _calculateRebaseEmission.

    3. Sends rebase emission to the rebase rewards distributor and calls checkpoint().

    Events:

    • Emits EpochUpdated with detailed breakdown.


    averageWeeklyEmissionOverTime()

    Description: Returns the average weekly emission across all completed epochs: s_totalDistributedEmission / s_epochCounter.


    Internal and Private Functions

    _authorizeUpgrade(address)

    • Description: Restricts the UUPS upgrade function to the contract owner.


    _calculateRebaseEmission(uint256 currentWeeklyEmission_)

    Description: Derives the rebase portion of the weekly emission based on total locked tokens from s_escrowManager.

    • If m_totalLocked >= s_lockThreshold, uses one set of base rates, multipliers, and s_secondaryInflationRate.

    • Otherwise, uses another set and s_initialInflationRate.

    Return:

    • rebaseEmission_: The final rebase token amount.

    Formula Components:

    1. Computes an adjustment factor that depends on s_baseRateAboveThreshold/s_rateMultiplierAboveThreshold or s_baseRateBelowThreshold/s_rateMultiplierBelowThreshold.

    2. Adds an inflation portion scaled by either s_secondaryInflationRate or s_initialInflationRate.


    Events

    • TreasuryUpdated(address newTreasury)

    • EmissionDistributorsUpdated(address newBondEmissionDistributor, address newGrantEmissionDistributor, address newIncentiveEmissionDistributor)

    • WeeklyEmissionStateUpdated(uint256 newWeeklyEmission, uint256 newGaugeEmissionPercentage, ..., uint256 newIncentiveEmissionPercentage)

    These events log critical changes such as treasury updates, changes to emission distribution, parameter updates, and epoch transitions.


    Errors

    • InvalidCallee(): Thrown if an unauthorized entity calls certain functions (not used in current logic).

    • ZeroEpochCounter(): Thrown if updateWeeklyEmissionState is called before any epoch has elapsed.

    • CooldownPeriodNotElapsed(): Thrown if a new weekly emission state update is attempted within the cooldown period.


    Summary

    EmissionManagerV1 is a flexible and upgradeable contract for distributing EYWA tokens weekly to different reward mechanisms—governed by configurable rates and distribution percentages. By leveraging a threshold-based logic, it dynamically adjusts rebase emissions based on the total locked tokens, ensuring that ecosystem participation and inflation rates are balanced. It integrates seamlessly with treasury, escrow, and reward distributor contracts to enforce cooldowns, respect maximum emission growth, and emit relevant events detailing emission updates.

    RebaseRewardsDistributorV1

    Overview

    RebaseRewardsDistributorV1 is an upgradeable contract that distributes rebase rewards to veEYWA token holders (locks) in the CrossCurve ecosystem. It relies on an Emission Manager (s_emissionManager) to trigger epoch updates (checkpoints) and fetches locked token data from an Escrow Manager (s_escrowManager). The contract tracks weekly reward distributions and lets veEYWA token holders claim these rebase rewards either directly (if their lock is expired) or by depositing rewards back into the lock (if it’s still active).

    Key features include:

    1. Epoch-Based Distribution: Rewards are recorded in discrete weekly intervals (epochs) and credited to locks according to each lock’s proportional voting power during the relevant weeks.

    2. Checkpointing Logic: Every time new rebase rewards are added, the contract updates an internal “checkpoint,” distributing the newly added tokens proportionally over the elapsed time since the last checkpoint.

    3. On-Chain Rebase: Locks continuously earn rebase rewards over time; once claimed, if the lock is still active (not past unlockTime), the rewards are automatically re-deposited. Otherwise, they are transferred to the lock owner.

    By implementing IRebaseRewardsDistributorV1, RebaseRewardsDistributorV1 ensures a standardized interface for initialization, checkpoint updates, and reward claims within the CrossCurve ecosystem.


    Inherited Contracts and Interfaces

    • UUPSUpgradeable (OpenZeppelin): Provides functionality for upgradeable contracts following the UUPS (Universal Upgradeable Proxy Standard) pattern.

    • OwnableUpgradeable (OpenZeppelin): Gives ownership control, allowing only the owner to authorize upgrades and perform restricted actions.

    • IRebaseRewardsDistributorV1 (Custom Interface): Declares the core functions (e.g., initialize, checkpoint, claim) and events (

    Additional External References:

    • SafeERC20, IERC20 (OpenZeppelin): For safe ERC20 transfers of the EYWA token.

    • IEscrowManager: Provides locked token data (voting power snapshots, unlockTime, ownership).

    • IEmissionManagerV1: Signals new epochs by calling checkpoint() and ensures emission periods are up-to-date.


    Constants

    • EPOCH_DURATION: Specifies that each distribution epoch is exactly one week (604,800 seconds).


    State Variables

    1. s_rewardsStartTime (uint256)

      • The timestamp (rounded down to the nearest week) at which rewards distribution officially begins.

    2. s_lastCheckpointTime (uint256)


    Constructor

    • Description: Disables initializers for this upgradeable contract, ensuring initialize is called only once in a UUPS proxy context.


    External Functions (IRebaseRewardsDistributorV1)

    1. initialize(...)

    • Description:

      • Sets up initial state for the rebase rewards distributor:

        • Assigns contract ownership to owner_.


    2. checkpoint()

    • Description:

      • Called only by s_emissionManager to record a new checkpoint, distributing newly added tokens across the weeks since the last checkpoint.

      • Reverts if msg.sender != s_emissionManager with UnauthorizedCaller().


    3. claim(uint256 tokenId_)

    • Description:

      • Lets a user claim the rebase rewards for a single veEYWA lock identified by tokenId_.

      • Requires that s_emissionManager.s_currentEpochStart() be updated to or beyond the current week; otherwise reverts with EmissionPeriodNotUpdated().


    4. claim(uint256[] calldata tokenIds_)

    • Description:

      • Claims rewards for multiple lock IDs in a single transaction.

      • Similar checks to claim(uint256), verifying the emission period is updated.

      • Iterates over each


    5. earned(uint256 tokenId_)

    • Description:

      • Returns how many tokens the lock with tokenId_ has accumulated but not yet claimed, using the latest known checkpoint.

      • Internally calls _earned(...) with s_lastCheckpointTime / EPOCH_DURATION * EPOCH_DURATION as the last checkpoint boundary.


    Internal and Private Functions

    _checkpoint()

    • Description:

      • The core logic that distributes newly added EYWA tokens among each weekly interval from the last checkpoint time until block.timestamp.

      • If a portion of a week is included, it distributes a proportional share.


    _claim(...)

    • Description:

      • Internal function that calculates how many rebase rewards tokenId_ has earned since its last claim, updates the last claimed time, and emits RewardsClaimed.

      • Returns the amount of newly claimed rewards.


    _earned(...)

    • Description:

      • Calculates how many tokens the lock tokenId_ earned from m_initialWeekCursor to lastCheckpointTime_, iterating in weekly increments.

      • Uses historical voting power from the escrowManager.getPastVotesByTokenId(...)


    Events

    1. Checkpoint(uint256 indexed timestamp, uint256 indexed totalReward)

      • Emitted whenever _checkpoint() distributes a new batch of tokens across weekly intervals.

      • timestamp: The timestamp of the checkpoint (usually block.timestamp).


    Errors

    • UnauthorizedCaller()

      • Thrown if checkpoint() is called by an entity other than s_emissionManager.

    • EmissionPeriodNotUpdated()

    No additional custom errors are introduced beyond those declared in the IRebaseRewardsDistributorV1 interface.


    Summary

    RebaseRewardsDistributorV1 provides a specialized, upgradeable system for distributing weekly rebase rewards to locks in the CrossCurve ecosystem. It does so by:

    • Recording new tokens from the emission manager in discrete weekly intervals via _checkpoint().

    • Allowing token holders to claim their proportional share of rebase rewards at any time, either receiving them directly if their lock is expired or re-depositing them if their lock remains active.

    • Integrating with the escrow manager to read historical voting power for each epoch and proportionally allocate weekly distributed tokens.

    By bridging data from the emission manager and the escrow manager, RebaseRewardsDistributorV1 ensures consistent rebase reward accounting that reflects each lock’s relative stake and time-based accumulation of benefits. It complements the rest of the CrossCurve ecosystem by providing a secure, time-based rebase distribution mechanism with minimal overhead and clear upgrade paths.

    Security audits

    CrossCurve DAO Security Audit Report by MixBytes

    1. Project architecture review:

    • Build an independent view of the project's architecture.

    sendData(
            bytes calldata data,
            bytes32 to,
            uint64 chainIdTo,
            bytes[] memory currentOptions
        ) external nonReentrant returns(uint256 fee)
    0x3619F7DA7e8Cc2A6E264d351d2D9a2CD36894063
    Identifying logical flaws.

    2. Checking the code in accordance with the vulnerabilities checklist:

    Eliminate typical vulnerabilities (e.g. reentrancy, gas limit, flash loan attacks etc.).

    3. Checking the code for compliance with the desired security model:

    Detect inconsistencies with the desired model.

    4. Consolidation of the auditors' interim reports into one:

    • Double-check all the found issues to make sure they are relevant and the determined threat level is correct.

    • Provide the Client with an interim report.

    5. Bug fixing & re-audit:

    • Verify the fixed code version with all the recommendations and its statuses.

    • Provide the Client with a re-audited report.

    6. Final code verification and issuance of a public audit report:

    • Conduct the final check of the code deployed on the mainnet.

    • Provide the Customer with a public audit report.

    5MBEywa DAO Security Audit Report.pdfpdf

    CrossCurve CLP security audit by MixBytes

    A group of auditors are involved in the work on the audit. Security engineers check the provided source code independently of each other in accordance with the methodology described below:

    1. Project architecture review:

    • Build an independent view of the project's architecture.

    • Identifying logical flaws.

    2. Checking the code in accordance with the vulnerabilities checklist: Eliminate typical vulnerabilities (e.g. reentrancy, gas limit, flash loan attacks etc.).

    3. Checking the code for compliance with the desired security model:

    Detect inconsistencies with the desired model.

    4. Consolidation of the auditors' interim reports into one:

    • Double-check all the found issues to make sure they are relevant and the determined threat level is correct.

    • Provide the Client with an interim report.

    5. Bug fixing & re-audit:

    • Verify the fixed code version with all the recommendations and its statuses.

    • Provide the Client with a re-audited report.

    6. Final code verification and issuance of a public audit report:

    • Conduct the final check of the code deployed on the mainnet.

    • Provide the Customer with a public audit report.

    3MBEywa CLP Security Audit Report.pdfpdf

    🔗 Link to MixBytes EYWA reports.

    CrossCurve CDP security audit by Smartstate

    The core architectural element of the CrossCurve ecosystem is the CrossCurve Cross-chain Data Protocol, which is a transport layer between blockchains. All CrossCurve products for DeFi users are based on this protocol.

    Although at the time of this audit the core of CrossCurve multisig is represented by a trusted group of projects, CrossCurve aims for DAO, as reflected in CrossCurve project current documentation.

    CDP Smart Contracts: These smart contracts serve as a means for sending and accepting cross-chain calls. They also include a node registration contract used in the Proof of Authority (POA) consensus among oracle nodes.

    Smart State evaluation: 8/10

    5MB05062305_EYWA_CDP_SС_report.pdfpdfCDP report from SmartState

    CrossCurve CLP security audit by Smartstate

    CrossCurve Cross-chain Liquidity Protocol ensures the operation of EYWA DEX v1

    CLP smart contracts - are smart contracts for processing synth and burn operations, as well as mint and lock tokens. They are also responsible for swap processing and liquidity handling operations.

    Smart State evaluation: 10/10

    🔗 Link to SmartState CrossCurve reports.

    Security audits by Hexens

    The Hexens team audited various components of CrossCurve, such as the BLS cryptography module in CrossCurve CDP as well as EYWA NFT.

    10MB
    EYWA_CLP_SС_report.pdf
    PDF
    Open
    CLP report from SmartState Jun 05 2023
    1MB
    CrossCurve_Metalayer_CLP_smart_contract_audit_report_Ver_1_2_August.pdf
    PDF
    Open
    CLP Smart contract audit report from SmartState Aug 29 2025
    Inflation Rates: Two inflation rates (s_initialInflationRate and s_secondaryInflationRate) further influence the rebase portion of weekly emissions.
  • Owner-Only Updates: Certain parameters, such as weekly emission amounts and distribution logic, can only be updated by the contract owner, subject to cooldowns and other constraints.

  • IRebaseRewardsDistributorV1: Distributes rebase rewards and triggers relevant accounting updates.

    PRECISION: Scaling factor for percentage calculations (e.g., 100,000 means 100%).
  • EPOCH_COOLDOWN_PERIOD: Number of epochs required between emission state changes.

  • : Percent allocated to grants, scaled by
    PRECISION
    .
  • s_incentiveEmissionPercentage (uint256): Percent allocated to incentives, scaled by PRECISION.

  • .
  • s_rateMultiplierBelowThreshold (uint256): Rate multiplier if locked tokens < s_lockThreshold.

  • s_rateMultiplierAboveThreshold (uint256): Rate multiplier if locked tokens ≥ s_lockThreshold.

  • s_grantEmissionDistributor (address): Distributor for grant emissions.
  • s_incentiveEmissionDistributor (address): Distributor for incentive emissions.

  • s_escrowVoteManager (IEscrowVoteManagerV1): Escrow vote manager contract for gauge emissions.

  • s_escrowManager (IEscrowManager): Escrow manager providing locked token data.

  • s_eywa (IERC20): EYWA token used for emission distributions.

  • bondEmissionDistributor_: Distributor contract for bond rewards.
  • grantEmissionDistributor_: Distributor contract for grants.

  • incentiveEmissionDistributor_: Distributor contract for incentives.

  • escrowVoteManager_: The escrow vote manager contract instance.

  • escrowManager_: Escrow manager contract instance for locked token data.

  • eywa_: EYWA token contract.

  • .
  • Sum of new distribution percentages = PRECISION (100%).

  • Distributes leftover among gauge, bond, grant, and incentive streams proportionally.

  • Increments s_epochCounter and updates s_totalDistributedEmission.

  • Divides by 1e18 at the end to restore integer arithmetic precision.

    ParametersUpdated(..., uint256 initialInflationRate, uint256 secondaryInflationRate)

  • EpochUpdated(uint256 epochStartTimestamp, uint256 totalEmission, uint256 rebaseEmission, ..., uint256 incentiveEmission)

  • ExcessiveEmissionIncrease(): Thrown if the new weekly emission exceeds the allowed maximum over historical average.

  • InvalidPercentagesSum(): Thrown if the sum of new distribution percentages does not equal PRECISION (100%).

  • uint256 public constant EPOCH_DURATION = 1 weeks;
    uint256 public constant TOTAL_SUPPLY = _000_000_000e18;
    uint256 public constant MAXIMUM_EMISSION_INCREASE_PERCENTAGE = 25_000;
    uint256 public constant PRECISION = 00_000;
    uint256 public constant EPOCH_COOLDOWN_PERIOD = 12;
    constructor() {
        _disableInitializers();
    }
    function initialize(
        address owner_,
        address treasury_,
        address rebaseRewardsDistributor_,
        address bondEmissionDistributor_,
        address grantEmissionDistributor_,
        address incentiveEmissionDistributor_,
        IEscrowVoteManagerV1 escrowVoteManager_,
        IEscrowManager escrowManager_,
        IERC20 eywa_
    ) external initializer
    function updateTreasury(address newTreasury_) external onlyOwner
    function updateEmissionDistributors(
        address newBondEmissionDistributor_,
        address newGrantEmissionDistributor_,
        address newIncentiveEmissionDistributor_
    ) external onlyOwner
    function updateWeeklyEmissionState(
        uint256 newWeeklyEmission_,
        uint256 newGaugeEmissionPercentage_,
        uint256 newBondEmissionPercentage_,
        uint256 newGrantEmissionPercentage_,
        uint256 newIncentiveEmissionPercentage_
    ) external onlyOwner
    function updateParameters(
        uint256 lockThreshold_,
        uint256 baseRateBelowThreshold_,
        uint256 rateMultiplierBelowThreshold_,
        uint256 baseRateAboveThreshold_,
        uint256 rateMultiplierAboveThreshold_,
        uint256 initialInflationRate_,
        uint256 secondaryInflationRate_
    ) external onlyOwner
    function updateEpoch() external
    function averageWeeklyEmissionOverTime() external view returns (uint256)
    function _authorizeUpgrade(address) internal override onlyOwner
    function _calculateRebaseEmission(uint256 currentWeeklyEmission_) private view returns (uint256)

    Owner-Only Upgrades: Using a UUPS proxy pattern, only the contract owner can authorize upgrades to the distributor’s logic.

    Checkpoint
    ,
    RewardsClaimed
    ) that define how rebase rewards are managed and distributed.

    Timestamp of the most recent checkpoint, marking when the contract last distributed tokens among the weekly intervals.

  • s_previousTokenBalance (uint256)

    • The EYWA token balance in the contract before the most recent checkpoint. Used to calculate how many new tokens were added since the last checkpoint.

  • s_eywa (IERC20)

    • The EYWA token contract used for rebase rewards.

  • s_escrowManager (IEscrowManager)

    • The escrow manager contract that manages veEYWA locks and provides historical voting power data.

  • s_emissionManager (IEmissionManagerV1)

    • The emission manager contract that calls checkpoint() each time new rebase rewards are determined.

  • s_weeklyTokensDistributed (uint256[1000000000000000])

    • A large array mapping from a week’s starting timestamp (multiple of EPOCH_DURATION) to the total tokens distributed in that particular week.

  • s_lastClaimedTimeByTokenId (mapping(uint256 => uint256))

    • For each veEYWA token ID, stores the last epoch’s timestamp at which it fully claimed rebase rewards.

  • Approves the escrowManager_ to pull unlimited EYWA tokens from this contract.
  • Records the start time of rewards (s_rewardsStartTime = current week boundary) and sets initial s_lastCheckpointTime similarly.

  • Links the references to s_eywa, s_escrowManager, and s_emissionManager.

  • Parameters:

    • owner_: The address designated as the contract owner.

    • eywa_: The EYWA token contract used for distributing rebase rewards.

    • escrowManager_: The contract that manages locked positions (NFT-based locks).

    • emissionManager_: The contract that triggers checkpoint updates.

  • Logic:

    1. Checks authorization.

    2. Calls _checkpoint() to distribute any new tokens proportionally among the weeks that have elapsed since s_lastCheckpointTime.

    Logic:

    1. Checks if the emission manager’s s_currentEpochStart() is updated to the current epoch.

    2. Calls _claim(tokenId_, lastCheckpointWeekBoundary).

    3. If the lock is expired (block.timestamp >= unlockTime), transfers the earned reward to the last lock owner. Otherwise, it deposits the reward back into the lock via escrowManager_.depositFor(...).

    4. Deducts the claimed reward from s_previousTokenBalance.

    tokenId_
    in
    tokenIds_
    and calls the internal
    _claim(...)
    , summing up the total claimed amount.

    Return:

    • uint256: The unclaimed rebase reward balance for that particular lock ID.

    Logic:
    1. Calculates m_totalReward = currentBalanceOfContract - s_previousTokenBalance.

    2. Spreads this m_totalReward proportionally across all full or partial weeks from s_lastCheckpointTime to block.timestamp.

    3. For each week boundary, updates s_weeklyTokensDistributed[weekTimestamp] += the portion of tokens corresponding to that interval.

    4. Updates s_previousTokenBalance to the current contract balance.

    5. Sets s_lastCheckpointTime = block.timestamp.

    6. Emits Checkpoint(block.timestamp, m_totalReward).

    Logic:

    1. Calls _earned(tokenId_, lastCheckpointTime_) to compute (m_reward, m_initialWeekCursor, m_updatedWeekCursor).

    2. Sets s_lastClaimedTimeByTokenId[tokenId_] = m_updatedWeekCursor.

    3. If m_reward == 0, returns immediately. Otherwise emits RewardsClaimed(tokenId_, m_initialWeekCursor, m_updatedWeekCursor, m_reward).

    4. Returns m_reward to the caller for final deposit/transfer logic.

    and total supply from
    escrowManager.getPastTotalSupply(...)
    to determine each week’s share of
    s_weeklyTokensDistributed
    .
  • Logic:

    1. Retrieves m_initialWeekCursor = s_lastClaimedTimeByTokenId[tokenId_]. If zero, attempts to set it from the lock’s first recorded epoch data in s_votingPowerPointByTokenIdAndEpoch.

    2. If m_initialWeekCursor >= lastCheckpointTime_, returns zero reward (nothing new to claim).

    3. Iterates at most 52 times (1 year lookback in weekly steps):

      • For each weekly boundary from m_updatedWeekCursor to lastCheckpointTime_, calculates:

        • m_balance = escrowManager.getPastVotesByTokenId(tokenId_, nextWeekTimestamp)

    4. Returns (m_reward, m_initialWeekCursor, m_updatedWeekCursor).

  • totalReward: The number of newly added tokens distributed.

  • RewardsClaimed(uint256 indexed tokenId, uint256 indexed initialWeekCursor, uint256 indexed updatedWeekCursor, uint256 reward)

    • Emitted whenever a token ID claims rebase rewards.

    • tokenId: The veEYWA NFT lock ID that claimed.

    • initialWeekCursor: The earliest week boundary for which new rewards are being claimed.

    • updatedWeekCursor: The new last claimed week boundary.

    • reward: The total tokens claimed in this operation.

  • Thrown if a user attempts to claim but the emission manager’s s_currentEpochStart() has not been advanced to the current week boundary.

  • IncentiveRewardsDistributor

    Overview

    IncentiveRewardsDistributor is a contract that builds upon an abstract RewardsDistributor to manage the distribution of incentive rewards within the CrossCurve ecosystem. The RewardsDistributor base contract provides fundamental logic for tracking deposits, withdrawals, reward notifications, and reward claims over discrete epochs. The IncentiveRewardsDistributor adds:

    1. Whitelisting of Tokens: Before accepting a new token as a reward token, it checks with the escrow vote manager to ensure it is whitelisted.

    2. Escrow Vote Manager Authorization: Restricts calls to certain functions (like getReward) to only the authorized vote manager.

    3. Inheritance and Extended Logic: Integrates seamlessly with the epoch-based deposit/withdraw system in RewardsDistributor to finalize reward amounts and calculations.

    By implementing IIncentiveRewardsDistributor, this contract conforms to a standard reward distributor interface used throughout the CrossCurve ecosystem.


    Inherited Contracts and Interfaces

    • RewardsDistributor (Abstract Contract):

      • Manages core reward distribution functionality, such as:

        • Tracking how many tokens each owner has deposited during a specific epoch.

        • Storing how many rewards are allocated to a token for each epoch.

    Additional External References:

    • IEscrowVoteManagerV1:

      • Provides s_isWhitelistedToken to validate new reward tokens.

      • Acts as an authorization gate for methods that require msg.sender to be the vote manager.


    Contract Architecture

    Inherited from RewardsDistributor

    The base RewardsDistributor constructor sets immutable references for ESCROW_VOTE_MANAGER and ESCROW_MANAGER. It also defines the following main categories of functionality:

    1. Epoch-Based Deposit and Withdrawal:

      • deposit(uint256 amount_, uint256 tokenId_)

      • withdraw(uint256 amount_, uint256 tokenId_)

    We now detail each of these base functions.


    Functions in the Base Contract: RewardsDistributor

    1. Constructor

    • Description: Sets ESCROW_VOTE_MANAGER and ESCROW_MANAGER as immutable addresses, used for authorization and lock ownership lookups.

    • Parameters:

      • escrowVoteManager_: The address of the escrow vote manager contract.


    2. deposit(uint256 amount_, uint256 tokenId_)

    • Description:

      • Called by the escrow vote manager to record that amount_ of tokens have been deposited for the lock represented by tokenId_ in the current epoch.

      • Increments the total supply and the lock owner’s balance for the current epoch.


    3. withdraw(uint256 amount_, uint256 tokenId_)

    • Description:

      • Called by the escrow vote manager to record that amount_ of tokens have been removed from the lock represented by tokenId_ in the current epoch.

      • Decrements the total supply and the lock owner’s balance for the current epoch.


    4. getRewardTokensCount()

    • Description: Returns the length of the s_rewardTokens array, i.e., how many reward tokens the distributor currently recognizes.

    • Return:

      • uint256: number of recognized reward tokens.


    5. earned(address owner_, address rewardToken_)

    • Description:

      • Computes how many tokens of rewardToken_ the owner_ has earned across epochs since their last claim.

      • Iterates through epochs in weekly increments up to a maximum of 52 (1-year look-back) or until reaching the current epoch.


    6. earnedByEpoch(address owner_, address rewardToken_, uint256 epoch_)

    • Description:

      • Returns how many rewardToken_ tokens were earned by owner_ specifically in a single epoch.

      • Calculated as rewardPerToken(rewardToken_, epoch_) * s_balanceByOwnerAndEpoch[owner_][epoch_] / 1e18.


    7. rewardPerToken(address rewardToken_, uint256 epoch_)

    • Description:

      • Calculates the distribution ratio for rewardToken_ in a given epoch_.

      • If s_totalSupplyByEpoch[epoch_] is zero, it simply returns s_rewardAmountByTokenAndEpoch[rewardToken_][epoch_].


    8. getReward(address owner_, address[] calldata rewardTokens_) (abstract)

    • Description:

      • Abstract in the base RewardsDistributor. The child contract (IncentiveRewardsDistributor) provides the actual implementation.

      • Child’s implementation calls _getReward(...) internally after verifying authorization.


    9. notifyRewardAmount(address rewardToken_, uint256 rewardAmount_) (abstract)

    • Description:

      • Abstract method for adding new reward tokens. Child contract overrides this to add whitelisting checks or additional logic.

      • The base logic is available in _notifyRewardAmount(...) (see below).


    10. _getReward(address owner_, address[] calldata rewardTokens_) (internal)

    • Description:

      • The internal function that loops over rewardTokens_, calculates earned(...), updates s_lastRewardClaimByOwnerAndToken, and transfers the reward to owner_.

      • Finally, emits


    11. _notifyRewardAmount(address sender_, address rewardToken_, uint256 rewardAmount_) (internal)

    • Description:

      • Transfers rewardAmount_ of rewardToken_ from sender_ to this distributor.

      • Adds the difference in the contract’s balance to s_rewardAmountByTokenAndEpoch[rewardToken_][currentEpochStart]


    Functions in IncentiveRewardsDistributor

    Constructor

    • Description:

      • Calls the RewardsDistributor constructor to set ESCROW_VOTE_MANAGER and ESCROW_MANAGER.

      • No additional logic besides inheritance.


    getReward(address owner_, address[] calldata rewardTokens_)

    • Description:

      • Implementation of getReward from both RewardsDistributor (abstract) and IIncentiveRewardsDistributor.

      • Allows the escrow vote manager to claim rewards for owner_.


    notifyRewardAmount(address rewardToken_, uint256 rewardAmount_)

    • Description:

      • Implementation of notifyRewardAmount from both RewardsDistributor (abstract) and IIncentiveRewardsDistributor.

      • First ensures rewardToken_ is whitelisted via


    Events and Errors

    Inherited Events

    1. TokensDeposited(from, tokenId, amount)

    2. TokensWithdrawn(from, tokenId, amount)

    3. RewardNotified(from, token, epoch, amount)

    Inherited Errors

    • InvalidRewardToken()

    • UnauthorizedAccess()

    • ZeroAmountProvided()

    No new custom events or errors are introduced in IncentiveRewardsDistributor beyond what’s inherited.


    Summary

    IncentiveRewardsDistributor leverages the robust, epoch-based reward accounting system from RewardsDistributor to facilitate secure incentive distribution in the CrossCurve ecosystem, adding token whitelisting checks and limiting reward claims (getReward) to calls from the escrow vote manager. This design ensures:

    • Authorized Control: Only recognized and whitelisted tokens can be notified as rewards; only the escrow vote manager can trigger claims.

    • Accurate Reward Calculations: Inherits deposit/withdraw logic to track each user’s epoch-based balance.

    • Easy Integration: Conforms to the IIncentiveRewardsDistributor interface, providing consistent methods for reward notifications and claims across the system.

    Together with the RewardsDistributor base contract, IncentiveRewardsDistributor offers a flexible, robust means of awarding incentive tokens in a multi-lock, epoch-based environment.

    Leaderboard

    Leaderboard Section and Its Functionality

    The accrual of points for the Airdrop Season 2 ended at 24:00 UTC on 30 September 2025.

    To start working in the CrossCurve app, go to the Leaderboard section. There, click “Connect wallet” in the top right corner, choose a suitable wallet from the list, and confirm the connection, making sure you are on the original page https://app.crosscurve.fi/leaderboard.

    1. After successfully connecting, you will see complete statistics of your earned points for participation in the EYWA Adventure Quest Season 2. The page displays the total number of earned points (updated every 24 hours at 00 UTC), the points received for completing basic and bonus tasks, statistics of your referrals.

    Below, you will see the stats for your referrals, sorted by referral level and liquidity volume. It also shows your overall ranking, along with the number and volume of transactions. By switching between Season 1 (completed) and Season 2, you can see the stats for either of the seasons of the Airdrop.

    1. By following the link Season 2 airdrop activities, you can learn about activities that allow you to accumulate points for the EYWA Season 2 airdrop:

    • Swaps on DEX

      In this on-chain activity, you receive points for cross-chain swaps on our DEX, up to 250 points* per day. For completing a swap daily, you receive bonus points. Each new day starts at 00:00 UTC, with the points added within two hours of the transaction being verified on the blockchain

    * from 12:30 UTC 18/06/2025 x3 points will be credited - up to 750 points per day

    • Early farming

      This new program rewards users for providing liquidity. Just lock your liquidity into the and pools and receive rEYWA (reward EYWA) tokens. rEYWA is a nontransferable ERC-20 token that you will be able to exchange 1:1 for EYWA after the TGE. Rewards accrue based on the Early Farming program rules and depend on the volume of liquidity provided and the pool chosen. rEYWA has a 90-day vesting period from the moment it’s claimed. Claiming is available at any time, but one must wait until the vesting period is complete in order to be able to exchange all of his rEYWA for EYWA 1:1. The exchange is only possible after the TGE (Token Generation Event). Exchanging rEYWA before the vesting is complete will give him EYWA for only the rEYWA that has already vested, with the rest being returned to the EYWA DAO treasury. Read the program’s details

    You can also join the ambassador program by filling out the form at the link.

    Mechanics of point accrual for on-chain DEX task completion

    Introducing a new mechanic for accruing a reward for the daily completion of even one CrossCurve transaction. The new day starts at 00:00 UTC, and the points are accrued within two hours of the transaction’s confirmation on the blockchain.

    Reward table for daily task completion

    Consecutive days with at least one transaction
    Daily reward for Season 2 airdrop activity

    The daily limit of points one can receive for completing tasks is 250*. If a user had 240 points and completed a task worth 20 points, only 10 points will be accrued, equalling 250* in total. You can get points for two activity types:

    * from 12:30 UTC 18/06/2025 x3 points will be credited - up to 750 points per day

    • Cross-chain swaps in the tab (up to 200 points/swap**)

    ** from 12:30 UTC 18/06/2025 x3 points will be credited - up to 600 points/swap

    • Deposits into the liquidity pool on the Fantom network in the tab ( up to 250 points/swap***)

    *** from 12:30 UTC 18/06/2025 x3 points will be credited - up to 750 points/swap

    1. Reward for cross-chain swaps

    You receive points for each cross-chain swap or LP in the tab.

    Transaction value *
    Base points **
    Bonus points**

    * transaction amount is considered in USD$ equivalent

    ** from 12:30 UTC 18/06/2025 all points are multiplied by x3.

    1. After entering the desired swap amount in the Swap tab, the app will reflect the number of points you will receive within two hours of the transaction confirmation on-chain. In the Daily Reward field, you’ll the number of points accrued for the daily completion of transactions.

    2. Clicking on info will give you complete information about your point accrual:

    • 70 base points for a swap of $1,000 to $4,999

    • 9,9 bonus points ( 3,3 for each $100 above $1,000)

    • Total amount of base points earned per day

    • Amount of points awaiting accrual within two hours

    1. To quickly find the optimal swap route go to the Find best route tab, and select token and network by clicking on Select Network and Token.

    After selecting token and network, enter the swap amount and click Find best route. The system will automatically find the best route for the swap.

    NOTE: The best route can send you to a network where you don’t have gas tokens, which can limit your subsequent transactions in that chain. Please check this before beginning the swap.

    2. Bridging rewards

    Points are rewarded for providing liquidity (Deposit) in in the tab. Points are also accrued for bridging* tokens from one chain to another.

    Bridge is the mechanism of moving tokens between blockchains based on the mint-and-burn principle, where the token is blocked or “burned” on the origin chain and its equivalent is created (“minted") on the destination chain.

    Single transaction value*
    Base points**
    Bonus points**

    * Each Deposit/Withdrawal transaction carries a fee of 0.005% from the tx value but no less than $0.02. Transaction amount is considered in USD$ equivalent

    ** from 12:30 UTC 18/06/2025 all points are multiplied by x3.

    After entering the desired deposit amount in the tab, the app will show you the number of points you’ll receive for this deposit, within two hours of the transaction confirmation on-chain.

    3. Referral program rules

    Through the referral system, you receive a part of the points from your referrals through our three-level program: 10% for the first level, 6% for the second level, and 4% for the third level. Points earned by each referral will be accrued once a day.

    By clicking “Get referral link”, you will need to log in through your X account.

    By clicking Connect Twitter, a new window will open for authorization through X. From there, click Authorize App.

    After successful authorization, you need to follow EYWA account on X by clicking Follow EYWA.

    Clicking Follow EYWA will open a new window to page. Click Follow.

    After following EYWA on Twitter, your referral for copying will appear.

    Clicking Post a Tweet and get Points will open a window to post the link in your account.

    To publish, click Post.

    EscrowManager

    Overview

    EscrowManager is a smart contract that manages locked EYWA tokens, each represented by a unique ERC-721 NFT (sometimes referred to as a "veEYWA" token). Each lock NFT stores information about its locked token amount, unlock time, vesting wallets, and booster NFTs. The contract supports operations like depositing, boosting, extending, deboosting, and withdrawing locked tokens, while tracking voting power via time-based checkpoints and epochs. It integrates with an external vote manager contract for governance operations and a collection contract for booster NFTs.

    Key Features:

    EscrowVoteManagerV1

    Overview

    EscrowVoteManagerV1 is a governance-related contract that manages gauge creation, voting power distribution, reward claiming, and other functionalities within the CrossCurve ecosystem. It integrates with:

    • Escrow Manager (IEscrowManager): Tracks locked EYWA positions.

    ProposalManager

    Overview

    ProposalManager is a governance contract built on OpenZeppelin’s Governor framework, incorporating additional logic for:

    • Protected Function Selectors: Certain function calls (on specific chain IDs and target addresses) are restricted to the contract owner. This prevents unauthorized calls to critical on-chain functionality within governance proposals.

    uint256 public constant EPOCH_DURATION = 1 weeks;
    constructor() {
        _disableInitializers();
    }
    function initialize(
        address owner_,
        IERC20 eywa_,
        IEscrowManager escrowManager_,
        IEmissionManagerV1 emissionManager_
    ) 
        external
        initializer
    function checkpoint() external
    function claim(uint256 tokenId_) external
    function claim(uint256[] calldata tokenIds_) external
    function earned(uint256 tokenId_) external view returns (uint256)
    function _checkpoint() private
    function _claim(uint256 tokenId_, uint256 lastCheckpointTime_) private returns (uint256)
    function _earned(
        uint256 tokenId_,
        uint256 lastCheckpointTime_
    )
        private
        view
        returns (
            uint256 m_reward,
            uint256 m_initialWeekCursor,
            uint256 m_updatedWeekCursor
        )
    m_supply = escrowManager.getPastTotalSupply(nextWeekTimestamp) (set to 1 if 0).
  • Distributes m_reward += (m_balance * s_weeklyTokensDistributed[weekTimestamp]) / m_supply.

  • Increments m_updatedWeekCursor by EPOCH_DURATION.

  • Calculating earned rewards for each owner at specific epochs and enabling claim logic.

  • Declares and implements the IRewardsDistributor interface.

  • IIncentiveRewardsDistributor:

    • Extends IRewardsDistributor with additional constraints and methods (getReward & notifyRewardAmount restricted to certain checks).

  • IEscrowManager:
    • Gives ownership and deposit/withdraw data for NFT-based locks.

    • Indirectly leveraged via RewardsDistributor functions for deposit/withdraw logic.

  • ReentrancyGuard (OpenZeppelin):

    • Inherited in RewardsDistributor to prevent re-entrant calls.

  • SafeERC20, IERC20 (OpenZeppelin):

    • Used for secure ERC20 transfers.

  • Reward Notification and Calculation:
    • notifyRewardAmount(address rewardToken_, uint256 rewardAmount_) (abstract here, implemented in the child contract)

    • earned(address owner_, address rewardToken_) and earnedByEpoch(address owner_, address rewardToken_, uint256 epoch_)

    • rewardPerToken(address rewardToken_, uint256 epoch_)

  • Claiming Rewards:

    • getReward(address owner_, address[] calldata rewardTokens_) (abstract here, partially implemented in the child)

    • _getReward(address owner_, address[] calldata rewardTokens_) (internal)

  • Data Structures for Epoch Accounting and Balances:

    • Mappings storing how much each user has deposited per epoch, total supply per epoch, and how much reward is allocated per epoch.

  • escrowManager_: The address of the escrow manager contract.

    Checks:

    • msg.sender == ESCROW_VOTE_MANAGER; otherwise UnauthorizedAccess().

  • Logic:

    1. Queries the current epoch start via IEscrowVoteManagerV1(ESCROW_VOTE_MANAGER).currentEpochStart().

    2. Increments s_totalSupplyByEpoch[m_currentEpochStart] by amount_.

    3. Retrieves lock owner via IEscrowManager(ESCROW_MANAGER).ownerOf(tokenId_).

    4. Increments s_balanceByOwnerAndEpoch[m_owner][m_currentEpochStart] by amount_.

    5. Emits TokensDeposited(m_owner, tokenId_, amount_).

  • Checks:

    • msg.sender == ESCROW_VOTE_MANAGER; otherwise UnauthorizedAccess().

  • Logic:

    1. Gets the current epoch start, as with deposit.

    2. Decrements s_totalSupplyByEpoch[m_currentEpochStart] by amount_.

    3. Finds lock owner and decreases s_balanceByOwnerAndEpoch[m_owner][m_currentEpochStart] by amount_.

    4. Emits TokensWithdrawn(m_owner, tokenId_, amount_).

  • Returns:

    • (uint256 m_reward, uint256 m_lastRewardClaim): the total reward due and the final epoch boundary used for calculation.

  • Logic:

    1. Checks if rewardToken_ is recognized in s_isRewardToken[rewardToken_]. If not, returns (0,0).

    2. Locates the last claimed epoch timestamp for (owner_, rewardToken_).

    3. Repeatedly calls earnedByEpoch(...) for each epoch from m_lastRewardClaim up to but not including currentEpochStart.

    4. Summation is the total pending rewards.

  • Otherwise, divides that reward amount by the epoch’s total supply (scaled by 1e18).

  • Return:

    • uint256: The per-token reward ratio used to multiply by an owner’s deposit amount to get their share.

  • RewardsClaimed(owner_, token, amount)
    .
    .
  • If s_initialIncentiveTimestamp == 0, sets it to the current epoch start.

  • Emits RewardNotified(sender_, rewardToken_, epoch, difference).

  • Calls _getReward(...) internally after checking msg.sender == ESCROW_VOTE_MANAGER.

    s_isWhitelistedToken
    in
    IEscrowVoteManagerV1
    .
    • If the token is not recognized (!s_isRewardToken[rewardToken_]), checks the vote manager to see if it’s whitelisted; if so, it’s now added to s_rewardTokens.

    • If not whitelisted, reverts with NotWhitelisted().

  • Calls _notifyRewardAmount(msg.sender, rewardToken_, rewardAmount_) to handle actual fund transfer and epoch reward updates.

  • RewardsClaimed(from, token, amount)
    NotWhitelisted()
    Lock Creation & Management: Users can create locks by transferring EYWA tokens, vesting wallets, or tokens from an NFT collection. They can add more tokens, apply boosters, or extend the lock duration.
  • Voting Power: Each lock corresponds to voting power that evolves over time. The contract records checkpoints of ownership and calculates voting weights using a dynamic rate-of-change approach.

  • Booster Mechanism: Boosters from the collection can increase a lock’s "coverage," thus effectively increasing its lock amount for voting power calculations.

  • Cooldown & Freeze Logic: After certain actions such as deboosting, token transfers may be temporarily frozen to prevent immediate re-deposit or locking manipulations.

  • Delegation Checks: The contract can integrate with a delegation manager to move voting power between addresses.

  • By implementing the IEscrowManager interface, the EscrowManager contract provides a consistent API for user and external contract interactions in the CrossCurve ecosystem.


    Inherited Contracts and Interfaces

    • ERC721Enumerable, ERC721 (OpenZeppelin): Provides standard ERC-721 NFT functionality with enumeration capabilities, enabling easy listing of all minted NFTs.

    • ERC721Holder (OpenZeppelin): Allows the contract to safely hold ERC-721 tokens (necessary when receiving booster NFTs).

    • ReentrancyGuard (OpenZeppelin): Mitigates re-entrant calls on state-changing functions.

    • SafeERC20, IERC20 (OpenZeppelin): Provides secure wrappers for ERC20 operations, ensuring safe token transfers.

    External Interfaces:

    • IEscrowManager: The interface implemented by this contract, defining locking and booster logic.

    • IEscrowVoteManagerV1: The vote manager that tracks epochs, triggers freeze logic, and notifies about gauge rewards.

    • ICollection, IWalletFactory, IVestingWallet: Components in the ecosystem for NFT boosters, creating/managing vesting wallets, and bridging custom data.

    • IMetadataProviderV1: Supplies metadata URIs for NFTs.

    • VotingPowerHelper (Library): Used to compute historical voting power and supply based on stored checkpoints and rate-of-change data.


    Constants

    • ATTACHMENTS_LIMIT = 100 Maximum number of attachments (vesting wallets or booster NFTs) allowed per lock.

    • EPOCH_DURATION = 1 weeks Governs epoch-based calculations for voting power and lock logic.

    • MAXIMUM_LOCK_DURATION = 156 weeks Maximum allowed lock duration in seconds (approximately 3 years).

    • MAXIMUM_NUMBER_OF_DELEGATES = 1024 Maximum delegates that can be tracked for a single account’s checkpoints.

    • SIGNED_MAXIMUM_LOCK_DURATION = 156 weeks Signed integer equivalent for arithmetic purposes.

    • Rarity Multipliers and Capacities: Predefined numerators and capacity values for Common, Uncommon, Rare, Legendary, and Infinity NFT rarities.

    • PRECISION = 100,000 Scaling factor for multiplier-based calculations (e.g., coverage, booster effects).

    Immutable Addresses:

    • ESCROW_VOTE_MANAGER (address): The escrow vote manager contract address.

    • DELEGATION_MANAGER (address): The delegation manager contract address.

    • EYWA (IERC20): The EYWA token used in locking.

    • COLLECTION (ICollection): The collection contract supporting booster NFTs.

    • WALLET_FACTORY (IWalletFactory): Factory contract for validating vesting wallets.

    • METADATA_PROVIDER (IMetadataProviderV1): Supplies off-chain metadata for NFTs.


    State Variables

    • s_nextTokenId (uint256) The next NFT token ID to be minted.

    • s_epoch (uint256) Tracks how many epochs have occurred, updated whenever lock states change significantly.

    • s_totalLocked (uint256) Total EYWA tokens locked across all positions.

    Lock and Booster Details:

    • _s_lockInfoByTokenId (mapping(uint256 => LockInfo)): Internal mapping of lock data.

    • s_pureLockAmountByTokenId, s_vestingWalletsLockAmountByTokenId: Track base token amounts and vesting wallet contributions.

    • s_currentCoverageByTokenId: Booster coverage for each lock.

    • s_boostersByTokenId, s_boostersByTokenIdAndRarity: Maintain sets of booster NFT IDs by token ID and rarity.

    Checkpointing and Voting:

    • s_checkpointsNumberByAccount (mapping(address => uint32)): Number of checkpoints for each account.

    • s_checkpoints (mapping(address => mapping(uint32 => Checkpoint))): Account checkpoints listing owned lock NFTs at different times.

    • s_ownershipChangeBlockNumberByTokenId (mapping(uint256 => uint256)): Block number of the last ownership change for each NFT (prevents double-voting in the same block).

    • s_rateOfChangeByUnlockTime (mapping(uint256 => int128)): Tracks changes in voting power at specific unlock times.

    • s_hasVotedByTokenId (mapping(uint256 => bool)): Whether a token has voted in the current epoch.

    • s_hasVotedByEpochAndTokenId (mapping(uint256 => mapping(uint256 => bool))): Tracks vote status for each token in each epoch.

    • s_votingPowerPointByEpoch (mapping(uint256 => VotingPowerPoint)): Stores aggregated voting power changes per epoch.

    • s_votingPowerPointByTokenIdAndEpoch (mapping(uint256 => VotingPowerPoint[1000000000])): Voting power data for each token ID across epochs.

    Deboost and Freeze Logic:

    • s_lastDeboostTimestampByTokenId (mapping(uint256 => uint256)): Records the last time a token was deboosted, used to freeze subsequent transfers.


    Constructor

    • Description: Deploys the EscrowManager, sets immutable addresses for the escrow vote manager, delegation manager, EYWA token, collection, wallet factory, and metadata provider, and initializes the NFT name and symbol.


    External Functions (Defined by IEscrowManager)

    createLock(uint256 lockAmount_, uint256 lockDuration_, address recipient_)

    Description: Creates a lock by transferring lockAmount_ of EYWA from the caller, locking it for lockDuration_ (rounded down to epoch boundaries). Mints an NFT for recipient_.


    createLock(uint256 lockDuration_, address recipient_, address[] calldata vestingWallets_)

    Description: Creates a lock by transferring tokens from multiple vesting wallets owned by the caller, then mints an NFT lock. Each vesting wallet's beneficiary must match the caller.


    createLock(uint256 lockDuration_, address recipient_, uint256[] calldata collectionTokenIds_)

    Description: Creates a lock using tokens associated with the given collection token IDs. Collects vesting wallets pinned to those NFTs, locks their balances, and automatically applies boosters via _modifyBoost.


    deposit(uint256 tokenId_, uint256 lockAmount_)

    Description: Adds extra EYWA to an existing lock. Requires caller authorization (_checkAuthorized).


    depositFor(uint256 tokenId_, uint256 lockAmount_)

    Description: Adds EYWA to an existing lock on behalf of the owner, without caller checks.


    boost(uint256 tokenId_, uint256[] calldata collectionTokenIds_)

    Description: Associates additional booster NFTs with a lock, increasing its coverage and potentially its voting power. Booster NFTs may also bring vesting wallets if pinned.


    deboost(uint256 tokenId_, uint256[] calldata collectionTokenIds_)

    Description: Removes booster NFTs from a lock. Verifies that the token hasn't voted in the current epoch. Records the block timestamp in s_lastDeboostTimestampByTokenId to freeze transfers for a defined period.


    withdraw(uint256 tokenId_)

    Description: Withdraws the tokens from an expired lock, returning booster NFTs, transferring vesting wallets, and burning the lock NFT. The caller must be authorized.

    Events:

    • Emits LockWithdrawn(recipient, tokenId, value) upon completion.


    extend(uint256 tokenId_, uint256 lockDuration_)

    Description: Extends the lock duration to a new unlockTime. Must be strictly greater than the current one. Updates voting power.


    setVoteStatus(uint256 tokenId_, bool status_)

    Description: Only callable by ESCROW_VOTE_MANAGER. Marks a token as having voted or not.


    registerTokenVote(uint256 tokenId_, bool status_)

    Description: Only callable by ESCROW_VOTE_MANAGER. Records that a token has voted (or not) in the current epoch.


    moveVotes(uint256 tokenId_, address from_, address to_)

    Description: Called by DELEGATION_MANAGER to transfer voting power if delegated. Ensures the token exists.


    getLockInfoByTokenId(uint256 tokenId_)

    Description: Returns the lock’s current amount, unlock timestamp, and associated vesting wallets.


    getRemainingFreezeTimeByTokenId(uint256 tokenId_)

    Description: Reports how many seconds remain until a token can be transferred again after deboost. Returns 0 if the freeze period has elapsed.


    getCheckpoint(address account_, uint32 index_)

    Description: Retrieves the checkpoint at index_ for account_, listing token ownership at that historical checkpoint.


    getPastVotes(address account_, uint256 timestamp_)

    Description: Calculates an account’s total voting power at a previous timestamp_, summing the power of all tokens they held at that time.


    getTotalSupply()

    Description: Returns the total voting power across all locks at the current time.


    getPastTotalSupply(uint256 timestamp_)

    Description: Returns the total voting power at a specific timestamp_. Uses the VotingPowerHelper for historical calculations.


    getPastVotesByTokenId(uint256 tokenId_, uint256 timestamp_)

    Description: Computes a single token’s voting power at a past timestamp_, factoring in rate-of-change data.


    getBoostersByTokenId(uint256 tokenId_)

    Description: Lists all booster NFT IDs currently enhancing the lock identified by tokenId_.


    checkAuthorized(address owner_, address spender_, uint256 tokenId_)

    Description: Checks if spender_ is permitted (owner, approved address, or operator) to manage the NFT for tokenId_.


    exists(uint256 tokenId_)

    Description: Returns true if an NFT for tokenId_ has been minted (i.e., the lock exists).


    Internal and Private Functions

    _createLock(...)

    Signature:

    Description: Core logic for creating a new lock. Mints an NFT, stores lock info, and transfers tokens or vesting wallets if needed.


    _deposit(...)

    Signature:

    Description: Adds more EYWA to a lock, updating voting power calculations.


    _modifyBoost(...)

    Signature:

    Description: Adds or removes booster NFTs to/from a lock. Adjusts coverage and recalculates voting power accordingly.


    _updateLock(...)

    Signature:

    Description: Recomputes and stores new voting power points whenever a lock’s amount or unlock time changes. Adjusts historical checkpoints and the global epoch.


    _moveVotes(...)

    Signature:

    Description: Reassigns voting power from from_ to to_ if the NFT’s ownership changes. Creates or updates checkpoints for both addresses.


    _clearStorage(...)

    Signature:

    Description: Clears all references and data for a withdrawn or burned lock, freeing storage.


    _findCheckpoint(...)

    Signature:

    Description: Helper to find or create the index for a checkpoint at the current timestamp for a given account.


    _calculateModifiedLockAmount(...)

    Signature:

    Description: Calculates the final lock amount after factoring in booster NFT coverage and rarity-based multipliers. If coverage exceeds lock amount, the algorithm partial-applies boosters in descending rarity.


    Events

    LockWithdrawn(address indexed recipient, uint256 indexed tokenId, uint256 indexed value)

    Emitted When: A user withdraws tokens from an expired lock. The NFT is burned, and booster NFTs/vesting wallets are returned.


    Errors

    • InvalidBeneficiary()

    • InvalidVestingWallet()

    • InvalidLockDuration()

    • InvalidLockAmount()

    • InvalidCollectionTokenId(uint256 tokenId)

    • InvalidArrayLength()

    • InvalidRarity()

    • NonExistentToken()

    • ExtendedUnlockTimeMustBeGreater()

    • AttachmentsLimitExceeded()

    • LockStillActive()

    • LockCurrentlyVoting()

    • MaximumNumberOfDelegatesExceeded()

    • BoostModificationAfterVoting()

    • UnauthorizedCaller()

    • TransferFrozenDueToDeboost()

    These errors ensure that contract rules regarding lock durations, amounts, boosters, freeze periods, and ownership checks are strictly enforced.


    Summary

    EscrowManager provides a robust system for locking EYWA tokens in exchange for NFT-based positions (veEYWA). Each lock can combine direct token transfers, vesting wallets, and booster NFTs, forming dynamic voting power that evolves over time. Freeze periods after deboosts and careful checkpointing logic protect against immediate manipulations of lock amounts and ownership. Through a clear interface defined in IEscrowManager, external ecosystem components (e.g., delegation managers, vote managers, NFT collections) can seamlessly integrate with this locking mechanism to support governance, incentive distribution, and user engagement within the CrossCurve platform.

    Emission Manager (IEmissionManagerV1): Supplies emission epochs and total reward amounts.

  • Rewards Distributor Factory (IRewardsDistributorFactoryV1): Deploys incentive reward distributor contracts for new gauges.

  • Gauge Factory (IGaugeFactoryV1): Deploys gauge contracts, which are used to distribute rewards based on votes.

  • Reward Distributors (IRewardsDistributor): Handle depositing and withdrawing of votes and distributing claimable incentives.

  • The contract also includes logic for:

    1. Voting with multiple token IDs: A user can cast votes across multiple locks (NFTs) for multiple pools.

    2. Transfer Freeze after Deboost: Adds a cooldown period preventing NFT transfers after a lock has been deboosted in the Escrow Manager.

    3. Gauge Lifecycle Management: Owners can create, kill, or revive gauges.

    4. Reward Distribution: Accumulates gauge rewards and distributes them after each epoch.

    By implementing IEscrowVoteManagerV1, EscrowVoteManagerV1 provides a standardized API for gauge-based governance interactions in the CrossCurve ecosystem.


    Inherited Contracts and Interfaces

    • UUPSUpgradeable (OpenZeppelin): Provides upgrade functionality under the UUPS proxy pattern, restricted to the contract owner.

    • OwnableUpgradeable (OpenZeppelin): Manages ownership, allowing only the owner to modify critical parameters and authorize upgrades.

    • IEscrowVoteManagerV1: Defines core methods (e.g., vote, createGauge, distributeRewardsForMultipleGauges) and events for this contract.

    Additional External References:

    • SafeERC20, IERC20 (OpenZeppelin): Handles secure ERC20 operations for distributing and approving token transfers.

    • Math (OpenZeppelin): Provides utility math functions, e.g., Math.max.

    • IEscrowManager: Holds locked token data and checks voting power and freeze logic.

    • IRewardsDistributorFactoryV1, IGaugeFactoryV1: Deploy new reward distributors and gauge contracts, respectively.

    • IGaugeV1: Interface for a gauge contract that can receive reward notifications (notifyRewardAmount).

    • IEmissionManagerV1: Informs about epoch starts and ensures updated weekly distributions.


    Constants

    • EPOCH_DURATION: Duration of each emission/gauge epoch (1 week).

    • PRECISION: Scaling factor (1e18) for reward calculations and distribution indexes.


    State Variables

    • s_transferFreezeAfterDeboost (uint256) Duration (in seconds) that locks are non-transferable after a deboost in the Escrow Manager.

    • s_emissionManager (address) Address of the emission manager contract, which calls this manager to notify new rewards.

    • s_eywa (address) Address of the EYWA token used for gauge rewards.

    • s_escrowManager (IEscrowManager) Reference to the contract that manages locked tokens (NFT-based locks).

    • s_rewardsDistributorFactory (IRewardsDistributorFactoryV1) Creates new rewards distributor contracts for gauges.

    • s_gaugeFactory (IGaugeFactoryV1) Creates new gauge contracts.

    • _s_distributionIndex (uint256) A global distribution index used to compute new reward distribution shares after the emission manager notifies reward amounts.

    • s_pools (address[]) An array of pool addresses that have gauges.

    • s_gaugeByPool (mapping(address => address)) Maps a pool address to its gauge contract address.

    • s_poolByGauge (mapping(address => address)) Reverse map: gauge address to the corresponding pool address.

    • s_incentiveRewardsDistributorByGauge (mapping(address => address)) Tracks which incentive rewards distributor belongs to which gauge.

    • s_votesByEpochAndPool (mapping(uint256 => mapping(address => uint256))) Records how many votes each pool has received in a given epoch (keyed by epoch start timestamp).

    • s_claimableRewardsByGauge (mapping(address => uint256)) Shows how many EYWA tokens each gauge can claim, waiting to be distributed.

    • s_lastDistributionTimestampByGauge (mapping(address => uint256)) Timestamp of the most recent reward distribution for each gauge.

    • s_isGauge (mapping(address => bool)) Indicates if an address is recognized as a gauge.

    • s_isWhitelistedToken (mapping(address => bool)) Tracks which tokens are whitelisted for reward distributions and voting.

    • s_isActiveGauge (mapping(address => bool)) If true, the gauge is active and can receive new rewards.

    • s_usedVotesByTokenId (mapping(uint256 => uint256)) How many votes a lock (NFT) has allocated.

    • s_lastVotedTimestampByTokenId (mapping(uint256 => uint256)) Timestamp of the last time a token ID voted, used to reset or poke votes.

    • s_votedPoolsByTokenId (mapping(uint256 => address[])) List of pools each token ID is currently voting for.

    • s_totalVotesByEpoch (mapping(uint256 => uint256)) Cumulative votes across all pools in a given epoch.

    • s_votesByTokenIdAndPool (mapping(uint256 => mapping(address => uint256))) Number of votes allocated by a specific token ID to a particular pool.

    • _s_supplyDistributionIndex (mapping(address => uint256)) Per-gauge distribution index to track how much of the global distribution index the gauge has accounted for.


    Constructor

    • Description: Disables contract initializers to prevent re-initialization in a UUPS proxy context.


    External Functions (Defined by IEscrowVoteManagerV1)

    initialize(...)

    Description: Configures ownership, references, and initial state:

    • Sets s_transferFreezeAfterDeboost to 4 hours initially.

    • References the emission manager, escrow manager, gauge/rewards distributor factories, and whitelists initial tokens.


    updateTransferFreezeAfterDeboost(uint256 transferFreezeAfterDeboost_)

    Description: Updates the freeze period (in seconds) that applies after a deboost in Escrow Manager. This restricts NFT transfers for transferFreezeAfterDeboost_ seconds.

    Events:

    • Emits TransferFreezeAfterDeboostUpdated(oldDuration, newDuration).


    createGauge(address pool_, IDistributionCreator.CampaignParameters calldata campaignParameters_)

    Description: Creates a new gauge for a specified pool by:

    1. Deploying an incentive rewards distributor via s_rewardsDistributorFactory.

    2. Deploying a gauge contract via s_gaugeFactory.

    3. Tracking the new gauge and marking it as active.

    Checks:

    • Ensures the pool does not already have a gauge.

    Events:

    • Emits GaugeCreated(pool_, gauge, incentiveRewardsDistributor).


    killGauge(address gauge_)

    Description: Deactivates a gauge so it stops receiving future rewards. Does not remove votes or claimable rewards; simply marks it inactive.

    Checks:

    • s_isActiveGauge[gauge_] must be true.

    Events:

    • Emits GaugeKilled(gauge_).


    reviveGauge(address gauge_)

    Description: Reactivates a previously killed gauge, allowing it to receive rewards again.

    Checks:

    • s_isActiveGauge[gauge_] must be false.

    Events:

    • Emits GaugeRevived(gauge_).


    setWhitelistStatusForTokens(address[] calldata tokens_, bool[] calldata statuses_)

    Description: Updates whether tokens are whitelisted for reward distribution. Only callable by the contract owner. Checks input array lengths.

    Events:

    • Emits WhitelistStatusUpdatedForTokens(operator, tokens_, statuses_).


    vote(uint256[] calldata tokenIds_, address[][] calldata pools_, uint256[][] calldata weights_)

    Description: Allows a user to cast votes for multiple token IDs across multiple pools. For each token ID:

    1. Authorizes caller via IEscrowManager.checkAuthorized.

    2. Validates array lengths for pools and weights.

    3. Performs _vote(...) to reset old votes, allocate new votes, and update vote counts.


    reset(uint256 tokenId_)

    Description: Removes all existing votes for a given token ID, setting them to zero. The caller must be authorized. Updates the token’s last vote timestamp.


    poke(uint256 tokenId_)

    Description: Recalculates (re-casts) votes for a token ID based on updated voting power without changing the vote distribution pattern. The function still calls _vote(...) internally using the same pools and weights previously allocated.


    claimIncentives(address[] calldata incentiveRewardsDistributors_, address[][] calldata rewardTokens_)

    Description: Claims incentives for the caller from multiple rewards distributors. Each distributor has a list of reward tokens. Forwards the call to IRewardsDistributor.getReward.


    notifyRewardAmount(uint256 rewardAmount_)

    Description: Only callable by s_emissionManager. Increments _s_distributionIndex by an amount proportional to rewardAmount_ / totalVotesInPreviousEpoch. If no votes or unauthorized call, reverts.

    Events:

    • Emits RewardNotified(rewardAmount_).


    distributeRewardsForMultipleGauges(address[] calldata gauges_)

    Description: Triggers an epoch update in the emission manager, then calls _distributeRewards(...) for each gauge in gauges_.


    distributeRewardsForGaugesInRange(uint256 start_, uint256 end_)

    Description: Also triggers an emission manager epoch update, then iterates through s_pools[start_ ... end_] to distribute rewards to each gauge.


    getPoolsCount()

    Description: Returns the number of pools (and thus gauges) tracked in s_pools.


    nextEpochStart()

    Description: Returns the next epoch’s start time as s_currentEpochStart + EPOCH_DURATION from the emission manager.


    currentEpochStart()

    Description: Returns the current epoch’s start time from the emission manager.


    Internal and Private Functions

    _authorizeUpgrade(address)

    Description: Restricts contract upgrades to the owner.


    _vote(...)

    Description: Handles the actual voting steps for a single token ID:

    1. Calls _reset(...) to remove existing votes.

    2. Proportionally allocates votingPower_ across pools based on weights_.

    3. Updates s_votesByEpochAndPool, s_votesByTokenIdAndPool, and s_votedPoolsByTokenId.

    4. Deposits votes into the associated gauge’s incentive rewards distributor.

    5. Tracks total votes used by the token ID (s_usedVotesByTokenId).

    6. Informs escrow manager the token has voted.

    Events:

    • VoteCast on each pool voted for.


    _reset(uint256 tokenId_)

    Description: Clears existing votes for tokenId_ by:

    • Withdrawing votes from all previously voted pools (if the token voted in the current epoch).

    • Adjusting s_votesByEpochAndPool and s_votesByTokenIdAndPool.

    • Updating the total votes for the epoch.

    • Marking the token as not voted in the escrow manager.

    • Emitting VotesAbstained.


    _distributeRewards(address gauge_, uint256 currentEpochStart_)

    Description: Distributes claimable EYWA tokens to a specified gauge. If the gauge is inactive, does nothing. Otherwise:

    1. Calls _updateRewardIndexForGauge(...).

    2. Notifies the gauge of claimable rewards via notifyRewardAmount.

    Events:

    • RewardsDistributed after successful distribution.


    _updateRewardIndexForGauge(address gauge_, uint256 currentEpochStart_)

    Description: Calculates how many new tokens a gauge can claim using the global distribution index. If there were votes in the previous epoch (currentEpochStart_ - EPOCH_DURATION), the gauge's share of _s_distributionIndex is updated, and claimable rewards are added to s_claimableRewardsByGauge[gauge_].


    Events

    • TransferFreezeAfterDeboostUpdated(oldDuration, newDuration) Emitted when the freeze period is changed.

    • GaugeCreated(pool, gauge, incentiveRewardsDistributor) Emitted upon successful gauge creation.

    • GaugeKilled(gauge), GaugeRevived(gauge) Emitted when a gauge is deactivated or reactivated.

    • WhitelistStatusUpdatedForTokens(operator, tokens, statuses) Shows updated whitelist status for multiple tokens.

    • RewardNotified(rewardAmount) Occurs when the emission manager notifies a new reward sum.

    • VoteCast(voter, pool, tokenId, votes) Occurs for each pool a token ID votes for.

    • VotesAbstained(voter, pool, tokenId, votes) Occurs when votes are reset/removed for a given pool.

    • RewardsDistributed(distributor, gauge, rewardAmount) Shows distribution of accumulated rewards to a gauge.


    Errors

    • GaugeDoesNotExist() Thrown if a user tries to vote for a gauge that is not known (no gauge for that pool).

    • GaugeAlreadyExists() Thrown when creating a gauge for a pool that already has one.

    • GaugeNotActive() Thrown if an action (like voting or distributing) is attempted on an inactive gauge.

    • GaugeAlreadyActive() Thrown if reactivating a gauge that is already active.

    • UnauthorizedAccess() Thrown if a non-authorized caller tries to vote or manage votes.

    • InvalidArrayLengths() Thrown if arrays for tokenIds_, pools_, or weights_ do not match in length.

    • ZeroEntry() Thrown if some operation results in zero (e.g., zero votes allocated to a pool).

    • AlreadyVoted() Not used in current logic, but defined in the interface.

    • ProtectedFunctionSelectorUsed() Not used here (relates to proposal manager).

    • InvalidSliceParameters() Not used here, pertains to slicing logic in other modules.


    Summary

    EscrowVoteManagerV1 orchestrates multi-token, multi-pool voting within the CrossCurve ecosystem. By coordinating gauges, incentive reward distribution, epoch-based reward notifications from the emission manager, and freeze logic from the escrow manager, it ensures a secure, transparent mechanism for users to direct token emissions to liquidity pools and other incentive-based programs. With features like deboost freeze periods and gauge lifecycle control, the contract provides flexible governance and reward distribution for token holders.

    IncentiveRewardsDistributor (Concrete)
     └── RewardsDistributor (Abstract)
          └── IRewardsDistributor (Interface)
    constructor(address escrowVoteManager_, address escrowManager_) {
        ESCROW_VOTE_MANAGER = escrowVoteManager_;
        ESCROW_MANAGER = escrowManager_;
    }
    function deposit(uint256 amount_, uint256 tokenId_) external
    function withdraw(uint256 amount_, uint256 tokenId_) external
    function getRewardTokensCount() external view returns (uint256)
    function earned(address owner_, address rewardToken_) public view returns (uint256, uint256)
    function earnedByEpoch(address owner_, address rewardToken_, uint256 epoch_) public view returns (uint256)
    function rewardPerToken(address rewardToken_, uint256 epoch_) public view returns (uint256)
    function getReward(address owner_, address[] calldata rewardTokens_) external virtual;
    function notifyRewardAmount(address rewardToken_, uint256 rewardAmount_) external virtual;
    function _getReward(address owner_, address[] calldata rewardTokens_) internal
    function _notifyRewardAmount(address sender_, address rewardToken_, uint256 rewardAmount_) internal
    constructor(address escrowVoteManager_, address escrowManager_) 
        RewardsDistributor(escrowVoteManager_, escrowManager_)
    {}
    function getReward(
        address owner_, 
        address[] calldata rewardTokens_
    )
        external
        override (RewardsDistributor, IIncentiveRewardsDistributor)
        nonReentrant
    function notifyRewardAmount(
        address rewardToken_, 
        uint256 rewardAmount_
    )
        external
        override (RewardsDistributor, IIncentiveRewardsDistributor)
        nonReentrant
    constructor(
        address escrowVoteManager_,
        address delegationManager_,
        IERC20 eywa_,
        ICollection collection_,
        IWalletFactory walletFactory_,
        IMetadataProviderV1 metadataProvider_
    ) 
        ERC721("EYWA DAO NFT", "veEYWA")
    {
        ...
    }
    function createLock(
        uint256 lockAmount_,
        uint256 lockDuration_,
        address recipient_
    ) 
        external 
        nonReentrant
    function createLock(
        uint256 lockDuration_,
        address recipient_,
        address[] calldata vestingWallets_
    ) 
        external 
        nonReentrant
    function createLock(
        uint256 lockDuration_,
        address recipient_,
        uint256[] calldata collectionTokenIds_
    )
        external 
        nonReentrant
    function deposit(uint256 tokenId_, uint256 lockAmount_) external nonReentrant
    function depositFor(uint256 tokenId_, uint256 lockAmount_) external nonReentrant
    function boost(uint256 tokenId_, uint256[] calldata collectionTokenIds_) external nonReentrant
    function deboost(uint256 tokenId_, uint256[] calldata collectionTokenIds_) external nonReentrant
    function withdraw(uint256 tokenId_) external nonReentrant
    function extend(uint256 tokenId_, uint256 lockDuration_) external nonReentrant
    function setVoteStatus(uint256 tokenId_, bool status_) external
    function registerTokenVote(uint256 tokenId_, bool status_) external
    function moveVotes(uint256 tokenId_, address from_, address to_) external
    function getLockInfoByTokenId(uint256 tokenId_) 
        external 
        view 
        returns (
            int128 lockAmount_,
            uint256 unlockTime_,
            address[] memory vestingWallets_
        )
    function getRemainingFreezeTimeByTokenId(uint256 tokenId_) external view returns (uint256)
    function getCheckpoint(address account_, uint32 index_) external view returns (Checkpoint memory)
    function getPastVotes(address account_, uint256 timestamp_) external view returns (uint256 votes_)
    function getTotalSupply() external view returns (uint256)
    function getPastTotalSupply(uint256 timestamp_) external view returns (uint256)
    function getPastVotesByTokenId(uint256 tokenId_, uint256 timestamp_) external view returns (uint256)
    function getBoostersByTokenId(uint256 tokenId_) external view returns (uint256[] memory boosters_)
    function checkAuthorized(address owner_, address spender_, uint256 tokenId_) external view returns (bool)
    function exists(uint256 tokenId_) external view returns (bool)
    function _createLock(
        uint256 lockAmount_,
        uint256 lockDuration_,
        address recipient_,
        address[] memory vestingWallets_,
        LockModificationType lockModificationType_
    ) private
    function _deposit(uint256 tokenId_, uint256 lockAmount_) private
    function _modifyBoost(
        uint256 tokenId_, 
        uint256[] memory collectionTokenIds_, 
        LockModificationType lockModificationType_
    ) private
    function _updateLock(
        uint256 tokenId_,
        LockInfo memory previousLockInfo_,
        LockInfo memory currentLockInfo_
    ) private
    function _moveVotes(uint256 tokenId_, address from_, address to_) private
    function _clearStorage(uint256 tokenId_) private
    function _findCheckpoint(address account_) private view returns (uint32)
    function _calculateModifiedLockAmount(
        uint256 tokenId_,
        uint256 coverage_,
        uint256 lockAmount_
    ) private view returns (uint256)
    uint256 public constant EPOCH_DURATION = 1 weeks;
    uint256 public constant PRECISION = 1e18;
    constructor() {
        _disableInitializers();
    }
    function initialize(
        address owner_,
        address emissionManager_,
        address eywa_,
        IEscrowManager escrowManager_,
        IRewardsDistributorFactoryV1 rewardsDistributorFactory_,
        IGaugeFactoryV1 gaugeFactory_,
        address[] calldata whitelistedTokens_
    ) external initializer
    function updateTransferFreezeAfterDeboost(uint256 transferFreezeAfterDeboost_) external onlyOwner
    function createGauge(
        address pool_,
        IDistributionCreator.CampaignParameters calldata campaignParameters_
    ) external onlyOwner
    function killGauge(address gauge_) external onlyOwner
    function reviveGauge(address gauge_) external onlyOwner
    function setWhitelistStatusForTokens(
        address[] calldata tokens_,
        bool[] calldata statuses_
    ) external onlyOwner
    function vote(
        uint256[] calldata tokenIds_,
        address[][] calldata pools_,
        uint256[][] calldata weights_
    ) external
    function reset(uint256 tokenId_) external
    function poke(uint256 tokenId_) external
    function claimIncentives(
        address[] calldata incentiveRewardsDistributors_, 
        address[][] calldata rewardTokens_
    ) external
    function notifyRewardAmount(uint256 rewardAmount_) external
    function distributeRewardsForMultipleGauges(address[] calldata gauges_) external
    function distributeRewardsForGaugesInRange(uint256 start_, uint256 end_) external
    function getPoolsCount() external view returns (uint256)
    function nextEpochStart() external view returns (uint256)
    function currentEpochStart() external view returns (uint256)
    function _authorizeUpgrade(address) internal override onlyOwner
    function _vote(
        uint256 tokenId_,
        uint256 votingPower_,
        address[] memory pools_,
        uint256[] memory weights_
    ) private
    function _reset(uint256 tokenId_) private
    function _distributeRewards(address gauge_, uint256 currentEpochStart_) private
    function _updateRewardIndexForGauge(address gauge_, uint256 currentEpochStart_) private

    Llamaville Mini App

    Your activity in the Llamaville app allows you to farm cryptodollars and receive new social and on-chain activity tasks as part of the 2nd season of our Airdrop program. Llamaville is a complete educational app. It immerses users into the world of crypto, allowing them to go through all the stages of growth, from fear and greed to success — without risking any real losses. The app is accessible only by invite, which you can request in EYWA’s official Telegram and Discord communities

  • Referral activity

    The 3-level referral program allows you to receive points for the activity of your friends. Generate your personal referral link by clicking Get your Referral link and invite others to join the program. You will instantly get a portion of the points as they earn them: 10% for level 1 referrals, 6% for level 2, and 4% for level 3. You can find more details about this program below.

  • 7

    100

    $5,000 and up

    200 points

    -

    1

    10

    2

    20

    3

    30

    4

    40

    5

    60

    6

    $5 to $49

    4.2 points

    0.33 points for each $5 above $5

    $50 to $99

    7 points

    1.8 points for each $5 above $50

    $100 to $999

    25 points

    0.5 points for each $10 above $100

    $1,000 to $4,999

    70 points

    $700 to $999

    7 points

    -

    $1,000 to $9,999

    10 points

    0.5 for each $100 above the first $1,000

    $10,000 to $49,999

    55 points

    4,9 for each $1,000 above $10,000

    $50,000 and up

    250 points

    xSTABLE
    xWETH
    here
    Join
    Trade
    Liquidity
    Trade
    CrossCurve pools
    Liquidity
    Liquidity
    EYWA's Twitter
    link

    80

    3.3 points for each $100 above $1000

    -

    Cross-Chain Awareness: Maintains a set of valid chain IDs for bridging proposals, allowing secure multi-chain governance actions when using the bridge.

  • Custom Quorum Rules: Allows the owner to adjust the quorum fraction within set bounds (25%–80%).

  • The contract also integrates with a Calldata Helper (CALLDATA_HELPER) to decode function selectors from the bridging calls. By extending Governor, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl, and Ownable, ProposalManager offers a robust on-chain DAO mechanism with time-locked execution, vote counting, adjustable quorum, and protective measures for crucial function selectors.


    Inherited Contracts and Interfaces

    1. Governor (OpenZeppelin): Base contract for on-chain governance, offering functionalities such as proposal creation, voting, proposal states, etc.

    2. GovernorCountingSimple (OpenZeppelin): Implements a simple vote counting mechanism: For, Against, and Abstain.

    3. GovernorVotes (OpenZeppelin): Integrates an IVotes token (in this case, an escrow manager providing voting power) for calculating a user’s votes at proposal snapshot blocks.

    4. GovernorVotesQuorumFraction (OpenZeppelin): Defines quorum as a fraction of the total supply of the governance token. The fraction is adjustable by the contract’s owner within defined limits.

    5. GovernorTimelockControl (OpenZeppelin): Integrates a TimelockController for executing proposals after a governance-defined delay.

    6. Ownable (OpenZeppelin): Provides basic ownership functionality, allowing the owner to perform restricted actions (e.g., adjusting quorum fraction, managing chain IDs/selectors).

    7. IProposalManager (Custom): Declares additional functions, errors, and events specifically for managing cross-chain or bridging-based proposals, including protected selectors.

    Additional External References:

    • ICalldataHelperV1 (CALLDATA_HELPER): A contract that decodes selectors from proposal call data, used for identifying protected function selectors in bridging calls.

    • EnumerableSet (OpenZeppelin): Used to store a set of valid chain IDs, ensuring efficient addition, removal, and existence checks.


    Constants

    • MINIMUM_QUORUM_NUMERATOR (25): Minimum permissible quorum fraction (25%).

    • MAXIMUM_QUORUM_NUMERATOR (80): Maximum permissible quorum fraction (80%).


    State Variables

    • CALLDATA_HELPER (ICalldataHelperV1 immutable) The address of a helper contract used to decode function selectors for bridging calls. Set in the constructor and cannot be changed.

    • s_bridge (address) The address of the bridge contract used for cross-chain proposals or calls. Initially set in the constructor, can be updated by setBridge.

    • _chainIds (EnumerableSet.UintSet) A private set of valid chain IDs recognized by the contract. The owner can add or remove chain IDs via addChainId / removeChainId.

    • s_protectedSelectorsByChainIdAndTarget (mapping(uint256 => mapping(address => bytes4[]))) Stores arrays of protected function selectors for each (chainId, target) pair.

    • s_isProtectedSelector (mapping(uint256 => mapping(address => mapping(bytes4 => bool)))) A quick boolean lookup indicating if a particular function selector is protected on a given chainId and target address.


    Constructor

    • Parameters:

      • escrowManager_: An IVotes-compliant contract (e.g., an escrow manager) used for vote calculations.

      • timelock_: The TimelockController contract address used to queue and execute proposals after a time delay.

      • calldataHelper_: The helper contract for decoding function selectors in bridging calls.

      • owner_: Address designated as the owner of this contract (can set quorum fraction, manage chain IDs, etc.).

      • bridge_: The initial address of the cross-chain bridge.

    • Logic and Effects:

      1. Initializes the underlying Governor modules:

        • Governor("EYWA DAO") sets the governor name.


    External Functions

    1. setBridge(address bridge_)

    • Description: Updates the s_bridge address used for bridging calls. Only callable by the contract owner.

    • Parameters:

      • bridge_: The new bridge contract address.

    • Events:

      • BridgeUpdated(oldBridge, newBridge) logs the address change.


    2. addChainId(uint256 chainId_)

    • Description: Adds a new chain ID to _chainIds. If the chain ID already exists, it reverts.

    • Checks:

      • _chainIds.add(chainId_) must return true, otherwise reverts with ChainIdAlreadyExists(chainId_).


    3. removeChainId(uint256 chainId_)

    • Description: Removes an existing chain ID from _chainIds. If the chain ID does not exist, it reverts.

    • Checks:

      • _chainIds.remove(chainId_) must return true, otherwise reverts with ChainIdDoesNotExist(chainId_).


    4. getChainIdsLength()

    • Description: Returns the number of chain IDs stored in _chainIds.

    • Return:

      • uint256: The length of _chainIds.


    5. getChainIdAtIndex(uint256 index_)

    • Description: Retrieves a chain ID from _chainIds by index_.

    • Return:

      • uint256: The chain ID at the specified index.


    6. addProtectedSelector(uint256 chainId_, address target_, bytes4 selector_)

    • Description: Marks a function selector (selector_) as protected on a particular chainId_ and target_. If the chain ID doesn’t exist or the selector is already protected, it reverts.

    • Events & Checks:

      • Must have _chainIds.contains(chainId_), otherwise InvalidChainId(...).

      • If s_isProtectedSelector[chainId_][target_][selector_] is true, reverts with SelectorAlreadyExists(...).

      • Adds the selector to s_protectedSelectorsByChainIdAndTarget[chainId_][target_] and sets s_isProtectedSelector[chainId_][target_][selector_] = true.


    7. removeProtectedSelector(uint256 chainId_, address target_, bytes4 selector_)

    • Description: Removes a protected function selector from s_protectedSelectorsByChainIdAndTarget. If the chain ID isn’t recognized or the selector isn’t actually protected, it reverts.

    • Logic:

      1. Ensures chainId_ is valid in _chainIds.

      2. Checks if s_isProtectedSelector[chainId_][target_][selector_] == true; otherwise reverts with SelectorDoesNotExist(...).

      3. Searches in the array s_protectedSelectorsByChainIdAndTarget[chainId_][target_], removes the entry by swapping the last element, then popping the array.

      4. Deletes s_isProtectedSelector[chainId_][target_][selector_].


    8. updateQuorumNumerator(uint256 quorumNumerator_)

    • Description: An override from GovernorVotesQuorumFraction that checks if the new quorum fraction is within [MINIMUM_QUORUM_NUMERATOR, MAXIMUM_QUORUM_NUMERATOR]. Otherwise reverts with GovernorInvalidQuorumFraction(...).


    9. updateTimelock(TimelockController)

    • Description: An override from GovernorTimelockControl. This function does nothing here (the timelock is set in the constructor).


    10. propose(...) (Overridden from Governor)

    • Description:

      • Creates a new proposal. Before creation, the contract calls _checkSelectors(...) to see if any protected calls are included in calldatas_. If protected calls are found but the proposer is not the owner, it reverts with ProtectedFunctionSelectorUsed().

      • After checking, it calls super.propose(...) to proceed with the standard Governor proposal workflow.

    • Parameters:

      • targets_, values_, calldatas_: Arrays specifying which contracts and functions to call, with how much ETH, plus the function data.

      • description_: A string describing the proposal.

    • Return:

      • uint256: The ID of the newly created proposal.


    Integration with OpenZeppelin Governor Modules

    clock() (IERC6372)

    • Description: Returns the current timestamp as a uint48. Used by the governance system for time-related logic.

    state(uint256 proposalId_)

    • Description: Returns the current state of a proposal (Pending, Active, Canceled, Defeated, Succeeded, Queued, Expired, or Executed), integrating timelock considerations.

    quorum(uint256 timepoint_)

    • Description: Calculates the number of votes required for quorum at a given timepoint_, i.e., (totalSupplyAt(timepoint_) * quorumNumerator(timepoint_)) / quorumDenominator().

    CLOCK_MODE()

    • Description: Returns "mode=timestamp", indicating that block timestamps (instead of block numbers) are used for governance timing.

    proposalThreshold(), votingDelay(), votingPeriod(), proposalNeedsQueuing(...)

    These standard overrides define:

    • proposalThreshold(): 2_500e18 — minimum voting power needed to create a proposal.

    • votingDelay(): 2 days — time between proposal creation and the start of voting.

    • votingPeriod(): 5 days — how long votes are accepted.

    • proposalNeedsQueuing(...): returns true, indicating proposals must be queued in the timelock after passing, before execution.


    Internal Functions

    _checkSelectors(...)

    • Description:

      • Iterates over targets_ and associated calldatas_, extracting the function selector for each. Then checks if it is among the protected selectors for the given chain ID (block.chainid) or if the target is the s_bridge address.

      • If any call uses a protected selector and proposalCreator_ is not the contract owner, reverts with ProtectedFunctionSelectorUsed().

    • Parameters:

      • proposalCreator_: The address that created the proposal.

      • targets_: The array of target contract addresses.

    • Logic:

      1. If targets_[i] equals s_bridge, decodes further with CALLDATA_HELPER.decode(...) to find (m_calldata, m_target, m_chainId). Then extracts the first 4 bytes (selector) from m_calldata.


    _queueOperations(...), _executeOperations(...), _cancel(...), _executor()

    These are standard overrides from GovernorTimelockControl that handle queueing, executing, and canceling proposals in the timelock. The _executeOperations override also calls _checkSelectors(...) again before executing the proposal.


    Events

    1. BridgeUpdated(address indexed oldBridge, address indexed newBridge)

      • Emitted when the bridge address changes via setBridge.

    No additional custom events are defined besides those in the IProposalManager interface and standard Governor events.


    Errors

    From IProposalManager, we have:

    • ChainIdAlreadyExists(uint256 chainId)

    • ChainIdDoesNotExist(uint256 chainId)

    • SelectorAlreadyExists(bytes4 selector)

    • SelectorDoesNotExist(bytes4 selector)

    • InvalidChainId(uint256 chainId)

    • ProtectedFunctionSelectorUsed()

    • GovernorInvalidQuorumFraction(uint256 newQuorumNumerator, uint256 quorumDenominator) (part of GovernorVotesQuorumFraction logic)


    Summary

    ProposalManager extends and customizes OpenZeppelin’s Governor to cater to CrossCurve DAO’s multi-chain governance needs. Through protective measures (_checkSelectors), it guards certain function calls on specific chain IDs and target addresses, ensuring only the contract owner can propose them. Additionally, it manages a dynamic range of acceptable quorum fractions and integrates with a TimelockController for secure, time-delayed proposal execution. By combining these features with ICalldataHelperV1 for decoding bridging calls, ProposalManager offers a flexible yet secure governance solution for cross-chain proposals in the CrossCurve ecosystem.

    uint256 public constant MINIMUM_QUORUM_NUMERATOR = 25;
    uint256 public constant MAXIMUM_QUORUM_NUMERATOR = 80;
    constructor(
        IVotes escrowManager_,
        TimelockController timelock_,
        ICalldataHelperV1 calldataHelper_,
        address owner_,
        address bridge_
    )
        Governor("EYWA DAO")
        GovernorVotes(escrowManager_)
        GovernorVotesQuorumFraction(50)
        GovernorTimelockControl(timelock_)
        Ownable(owner_)
    {
        CALLDATA_HELPER = calldataHelper_;
        s_bridge = bridge_;
    }
    function setBridge(address bridge_) external onlyOwner
    function addChainId(uint256 chainId_) external onlyOwner
    function removeChainId(uint256 chainId_) external onlyOwner
    function getChainIdsLength() external view returns (uint256)
    function getChainIdAtIndex(uint256 index_) external view returns (uint256)
    function addProtectedSelector(uint256 chainId_, address target_, bytes4 selector_) external onlyOwner
    function removeProtectedSelector(uint256 chainId_, address target_, bytes4 selector_) external onlyOwner
    function updateQuorumNumerator(uint256 quorumNumerator_) external override onlyOwner
    function updateTimelock(TimelockController) external override
    function propose(
        address[] memory targets_,
        uint256[] memory values_,
        bytes[] memory calldatas_,
        string memory description_
    )
        public
        override (Governor, IGovernor)
        returns (uint256)
    function clock() public view override (Governor, GovernorVotes, IERC6372) returns (uint48)
    function state(uint256 proposalId_) public view override(Governor, GovernorTimelockControl, IGovernor) returns (ProposalState)
    function quorum(uint256 timepoint_) public view override (Governor, GovernorVotesQuorumFraction, IGovernor) returns (uint256)
    function CLOCK_MODE() public pure override (Governor, GovernorVotes, IERC6372) returns (string memory)
    function _checkSelectors(
        address proposalCreator_,
        address[] memory targets_,
        bytes[] memory calldatas_
    )
        private
        view
    GovernorVotes(escrowManager_)
    specifies the votes token source.
  • GovernorVotesQuorumFraction(50) sets an initial quorum fraction of 50%.

  • GovernorTimelockControl(timelock_) ties this governor to the specified timelock.

  • Ownable(owner_) sets the contract owner.

  • Stores CALLDATA_HELPER and s_bridge.

  • calldatas_
    : The array of encoded function calls corresponding to each target.
    Checks s_protectedSelectorsByChainIdAndTarget[m_chainId][m_target].
  • If matched, marks m_isProtected = true.

  • Otherwise, if targets_[i] != s_bridge, reads the first 4 bytes from calldatas_[i] as the selector and checks s_protectedSelectorsByChainIdAndTarget[block.chainid][targets_[i]].

  • If m_isProtected == true and proposalCreator_ != owner(), revert with ProtectedFunctionSelectorUsed().

  • Locker Interface

    Locker Interface Description

    The Locker is a smart contract where holders lock their EYWA tokens, EYWA token safes, EYWA NFTs with EYWA tokens, and project safes for various durations. The purpose of such locking is to obtain project votes - veEYWA voting power. A user’s voting power depends on the duration for which their tokens are locked. The maximum lock period is 3 years (156 weeks), which provides the highest ratio: 1 locked token = 1 vote. More details can be found here.

    To start using the CrossCurve application, navigate to the Locker page under the DAO section. Click «Connect wallet», select a suitable wallet from the list, and confirm the connection, ensuring you are on the official page: https://app.crosscurve.fi/locker

    On the Locker page, the current CrossCurve DAO statistics are displayed:

    • Total locked EYWA - the total number of locked EYWA tokens

    • Total supply veEYWA - the total issued veEYWA tokens

    For detailed mechanics on how voting power is calculated when locking EYWA tokens, click Read docs.

    To create a new EYWA token lock, click Lock Tokens

    The page Create token lock contains the following elements:

    • Now you have - the number of created locks and the total veEYWA amount in these locks.

    • Amount to lock - the number of EYWA tokens from your wallet balance for the new lock, increasing the total veEYWA amount.

    • Select your vested EYWA to receive veEYWA - an option to select vesting safes for the new lock, adding EYWA tokens from vesting safes to increase the total veEYWA amount.

    • Select your EYWA NFTs and boost voting power

    The Create Token Lock application allows you to add EYWA tokens from your wallet, vesting safes, and the EYWA NFT container either separately or simultaneously*.

    You can specify the number of EYWA tokens from your wallet balance in the Amount to lock field, select vesting safes in the Select your vested EYWA to receive veEYWA menu, and select EYWA tokens from NFT containers in the Select your EYWA NFTs and boost voting power menu. After selecting the desired amount of EYWA tokens, vesting safes, and EYWA NFT containers, the application calculates the total locked EYWA tokens in the You lock field and the veEYWA voting power based on the selected lock duration in the You’ll get field.

    * Note: Creating a lock requires signing multiple transactions, as indicated on the Create Token Lock. For example: if you selected n EYWA tokens from your wallet balance, three vesting safes, and two EYWA NFTs, the total number of transactions to sign will be 5.

    1. Creating a lock with EYWA Tokens from your wallet

    To create a lock with EYWA tokens from your wallet balance, enter the number of locked tokens in the Amount to lock field and select the lock duration using the slider in the Lock time field. The possible lock duration ranges from 0 to 156 weeks.

    The maximum lock duration is 3 years (156 weeks), ensuring the highest ratio: 1 locked token = 1 vote. The minimum lock duration is a few days (until the end of the current epoch), for example, 2 days provide 2/1092 votes.

    Example: 156 locked tokens for a week provide 1 vote. More details can be found in the , but the simple explanation is:

    • 1 EYWA, locked for 3 years = 1 veEYWA

    • 1 EYWA, locked for 2 years = 0.66(6) veEYWA

    • 1 EYWA, locked for 1.5 years = 0.5 veEYWA

    • 1 EYWA, locked for 1 year = 0.33(3) veEYWA

    The longer you lock your EYWA, the greater your Voting Power and the bigger the boost you can achieve. Voting power is expressed in the number of veEYWA.

    After ensuring the number of locked tokens and the lock duration, the amount of voting power in veEYWA tokens obtained will be displayed in the You’ll get field. Below, the current CrossCurve DAO statistics will be displayed:

    • Total locked EYWA - the total number of locked EYWA tokens in DAO

    • Total supply veEYWA - the total issuance of veEYWA tokens

    • Average EYWA NFT boost - the average boost multiplier obtained for locking an EYWA NFT, depending on the rarity of the NFT being locked (more details )

    To create a lock, click Create Token lock and sign the transaction in your wallet. If you do not have EYWA tokens in your wallet, use the direct Buy token link for purchase.

    After successful on-chain conformation of the transaction, detailed information about the existing locks will be displayed on the page:

    2. Selecting vesting safes for a new lock

    To add EYWA tokens from vesting safes to the newly created lock, select safes by clicking Select your vested EYWA to receive veEYWA in the Create Token Lock menu. The possible ranges from 0 to 156 weeks.

    In the modal window, you will see a list of all available Vested EYWA safes and information about the total number of safes Total in wallet, as well as the sum of all EYWA tokens in them.

    Select a safe (or a group of safes of the same type) to create a lock by clicking the checkbox to the left of the safe. The Locker will display the number of selected safes and EYWA tokens in them in the You selected window. A maximum of 100 safes can be selected per transaction when creating one lock*. To continue, click Lock selected.

    * Adding any type of vesting safes to a lock is only possible when creating a new lock. For an already created lock, it is possible to add vesting safes .

    Returning to the Create Token Lock menu, the number of selected safes and EYWA tokens in them will be displayed in the Selecting field.

    To add Vested EYWA safes to the lock, select the lock duration using the slider in the Lock time field. The possible ranges from 0 to 156 weeks. After selecting the lock duration, the You’ll get field will display the total amount of voting power received in veEYWA tokens. If you need to create a lock only from vesting safes, click Create Token lock and sign the transaction in your wallet.

    3. Boosting voting power by locking EYWA NFT.

    To add EYWA tokens from EYWA NFT containers to the newly created lock, click Select your EYWA NFTs and boost voting power in the Create Token Lock menu. The possible ranges from 0 to 156 weeks.

    In the modal window, you will see a list of all available EYWA NFTs in the connected wallet, sorted by their rarity, along with detailed information:

    • EYWA tokens - the number of EYWA tokens attached to the NFT container (more details )

    • Capacity - the capacity of the NFT container (more details )

    • veEYWA Boosted - NFT boost (more details )

    If there are no EYWA NFTs in the connected wallet, use the quick buy link in the Aurora () or Arbitrum ()

    Select an NFT* (or a group of NFTs of the same rarity) to create a lock by clicking the checkbox to the left of the NFT. The Locker will display the number of selected NFTs and EYWA tokens in containers in the Selected field. A maximum of 100 NFTs can be selected per transaction when creating one lock. To continue, click Lock EYWA NFTs.

    * Attention! In some cases, EYWA NFT may be unavailable for adding to the lock:

    • If you have detached EYWA tokens from the EYWA NFT container, that EYWA NFT will have a 4-hour freeze period. Only after the timer has expired can you add that NFT to the lock.

    • If the EYWA NFT container has EYWA tokens without vesting attached, you must them in EYWA NFT Manager (use quick ) so that this NFT becomes available for adding to the lock. After detaching EYWA tokens, this NFT will be frozen for 4 hours (frontrun protection).

    Returning to the Create Token Lock menu, the line Selecting will display the number of selected NFTs and the number of EYWA tokens in the containers, and in the line Average EYWA NFT boost, the average boost for vote will be calculated depending on the rarity of the selected NFTs.

    To create the EYWA NFTs lock, select the lock duration using the slider in the Lock time field. The possible ranges from 0 to 156 weeks. After selecting the lock duration, the You’ll get field will display the amount of voting power boost obtained (more details ). If you need to create a lock only from EYWA NFTs, click Create Token lock and sign the transaction in your wallet.

    If the Amount to Lock field is set to 0 EYWA and no EYWA in vesting is selected, and you have selected an EYWA NFT with no EYWA tokens attached, a message will appear: Unselect NFTs with 0 EYWA or add EYWA tokens. In this case, to create the lock, you must fulfill one of the following conditions:

    • Unselect the NFT with 0 EYWA tokens in the selection menu Select your EYWA NFTs and boost voting power

    • Add EYWA tokens from your wallet balance in the Amount to lock, or add EYWA tokens with vesting in the selection menu Select your vested EYWA to receive veEYWA.

    Locker

    During the lock period, you can manage accrued rewards and add EYWA tokens and EYWA NFTs to the lock.

    To start working using the CrossCurve application, go to the Locker page in the DAO section. Click «Connect wallet», select the appropriate wallet from the list, and confirm the connection, ensuring you are on the official page:

    On the Locker page, detailed information about existing locks will be displayed:

    • id - D number of EYWA DAO NFT (ID number assigned after creating a new lock through Create lock)

    • Locked EYWA - the number of EYWA tokens in the EYWA DAO NFT safe

    • NFTs - the number of EYWA NFTs inside the lock

    • Unlock time - the next lock expiration date

    * There are two states of lock transferability:

    1. The label Available, means that this EYWA DAO NFT (lock) is free for transfer, sale, and unlocking if the lock period has expired.

    2. The snowflake icon means that the transfer is frozen, and this EYWA DAO NFT cannot be moved, sold, or unlocked. Freezing can occur for two reasons:

      1. EYWA DAO NFT is currently or was previously involved in voting during an epoch. In this case, to remove the frozen status, you need to cancel the vote by clicking

    The Available status means that the EYWA DAO NFT can be transferred, sold, or unlocked (if the lock period has ended).

    The status with the Unfreeze link next to it means that the transfer is frozen - this lock is currently participating in voting for the current or previous epoch. To transfer, you must cancel the vote. To cancel the vote, click Unfreeze and confirm the vote cancellation in the modal window.

    To confirm vote cancellation in the current/previous voting rounds, click Reset votes and sign the transaction in your wallet.

    After confirming the transaction on-chain, the EYWA DAO NFT will become available for transfer.

    The status with the Timer icon means that the EYWA DAO NFT is unavailable for transfer after detaching the EYWA NFT. You must wait 4 hours (front-running protection) before the EYWA DAO NFT can be moved.

    Once the timer expires, the transferability status will change to Available.

    1. To add accrued Staking rewards to the lock, click Compound and sign the transaction in your wallet. The EYWA Staking rewards tokens will be added to the lock for which they were received, for the same duration as the existing lock.

    1. To add EYWA tokens to an existing lock and extend it, click Manage.

    Information about the selected lock will be displayed:

    • Unlocking on - the lock expiration date

    • Already locked - the number of locked EYWA tokens and vesting safes

    • Owned - voting power in veEYWA tokens

    To view detailed information about existing vesting safes, click View

    In the Vested EYWA modal window, detailed information about your vesting safes will be displayed:

    • The round name when the safe was received and the number of identical vesting safes (more details )

    • All tokens - the number of EYWA tokens in the vesting safe

    • Unlocked EYWA - the number of EYWA tokens received from the vesting safe

    • Vesting ends in - the vesting expiration time

    2.1 To add EYWA tokens to the lock, enter the amount in the Amount to compound field.

    To update the lock duration, select Update time lock and set a new lock duration using the slider.

    After entering the amount and selecting the lock duration, the application will display the total number of EYWA tokens ready for locking in the You lock field and the voting power (veEYWA) obtained after the changes in the You’ll get field. To update the lock, click Update Locker and confirm the transaction in your wallet.

    2.2 To add EYWA tokens from EYWA NFT containers to the lock and receive a voting power boost, click Select your EYWA NFTs and boost voting power in the Manage Locker menu.

    In the modal window, you will see a list of all EYWA NFTs available in your connected wallet, sorted by rarity, along with detailed information. If there are no EYWA NFTs in your connected wallet, use the quick purchase link for Aurora () or Arbitrum ()

    Select an NFT (or a group of NFTs of the same rarity) to add to the lock by clicking the checkbox next to the NFT. The Locker will display the number of selected NFTs and EYWA tokens in the containers in the Selected field. A maximum of 100 NFTs can be selected per transaction when adding NFTs to a lock. To continue, click Lock EYWA NFTs

    Returning to the Manage Locker menu, the Selecting field will display the number of selected NFTs and EYWA tokens in the containers. To update the lock duration, select Update time lock and set a new lock duration using the slider.

    After selecting the lock duration, the application will display the total number of EYWA tokens ready for locking in the You lock field, the voting power (veEYWA) obtained after the changes in the You’ll get field, and the average voting power boost in the Average EYWA NFT boost. To update the lock, click Update Locker and confirm the transaction in your wallet.

    The EYWA NFT in locks window displays detailed information about EYWA NFTs locked in the DAO:

    • Transferable - lock transferability status (more details here)

    • Locked EYWA NFTs - the number of EYWA NFTs locked in the DAO

    • Unboosted tokens - the number of EYWA tokens that were not counted in the boost calculation due to container capacity limitations.

    For example, if you have 1,000,000 EYWA tokens and one Legendary EYWA NFT with a container capacity of 250,000 tokens, then Unboosted tokens = 750,000, since tokens exceeding the container size are not included in the boost calculation

    • Average boost - the average boost value obtained for the EYWA NFT lock (more details )

    To transfer an NFT from the lock, click Withdraw

    In the modal window, you will see a list of EYWA NFTs locked in the DAO, sorted by rarity and detailed information:

    • Capacity - NFT container capacity (more details here)

    • veEYWA Boosted - NFT boost (more details here)

    If there are no EYWA NFTs in your connected wallet, use the quick purchase link for Aurora () or Arbitrum ()

    Select an NFT* (or a group of NFTs of the same rarity) to unlock by clicking the checkbox next to an NFT. A maximum of 100 NFTs can be unlocked per transaction.

    * If the EYWA DAO NFT you selected for unlocking participated in voting, it is in Freeze status, and you need to cancel votes by clicking Unfreeze to withdraw

    To confirm vote cancellation in the current/previous voting rounds, click Reset votes and sign the transaction in your wallet.

    After confirming the transaction on-chain, the EYWA NFT will become available for unlocking.

    To continue unlocking EYWA NFTs, click Withdraw EYWA NFTs and confirm the transaction in your wallet.

    1. Once the lock period ends, the Unlock button will become available. To unlock the EYWA DAO NFT and manage safes, click Unlock.

    To confirm unlocking* click OK and sign the transaction in your wallet.

    * Unlocking after the lock period allows managing vesting safes in the .

    3.1. If you want to unlock the EYWA DAO NFT that is/was involved in voting, you need to cancel the votes. To cancel the votes, click Unfreeze and confirm the vote cancellation in the modal window.

    Alternatively, clicking Unlock will bring up a modal window displaying the lock contents and a prompt to unfreeze the EYWA DAO NFT to access its contents.

    To unfreeze the selected EYWA DAO NFT, click Unfreeze to unlock. The You’ll get field will show the number of unlocked EYWA tokens, vesting safes, and NFTs.

    To confirm the vote cancellation in the current/previous voting rounds, click Reset votes and sign the transaction in your wallet.

    After confirming the transaction on-chain, the EYWA DAO NFT will become available for unlocking.

    3.2. If you want to unlock an EYWA DAO NFT that has a timer set after detaching an NFT, you must wait 4 hours (front-running protection) before it can be moved. Click Unlock to initiate the process.

    Once the timer expires, the EYWA DAO NFT will become available for transfer.

    - an option to select EYWA NFTs for the new lock, adding EYWA tokens from the NFT container and increasing the total veEYWA amount. It also grants a voting power boost based on the rarity of the EYWA NFT.
  • Lock time - selection of the locking duration.

  • veEYWA - the voting power amount in veEYWA tokens for the selected lock

  • Staking APY - the APY yield for locked EYWA tokens (more details on staking APY here)

  • Transferable - the status of the selected NFT’s transferability*

  • Staking rewards - the amount of rewards received in EYWA tokens for the past lock period

  • Unfreeze
  • If an EYWA NFT was detached from an EYWA DAO NFT, a timer will be displayed showing the time remaining until the freeze is lifted, after which the EYWA DAO NFT can be moved. This is one of the front-running protection mechanisms.

  • Total in lock - the total number of vesting safes in the lock and the total amount if EYWA tokens in them.

    lock formula section
    here
    Locker
    lock duration
    attached to an EYWA NFT
    lock duration
    lock duration
    here
    here
    here
    tofunft
    opensea
    detach
    link
    lock duration
    here
    https://app.crosscurve.fi/locker
    here
    tofunft
    opensea
    here
    tofunft
    opensea
    Locker

    Liquidity transfer from Fantom to Sonic

    CrossCurve liquidity pools are starting their migration from the Fantom network to the Sonic network (learn more here). In this step-by-step guide, we will explore how to safely and profitably transfer your liquidity.

    Please carefully read the entire list of required actions for transferring liquidity before starting the process.

    When migrating to Sonic, the architecture of the pools changes—instead of pools with 8 directions, paired pools are now used. Therefore, before transferring liquidity, please decide which paired pools you will transfer your liquidity to and how you will do it:

    • You can simply withdraw liquidity from a pool with 8 tokens and distribute it across 8 corresponding paired pools.

    • Alternatively, you can divert all liquidity from such a pool to a single paired pool or split it across several.

    It’s also important to understand that, unlike the previous architecture, paired pools now include not only the directional token (synthetic) but also a "universal" token (xfrxUSD for USD, xfrxETH for ETH, and scBTC for BTC assets). Thus, transferring liquidity will require both the destination token and the "local universal" token.

    Learn more about the changes in pool architecture.

    Pool Hub-Chain Structure Update

    This update will also affect the structure of the pool hub-chain. The previous pool system used Curve stable pools with 8 assets, connected via liquidity provider (LP) tokens from one or more pools:

    There are numerous ways to transfer liquidity, and it’s impossible to describe every scenario, so we’ll outline the key general steps:

    1. Choose the pool to which liquidity will be transferred, for example, xsArbitrum.

    2. Determine how many of each token is needed. In the Arbitrum example, you’ll need 25% frxUSD tokens and 25% scUSD tokens to obtain 50% xfrxUSD and 50% sUSDC_arb (percentages are based on the total liquidity planned for transfer to the xsArbitrum pool).

    3. Obtain the synthetic token corresponding to this direction—in this case, sUSDC_arb.

    Brief list of all actions for Liquidity Transfer

    If you provided liquidity to CrossCurve pools on the Farms tab in the Fantom network, you’ll need to follow these steps to transfer your funds from the Fantom network to the Sonic network:

    1. Unstake your position on the Farms page.

    2. Decide which pools your liquidity will be transferred to:

    • You can distribute liquidity across 8 directions.

    • You can choose one or several directions.

    1. Decide which method you’ll use to transfer liquidity:

      • In Easy Mode, directly swap LP tokens from the pool for the required tokens.

    Note: This may result in losses due to conversion and slippage. For low liquidity pools and large amounts, losses can be significant.

    Examples of swap directions in Easy Mode:

    • xSTABLE → sUSDT_eth

    • xSTABLE3 → sUSDC_arb

    • xSTABLE2 → sUSDC_ba

    This method is more labor-intensive but allows for the most cost-effective swaps and is better suited for large liquidity amounts.

    Examples of swap directions in Balanced Mode:

    • s3CRV_e → sUSDT_eth

    • s2CRV_ar → sUSDC_arb

    • s4pool_b → sUSDC_ba

    1. Swap your FTM for S (or obtain S) to pay for gas (gwei).

    2. Obtain the universal token for paired pools:

    • For USD pools, obtain the LP token xfrxUSD.

    • For ETH pools, obtain the LP token xfrxETH.

    • For BTC pools, obtain the scBTC token.

    1. Obtain a synthetic token corresponding to the desired direction (e.g., sUSDT_eth, sUSDC_arb, sUSDC_ba, etc.)

    2. Deposit liquidity into the pools:

    • To obtain xfrxUSD, deposit frxUSD and scUSD into the pool.

    • To obtain xfrxETH, deposit frxETH and scETH into the pool.

    1. Lock liquidity in the new pools on the Sonic network to earn profits.

    Important Note: Rewards distribution in CrossCurve pools on the Fantom network will end at the conclusion of the current epoch. Voting for these pools and reward distribution to DAO participants in these pools will be paused. Starting from the next epoch, voting for reward allocation in the new pools on the Sonic network will begin.

    Detailed description of Liquidity Transfer actions

    Unstake LP tokens from CrossCurve Pools on Fantom

    Go to the Farms staking page to view all available pools and the size of your positions in them.

    1. First, withdraw accumulated rewards by clicking Claim in all pools and signing the transaction in your wallet.

    Withdraw Liquidity from LP Tokens in the Pool

    After receiving LP tokens, there are two methods to withdraw your liquidity:

    • Easy Mode via CrossCurve into a single asset of your choice (may incur penalties due to slippage).

    • Balanced Mode on Curve

    Obtaining Universal tokens for paired pools

    Each paired pool in the Sonic hub-chain consists of two tokens:

    • A universal token—an asset from Sonic, common for all pools of the same type (xfrxUSD for USD assets, xfrxETH for ETH, and scBTC for BTC).

    • A synthetic derivative, backed by the original asset locked in the Consensus Bridge. This can be either a single asset or LP tokens from Curve.

    Universal tokens come in three types:

    • For USD pools: LP token xfrxUSD.

    • For ETH pools: LP token xfrxETH.

    • For BTC pools: scBTC token.

    Obtaining LP xfrxUSD

    To obtain xfrxUSD, follow these three steps:

    1. Obtain frxUSD on Sonic.

    2. Obtain scUSD on Sonic.

    3. Deposit frxUSD and scUSD into the CrossCurve frxUSD pool to receive xfrxUSD.

    You can obtain frxUSD and scUSD in various ways; below are a few methods.

    Obtaining frxUSD on Sonic using CrossCurve and Frax bridge

    frxUSD tokens on the Fraxtal network can be swapped from any available asset in the app.

    Then, bridge them to the Sonic network on .

    Obtaining scUSD on Sonic using CrossCurve and Rings app

    In the app, you can transfer any available asset to the Ethereum network, receiving USDT, USDC, or DAI.

    Then, scUSD tokens can be swapped in the app by depositing the available assets as collateral.

    Obtaining frxUSD and scUSD using other bridges for Sonic

    Choose your preferred app from the list of bridges in the section under Apps in the Bridge category.

    Obtaining frxUSD and scUSD Using the Jumper.exchange Aggregator

    Swaps are also available on the aggregator for any available assets.

    Obtaining xfrxUSD via the Curve App interface

    To obtain the LP token xfrxUSD, you need to provide liquidity in the pool:.

    Go to the pool page and connect your wallet.

    Enter the desired deposit amount on the Deposit tab. To avoid losses due to slippage, it’s recommended to deposit funds in a balanced manner by clicking Add all coins in a balanced proportion (learn more ).

    In the first transaction, confirm the spending of funds by clicking Approve Spending and signing the transaction in your wallet.

    In the second transaction, deposit the funds by clicking Deposit and signing the transaction in your wallet.

    After the transaction is successfully confirmed on-chain, your wallet will display the amount of received xfrxUSD LP tokens.

    If your wallet doesn’t support automatic token addition, add it manually as a custom token with the contract address on the Sonic network.

    Obtaining LP xfrxETH

    To obtain xfrxETH, follow these three steps:

    1. Obtain frxETH on Sonic.

    2. Obtain scETH on Sonic.

    3. Deposit frxETH and scETH into the CrossCurve frxETH pool to receive xfrxETH.

    You can obtain frxETH and scETH in various ways; below are a few methods.

    Obtaining frxETH on Sonic using CrossCurve and Frax bridge

    wfrxETH tokens on the Fraxtal network can be swapped from any available asset in the app.

    Then, bridge them to the Sonic network on .

    Obtaining scETH on Sonic using CrossCurve and Rings app

    In the app, you can transfer any available asset to the Ethereum network, receiving WETH or ETH.

    Then, scETH tokens can be swapped in the app by depositing the available assets as collateral.

    Obtaining scETH or frxETH on Sonic using other bridges for Sonic

    Choose your preferred app from the list of bridges in the section under Apps in the Bridge category.

    Obtaining scETH or frxETH Using the Jumper.exchange aggregator

    Swaps are also available on the aggregator for any available assets.

    Obtaining xfrxETH via the Curve App Interface

    To obtain the LP token xfrxETH, you need to provide liquidity in the pool:.

    Go to the pool page and connect your wallet.

    Enter the desired deposit amount on the Deposit tab. To avoid losses due to slippage, it’s recommended to deposit funds in a balanced manner by clicking Add all coins in a balanced proportion (learn more ).

    In the first transaction, confirm the spending of funds by clicking Approve Spending and signing the transaction in your wallet.

    In the second transaction, deposit the funds by clicking Deposit and signing the transaction in your wallet.

    After the transaction is successfully confirmed on-chain, your wallet will display the amount of received xfrxETH LP tokens.

    If your wallet doesn’t support automatic token addition, add it manually as a custom token with the contract address on the Sonic network.

    Obtaining scBTC

    You can obtain scBTC using the official Rings issuer app. Alternatively, you can use third-party services listed below.

    Obtaining scBTC on Sonic using CrossCurve and Rings app

    In the app, you can transfer any available asset to the Ethereum network, receiving WBTC.

    Then, scBTC tokens can be swapped in the app by depositing WBTC on the Ethereum network as collateral.

    Obtaining scBTC on Sonic using other bridges for Sonic

    Choose your preferred app from the list of bridges in the section under Apps in the Bridge category.

    Obtaining scBTC using the Jumper.exchange aggregator

    Swaps are also available on the aggregator for any available assets.

    Obtaining a Synthetic Derivative

    Each paired pool on the Sonic hub-chain consists of two tokens:

    • A universal token – an asset from Sonic, uniform across all pools of the same type (e.g., xfrxUSD for USD assets, xfrxETH for ETH, and scBTC for BTC).

    • A synthetic derivative, backed by the original asset locked in the Consensus Bridge. These can be either single assets or LP tokens from Curve.

    Synthetic tokens are categorized into three types:

    • s_Stable_chain, where Stable represents a USD asset variant, and chain is the network where the asset is used.

    Each type of synthetic token corresponds to a pool where it can be paired in an LP token:

    • xs_chain, where xs is a stable pool, and chain is the network where the asset is used.

    • xe_chain, where xe is a volatile pool, and chain is the network where the asset is used.

    Obtaining sUSDC_arb

    sUSDC_arb tokens on the Sonic network can be swapped from any available asset in the xsArbitrum pool via the app.

    1. Navigate to the Liquidity tab in the Yield section. Select the Balanced mode and click Next.

    Enter the desired amount to swap, approve the spending by clicking Approve, and sign the transaction in your wallet.

    Click Swap to execute the exchange and confirm the transaction in your wallet.

    1. If you know the swap direction, you can also perform the exchange in the tab using any available asset.

    Note: Some directions may experience high slippage!

    Providing Liquidity to pools on Sonic

    To provide liquidity to Sonic pools:

    • Select the pool where you want to transfer liquidity, e.g., xsArbitrum.

    • Determine the required token amounts.

    For the Arbitrum example, you need 25% frxUSD and 25% scUSD to obtain 50% xfrxUSD and 50% sUSDC_arb (percentages are based on the total liquidity you plan to transfer to the xsArbitrum pool).

    • Obtain the synthetic token for this direction, in this case, .

    • For USD pools, acquire tokens. For example, deposit an equal amount of and into the pool.

    • Deposit the universal token and the directional (synthetic) token into the paired pool.

    In our example, deposit xfrxUSD and sUSDC_arb into the CrossCurve Stable ARB pool.

    Obtaining LP xsArbitrum via Curve

    Navigate to the pool page: and connect your wallet.

    Enter the desired deposit amount in the Deposit tab. To avoid losses due to slippage, it’s recommended to deposit using the balanced method by clicking Add all coins in a balanced proportion (more details ).

    In the first transaction, approve the spending by clicking Approve Spending and sign the transaction in your wallet.

    In the second transaction, deposit the funds by clicking Deposit and sign the transaction in your wallet.

    After the transaction is confirmed on-chain, the amount of received xsArbitrum LP tokens will appear in your wallet.

    If your wallet doesn’t automatically add the token, manually add it as a custom token using the contract address on the Sonic network.

    Obtaining LP xsArbitrum via CrossCurve

    LP xsArbitrum tokens on the Sonic network can be swapped from any available asset in the xsArbitrum pool via the app.

    Go to the Liquidity tab in the Yield section. Select the Easy mode and click Next.

    Choose the available asset for the swap.

    Enter the desired amount to swap, approve the spending by clicking Approve, and sign the transaction in your wallet.

    Click Swap to execute the exchange and confirm the transaction in your wallet.

    Depositing LP xsArbitrum into the CrossCurve Stable ARB Pool

    To provide liquidity to CrossCurve pools navigate to the Farms page in the Yield section: and connect your wallet.

    In the xsArbitrum pool tab, click Stake LP and get rewards.

    Enter the deposit amount, approve the spending by clicking Approve, and sign the transaction in your wallet.

    After successful confirmation, deposit the funds by clicking Stake and sign the transaction in your wallet.

    The deposited amount will appear in the Staked field.

    You can view the current vAPR and accrued rewards in the selected pool by clicking on the APY icon.

    V1
    Pools (
    xSTABLE
    ,
    xSTABLE2
    ,
    xSTABLE3
    ) consist of 8 synthetic derivatives backed by the original asset locked in LP tokens on
    Curve
    .

    CrossCurve MetaLayer introduces a fundamentally new approach—liquidity isolation, where each pool contains liquidity for only one direction:

    V2 Each paired pool in the hub-chain consists of two tokens:

    • A universal token—an asset from Sonic, common for all pools of the same type (xfrxUSD for USD assets, xfrxETH for ETH, and scBTC for BTC).

    • A synthetic derivative, backed by the original asset locked in the Consensus Bridge. This can be either a single asset or LP tokens from Curve.

    As a result, all xSTABLE pools will transform into 20+ paired pools. When transferring liquidity, it won’t be possible to do a one-to-one transfer, as paired pools require an additional "universal" pool token.

    For USD and ETH pools, you’ll need to obtain xfrxUSD or xfrxETH tokens, respectively. To do this, in Sonic, you need to acquire frxUSD, scUSD, frxETH, and scETH accordingly. For example, you’ll need equal amounts of frxUSD and scUSD to deposit into the CrossCurve frxUSD pool.

  • Deposit the universal token and the destination token (synthetic) into the paired pool. In our example, you’ll need to deposit xfrxUSD and sUSDC_arb into the CrossCurve Stable ARB pool.

  • In Balanced Mode, withdraw 8 synthetic tokens from the LP token and swap them directly.

    After successfully claiming rewards from the pool, click Unstake to withdraw LP tokens from staking.

    1. In the modal window, to select the maximum number of LP tokens to withdraw, click MAX next to the token balance in your wallet, then click Unstake to withdraw your liquidity from the pool and receive LP tokens on the Fantom network.

    1. Sign the transaction in your wallet.

    into the assets composing the LP in the pool (
    the most cost-effective method
    ).
    1. Easy Mode via CrossCurve

    To quickly withdraw liquidity using Easy Mode, go to the Liquidity page under the Yield tab.

    In the pool list, under Choose pool, select the pool where you provided liquidity and have LP tokens.

    Select the withdrawal mode Withdraw, operation type Easy Mode, and click Next to proceed.

    Choose the asset you want to swap your LP token for by opening the selection list.

    Enter the amount of LP tokens to swap or click MAX to select the entire balance from your wallet. Click Approve and confirm the LP token spending operation in your wallet.

    After confirming the spending operation, click Swap to perform the exchange and sign the transaction in your wallet.

    Wait for the transaction to be processed on-chain.

    1. Balanced Mode via Curve

    To withdraw liquidity in Balanced Mode, go to the page of the pool you’re interested in on the Curve app using the quick link.

    If you haven’t performed an unstake in the CrossCurve app, go to the Withdrawal/Claim menu under the Unstake tab. Enter the number of LP tokens to unstake, click Unstake, and sign the transaction in your wallet.

    After the transaction is successfully confirmed on-chain, you’ll see a notification: Unstake Complete.

    Claim the rewards on the Claim Rewards tab by clicking Claim and signing the transaction in your wallet.

    To withdraw liquidity, go to the Withdraw tab, enter the number of LP tokens, select Balanced mode, and click Withdraw. Sign the transaction in your wallet.

    After the transaction is successfully confirmed on-chain, you’ll see a notification: Withdraw Complete.

    s_WETH_network, where WETH represents ETH backing, and chain is the network where the asset is used.
  • s_WBTC_network, where WBTC represents BTC backing, and chain is the network where the asset is used.

  • xb_chain, where xb is a volatile pool, and chain is the network where the asset is used.

  • CrossCurve
    Frax.com
    CrossCurve
    Rings
    mySonic
    Jumper.exchange
    CrossCurve frxUSD
    https://curve.finance/dex/sonic/pools/factory-stable-ng-25/deposit/
    CrossCurve frxUSD
    here
    0xf1232a1ab5661abdd6e02c6d8ac9940a23bb0b84
    CrossCurve
    Frax.com
    CrossCurve
    Rings
    mySonic
    Jumper.exchange
    CrossCurve frxETH
    https://curve.finance/dex/sonic/pools/factory-stable-ng-26/deposit/
    CrossCurve frxETH
    here
    0x346704605c72d9f5f9F02D651e5A3DccE6964F3d
    CrossCurve
    Rings
    mySonic
    Jumper.exchange
    CrossCurve
    Trade
    sUSDC_arb
    xfrxUSD
    frxUSD
    scUSD
    CrossCurve frxUSD
    CrossCurve Stable ARB
    https://curve.finance/dex/sonic/pools/factory-stable-ng-73/deposit/
    here
    0x440bcab62d629ba60ca56b80e565636e0c404e60
    CrossCurve
    https://app.crosscurve.fi/farm

    DelegationManagerV1

    Overview

    DelegationManagerV1 This is an upgradeable contract that allows you to delegate your locks to another account. This contract is integrated with EmissionManager, EscrowManager, EscrowVoteManager, LockHolderFactory, RebaseRewardsDistributor, DelegationConditionValidator. It allows the lock owner to delegate or automate actions such as voting and collecting rebase rewards and incentive rewards.

    Key Roles and Features:

    1. Access Control: Restricts setAssuranceLockParameters and setMinLockVeEywa calls to the owner of contract(owner()).

    2. Upgradeable via UUPS: Uses UUPSUpgradeable and OwnableUpgradeable patterns, restricting contract upgrades to the owner.


    Inherited Contracts and Interfaces

    • UUPSUpgradeable (OpenZeppelin): Provides upgrade functionality under the UUPS proxy pattern, restricted to the contract owner.

    • OwnableUpgradeable (OpenZeppelin): Manages ownership, allowing only the owner to modify critical parameters and authorize upgrades.

    • IDelegationManagerV1: Defines core methods (e.g., setDelegationParameters, delegate, vote) and events for this contract.

    Additional External References:

    • SafeERC20, IERC20 (OpenZeppelin): Handles secure ERC20 operations for distributing and approving token transfers.

    • IRebaseRewardsDistributorV2: Distributes rebase rewards and triggers relevant accounting updates.

    • IDelegationConditionValidatorV1: Logic to test additional conditions for delegation

    • ILockHolderFactoryV1: Deployment of new LockHolder contracts


    Constants

    • EPOCH_DURATION: Duration of each emission/gauge epoch (1 week).

    • PRECISION: The divisior for percentage math.


    State Variables

    • s_eywa (IERC20) ERC20 token interface for the EYWA token.

    • s_collection (ICollection) ICollection Interface for the NFT collection contract.

    • s_emissionManager (IEmissionManagerV1) IEmissionManagerV1 interface for the EmissionManagerV1 contract.


    Constructor

    • Description: Disables contract initializers to prevent re-initialization in a UUPS proxy context.


    External Functions (Defined by IDelegationManagerV1)

    initialize(...)

    Description: Configures ownership, references, and initial state:

    • Sets s_minLockEywa to 500 000 * 1e18 initially.

    • Sets s_minLockVeEywa to 1 000 * 1e18 initially.

    • Sets s_minLockDuration to 52 weeks initially.

    Parameters:

    • owner_: The address of the contract owner.

    • eywa_: ERC20 token interface for the EYWA token.

    • collection_: ICollection Interface for the NFT collection contract.


    setAssuranceLockParameters(uint256 minLockEywa_, uint256 minLockDuration_)

    Description: Setting parameters for the delegate assurance lock

    Parameters:

    Checks:

    • Only the owner of the contract can call this function.


    setMinLockVeEywa(uint256 minLockVeEywa_)

    Description: Setting the minimum veEYWA value for delegated locks

    Parameters:

    • minLockVeEywa_: The minimum number of veEYWA that must be in the delegated lock.

    Checks:

    • Only the owner of the contract can call this function.


    setDelegationParameters(DelegationParameters memory delegationParameters_)

    Description: Setting delegation parameters for the delegate If this is the first time a delegate is setting parameters, its address is added to the delegate array (s_delegaties) delegationParameters_.eywaDeposit and the delegate's current deposit. Delegation parameters can only be changed once the rewards have been received and distributed and rent has been paid for all delegated locks. When one or more parameters are changed: delegationParameters_.maxDelegatedVeEYWA, delegationParameters_.delegationEnd, delegationParameters_.eywaDeposit - the rent per veEYWA unit per epoch is recalculated. Performs a transfer of the required number of EYWA tokens from the delegate's account to his deposit in the contract. This deposit will be used to pay for lock rentals to delegates. The required number is calculated as the difference between

    Parameters:

    • delegationParameters_: Parameters of the delegation.

    Checks:

    • The delegate must pass the correct parameters. Otherwise, WrongDelegationParameters() is thrown.

    • The delegate assuranceLock lock must comply with the requirements set forth. Otherwise, BadAssuranceLock() is thrown.

    • All rewards for all delegated locks must be received. Otherwise, RewardsUnclaimed() is thrown.


    setDelegationVoteParameters(address[] calldata pools_, uint256[] calldata weights_)

    Description: Setting the parameters auto-voting for a specific delegate.

    Parameters:

    • pools_: The array of voting pools.

    • weights_: The array with voice weights for each pool.

    Checks:

    • pools_ and weights_ arrays must not be null and must have the same size. Otherwise, InvalidArrayLengths() is thrown.


    setAutoVotePermission(bool permission_)

    Description: Set the permission for automatic voting using the autoVote function. With this permission, this autoVote function can be called by any account. To perform automatic voting, you must set the parameters with the setDelegationVoteParameters function

    Parameters:

    • permission_: The permission parameter.


    boost(uint256 tokenId_, uint256[] calldata collectionTokenIds_)

    Description: The function proxies the call of the boost function on the EscrowManager contract.

    Parameters:

    • tokenId_: The ID of the token representing the lock.

    • collectionTokenIds_: An array of token IDs from the collection that will be used to boost the lock.

    Checks:

    • The lock must be self-delegation and the caller must be a delegator. Otherwise, UnauthorizedCaller() is thrown.

    • Delegation time should not be finalized. Otherwise, DelegateTimeExpired() is thrown.


    deboost(uint256 tokenId_, uint256[] calldata collectionTokenIds_)

    Description: The function proxies the call of the deboost function on the EscrowManager contract. And then performs a transfer of the NFTs withdrawn from the lock to the delegator balance.

    Parameters:

    • tokenId_: The ID of the token representing the lock.

    • collectionTokenIds_: An array of token IDs from the collection that will be used to boost the lock.

    Checks:

    • The lock must be self-delegation and the caller must be a delegator. Otherwise, UnauthorizedCaller() is thrown.


    extend(uint256[] calldata tokenIds_, uint256[] calldata lockDurations_)

    Description: The function proxies the call of the extend function on the EscrowManager contract.

    Parameters:

    • tokenIds_: An array of IDs of the token representing the lock.

    • collectionTokenIds_: An array of token IDs from the collection that will be used to boost the lock.

    Checks:

    • The tokenIds_ and lockDurations_ arrays must have the equal length. Otherwise, InvalidArrayLengths() is thrown.

    • For each lock from tokenIds delegatee_ must be a delegator. Otherwise, WrongDelegatee() is thrown.


    withdrawDeposit(uint256 amount_)

    Description: Function for deposit withdrawal. Performs transfer of amount_ of EYWA tokens from contract balance to msg.sender balance. Decreases by amount_ the value in s_depositByDelegatee on the msg.sender key. A delegate can only withdraw a deposit if the current delegation has been completed and all payments for all delegated locks have been made.

    Parameters:

    • amount_: The amount of EYWA tokens.

    Checks:

    • Checks that the delegate's deposit is not less than amount_. Otherwise, NotEnoughAmount() is thrown.

    • Fee must be paid for each delegated lock. Otherwise, DelegationUnpaid() is thrown.


    claim()

    Description: The function transfers EYWA, received as a commission for delegated locks, to the balance of the delegator


    delegate(address delegatee_, uint256[] calldata tokenIds_)

    Description: This function performs a number of necessary checks, after which the internal function _delegate() is called, in which delegation takes place.

    Parameters:

    • delegatee_: The delegate's address.

    • tokenIds_: An array of IDs of the token representing the lock.

    Checks:

    • If it is not a self-delegation, it is checked that delegatee_ has set the delegation parameters. Otherwise, DelegateeNotExist() is thrown.

    • If it is not self-delegation, it is verified that the condition of the assurance lock is as specified. Otherwise, BadAssuranceLock() is thrown.

    • If it is not a self-delegation, iit is checked that the maximum number of veEYWA specified in the delegation parameters will not be exceeded. Otherwise, MaxDelegatedVeEywaExceeded()

    Events:

    • Emits Delegate(delegator, delegatee, tokenIds).


    paymentAndExtendDelegations(uint256[] calldata tokenIds_)

    Description: The function transfers lock commissions from the delegatee's deposit to the delegator's deposit, for all epochs since the last time the commission was received, and renews locks

    Parameters:

    • tokenIds_: An array of IDs of the token representing the lock.


    claimIncentives(uint256[] calldata tokenIds_)

    Description: The function proxies the call of the claimIncentives function on the LockHoldeV1 contract. After collecting and distributing the bounty, notes that the bounty for the specified locks is received in this epoch.

    Parameters:

    • tokenIds_: An array of IDs of the token representing the lock.


    revokeDelegations(uint256[] calldata tokenIds_)

    Description: Function to revoke the delegation. Sets the start of the next epoch to the time the delegation ends. After the start of the next epoch, these delegated locks cannot be voted on.

    Parameters:

    • tokenIds_: An array of IDs of the token representing the lock.

    Checks:

    • For each lock from tokenIds_, it is checked that the function is called by a delegator or delegate. Otherwise, UnauthorizedCaller() is thrown.

    • For each lock from tokenIds_, it is checked that its delegation time has not yet expired. Otherwise, DelegateTimeExpired() is thrown.


    recallDelegations(uint256[] calldata tokenIds_)

    Description: Delegation Completion Function. In the normal situation, this function is called in the next epoch, after the revokeDelegations function has been called. For self-delegated locks, this function can be called at any time, without first calling the revokeDelegations function. If the delegation time specified in the delegation parameters has expired, you can call this function, without first calling the revokeDelegations function. After partitioning a lock, reduces by its veEYWA value the amount of veEYWA delegated to the delegate.

    Parameters:

    • tokenIds_: An array of IDs of the token representing the lock.

    Checks:

    • You can't recall assurance lock. Otherwise, DelegationWithdrawalForbidden() is thrown.

    • For each lock from tokenIds_, it is checked that the function is called by a delegator or delegate. Otherwise, UnauthorizedCaller() is thrown.

    • All rewards for all delegated locks must be received. Otherwise, RewardsUnclaimed() is thrown.

    Events:

    • Emits RecallDelegations(tokenIds_).


    function vote(uint256[] calldata tokenIds_, address[][] calldata pools_, uint256[][] calldata weights_)

    Description: The function proxies the call of the extend function on the EscrowVoteManager contract.

    For each lock from tokenIds_ the necessary checks are performed in the internal function _checkDelegation, which will be described in detail below

    Parameters:

    • tokenIds_: An array of IDs of the token representing the lock.

    • pools_: An array of voting pools.

    • weights_: An array with voice weights for each pool.


    autoVote(address delegatee_, uint256[] calldata tokenIds_)

    Description: The function proxies the call of the extend function on the EscrowVoteManager contract.

    The delegate must set permission for auto-voting in the setAutoVotePermission function and set the voting parameters in the setDelegationVoteParameters function. Then any account can perform voting by delegated locks of this delegate using the set parameters.

    For each lock from tokenIds_ the necessary checks are performed in the internal function _checkDelegation, which will be described in detail below

    Parameters:

    • delegatee_: An array of IDs of the token representing the lock.

    • tokenIds_: An array of IDs of the token representing the lock.

    Checks:

    • The delegatee_ must set the authorization for auto-voting. Otherwise, NotSetAutoVote() is thrown.

    • The delegatee_ must set the parameters for auto-voting. Otherwise, NotSetAutoVoteParameters() is thrown.

    • For each lock from tokenIds


    reset(uint256[] calldata tokenIds_)

    Description: The function proxies the call of the reset function on the EscrowVoteManager contract.

    For each lock from tokenIds_ the necessary checks are performed in the internal function _checkDelegation, which will be described in detail below.

    Parameters:

    • tokenIds_: An array of IDs of the token representing the lock.


    poke(uint256[] calldata tokenIds_)

    Description: The function proxies the call of the poke function on the EscrowVoteManager contract.

    For each lock from tokenIds_ the necessary checks are performed in the internal function _checkDelegation, which will be described in detail below.

    Parameters:

    • tokenIds_: An array of IDs of the token representing the lock.


    isAvailableDelegate(address delegator_, address delegatee_, uint256[] calldata tokenIds_)

    Description: The function checks all current delegation parameters accepts determines whether delegation from delegator_ to delegatee_ of tokenIds_ locks is possible. Returns true/false - delegation is or is not possible for the given values

    Parameters:

    • delegator_: The delegator's address.

    • delegatee_: The delegate's address.

    • tokenIds_: An array of IDs of the token representing the lock.


    getDelegationsParameters()

    Description: The function returns an array of parameters of all delegates


    getDelegationsVoteParametersByDelegate(address delegatee_)

    Description: The function returns the auto-voting parameters for a specific delegatee_

    Parameters:

    • delegatee_: The delegate's address.


    getDelegationsInfoByTokenIds(uint256[] calldata tokenIds_)

    Description: The function returns an array with delegation information for an array of delegations

    Parameters:

    • tokenIds_: An array of IDs of the token representing the lock.


    getDelegationInfoAndParametersByTokenId(uint256 tokenId_)

    Description: The function returns delegation information delegationInfo_ and delegation parameters delegationParameters_ for a specific delegated lock by its tokenId_

    Parameters:

    • tokenId_: The ID of the token representing the lock.


    getLockIdsByDelegator(address delegator_)

    Description: The function returns an array of id's of all locks delegated by the delegator_

    Parameters:

    • delegator_: The delegator's address.


    getLockIdsByDelegatee(address delegatee_)

    Description: The function returns an array of id's of all locks delegated to the delegatee_

    Parameters:

    • delegatee_: The delegate's address.


    getAssuranceLockStatus(uint256 tokenId_, address delegatee_)

    Description: The function checks and returns true/false the status of tokenId_ as a Assurance lock for the delegatee_

    Parameters:

    • tokenId_: The ID of the token representing the lock.

    • delegatee_: The delegate's address.


    Internal and Private Functions

    _delegate(IEscrowManagerExtended escrowManager_, DelegationParameters memory delegationParameters_, uint256[] calldata tokenIds_, address delegatee_)

    Description: The delegation function performs the necessary checks and then performs a lock transfer to the LockHolder contract, and the entire veEYWA of the lock is transferred to the delegate_ account. If this sender delegates locks to this delegate_ for the first time, a new LockHolder contract is deployed for them. The necessary data structures are also created to store information about the delegated lock. If a sender address or null address is specified as delegate_, self-delegation occurs.

    Parameters:

    • escrowManager_: The IEscrowManagerExtended interface for the EscrowManager contract.

    • delegationParameters_: Parameters of the delegation.

    • tokenIds_: The array of IDs of the token representing the lock.

    Checks

    • If it is not a self-delegation, checked that the veEYWA value of all lots specified in tokenIds_ is not less than the s_minLockVeEywa value set in the contract minVeEYWA set in delegations parameters. Otherwise, WrongVeEywaAmount() is thrown.

    • If it is not self-delegation, checks that the time to unlock the lock is not lower than the minimum time set by the delegatee_. Otherwise, LittleTimeToUnlock() is thrown.


    _recallDelegation(address delegator_, address delegatee_, uint256 tokenId_)

    Description: Delegation recall function

    First, a check is made to see if the vote was made by this tokenId_, and if so, the reset function is called on the LockHolder contract to reset the vote. Otherwise it will be impossible to perform a lock transfer.

    The data structures are then overwritten and the data of the revocable delegation is deleted.

    At the end, a transfer of the voiting power and lock token to the delegator address is made

    Checks:

    • For tokenId_, it is checked that there exists a LockHolder contract corresponding to the delegate-delegate pair. Otherwise, LockHolderNotExist() is thrown.

    Parameters:

    • delegator_: The delegator's address.

    • delegatee_: The delegate's address.

    • tokenId_ The ID of the token representing the lock.


    _getVotes(IEscrowManagerExtended escrowManager_, uint256[] calldata tokenIds_)

    Description: Returns the sum of veEYWA from an array of locks tokenIds_

    Parameters:

    • tokenIds_: The array of IDs of the token representing the lock.


    _getLastEpochOfDelegation(uint256 timeExpiry_, uint256 delegationEnd_)

    Description: The function returns the completion time of the delegation

    Parameters:

    • timeExpiry_: The expiry timestamp to verify.

    • delegationEnd_: The epoch in which the delegation will be completed.


    _getPaidEpoch(uint256 timeExpiry_, uint256 delegationEnd_, uint256 currentEpochStart_)

    Description: The function returns the start time of the last paid epoch

    Parameters:

    • timeExpiry_: The expiry timestamp to verify.

    • delegationEnd_: The epoch in which the delegation will be completed.

    • currentEpochStart_: The start time of the current epoch.


    _checkDelegationPaid(bool isSelfDelegation_, uint256 lastPaidEpoch_, uint256 paidEpoch_)

    Description: The function checks whether the delegation has been paid in the current epoch. Returned with DelegationUnpaid if the delegation is not paid in the current epoch.

    Parameters:

    • isSelfDelegation_: Indicates whether the delegation is self-delegated.

    • lastPaidEpoch_: An epoch when the last fee payment was made.

    • paidEpoch_: An epoch that must be paid for.

    Checks

    • Unless it is self-delegation, the last epoch paid should not be less than the epoch to be paid. Otherwise, DelegationUnpaid() is thrown.


    _checkRewardsClaimed(uint256 tokenId_, uint256 currentEpochStart_, address lockHolder_)

    Description: The function checks to see if available awards have been received. Returned with RewardsUnclaimed if no awards have been received.

    Parameters:

    • tokenId_: Indicates whether the delegation is self-delegated.

    • currentEpochStart_: The current epoch start.

    • lockHolder_: The lock holder contract address.

    Checks

    • Unless it is self-delegation, the last epoch paid should not be less than the epoch to be paid. Otherwise, DelegationUnpaid() is thrown.


    _checkCaller(address caller_)

    Description: Internal function to check the caller.

    Parameters:

    • caller_: The expected caller's address.

    Checks:

    • msg.sender must be equal to caller_. Otherwise, UnauthorizedCaller() is thrown.


    _checkDelegatorOrDelegatee(address delegator_, address delegatee_)

    Description: Internal function to verify that the function caller is a delegate or delegator.

    Parameters:

    • delegator_: The delegator's address.

    • delegatee_: The delegate's address.

    Checks:

    • msg.sender must be equal to delegator_ or delegatee_. Otherwise, UnauthorizedCaller() is thrown.


    _checkTimeExpiry(uint256 timeExpiry_)

    Description: Internal function to check that the delegation time has not expired. If the delegation has been revoked and timeExpiry is not equal to 0, the end time of the delegation must be less than the current time

    Parameters:

    • timeExpiry_: The end time of delegation.

    Checks:

    • block.timestamp must be not equal 0 and greater than timeExpiry_. Otherwise, DelegateTimeExpired() is thrown


    _checkLockHolder(address delegator_, address delegatee_)

    Description: Internal Function to check the LockHolder contract address for a pair of delegator and delegate. Returns the LockHolder contract's address.

    Parameters:

    • delegator_: The delegator's address.

    • delegatee_: The delegate's address.

    Checks:

    • a LockHolder contract must be deployed for the delegator_ and delegatee_ pair. Otherwise, LockHolderNotExist() is thrown


    _checkAssuranceLock(uint256 assuranceLock_, address delegatee_)

    Description: Internal function to check the assurance lock. Verification that the lock is a self-made lock, or its assurance lock meets the specified requirements

    Parameters:

    • assuranceLock_: The token ID used as the assurance lock.

    • delegatee_: The delegatee assurance lock.

    Checks:

    • If the conditions are not met for assuarnce lock. Otherwise, BadAssuranceLock() is thrown


    _checkDelegation(DelegationInfo memory delegationInfo_, address caller_, uint256 currentEpochStart_)

    Description: Internal function for check the delegation status. Check caller, time expiry, delegation fee payment. A number of internal functions are called for the checks, which will be described below

    Parameters:

    • delegationInfo_: The delegation information associated with the token.

    • caller_: The expected caller's address.

    • currentEpochStart_: The current epoch start.

    Checks:

    • The start time of the current epoch must be less than the end time of the delegation. Otherwise, DelegationEnded() is thrown.


    _checkForSelfDelegation(uint256 tokenId_)

    Description: Internal function for checking self-delegation. Returns the LockHolder contract's address.

    Parameters:

    • tokenId_: The ID of the token representing the lock.

    Checks:

    • When self-delegating for tokenId_, the delegator must be equal to the delegate and both of these values must be equal to msg.sender. Otherwise, UnauthorizedCaller() is thrown


    _currentEpochStart()

    Description: The function returns the start timestamp of the current epoch


    _nextEpochStart()

    Description: The function returns the start timestamp of the next epoch


    _getTimeToUnlock(uint256 tokenId_)

    Description: The function returns the time until the lock is unlocked

    Parameters:

    • tokenId_: The ID of the token representing the lock.


    _checkDelegateeExist(address delegatee_)

    Description: Internal function to check if the delegate has set the delegation parameters

    Parameters:

    • delegatee_: The delegate's address.

    Checks:

    • delegatee_ must have delegation parameters set. Otherwise, DelegateeNotExist() is thrown.


    Events

    • Delegate(address indexed delegator, address indexed delegatee, uint256[] tokenIds) The event is emitted when the delegation is successful.

    • RecallDelegations(uint256[] tokenIds) The event is emitted when the recall delegation is successful.


    Errors

    • WrongDelegationParameters() Thrown if the delegate tries to set the wrong delegation parameters.

    • BadAssuranceLock() Thrown if the assurance lock is not compliant.

    • DelegateeNotExist() Thrown if the delegate has not set the delegation parameters.


    Summary

    DelegationManagerV1 contract allows the castle owner not to track voting and reward collection, and not to spend ether on transaction fees. The delegate, on the other hand, can earn by taking a percentage of the rewards, sharing them with the castle owner. Alternatively, the castle owner can delegate to himself, which would simply automate the execution of voting and collection of rebase rewards and incentive rewards.

  • IEscrowManagerExtended: Holds locked token data and checks voting power and freeze logic.

  • IEscrowVoteManagerV1: Receives gauge emission amounts and coordinates gauge reward distribution.

  • IEmissionManagerV1: Informs about epoch starts and ensures updated weekly distributions.

  • ILockHolderV1: Logic for proxied calls to EscrowManager, EscrowVoteManager and IncentiveRewardsDistributor contract functions

  • ICollection: Components in the ecosystem for NFT.

  • s_escrowManager (IEscrowManagerExtended) IEscrowManager interface for the EscrowManager contract.

  • s_escrowVoteManager (IEscrowVoteManagerV1) IEscrowVoteManagerV1 interface for the EscrowVoteManager contract.

  • s_lockHolderFactory (ILockHolderFactoryV1) ILockHolderFactoryV1 interface for the LockHolderFactoryV1 contract.

  • s_rebaseRewardsDistributor (IRebaseRewardsDistributorV2) IRebaseRewardsDistributorV2 interface for the RebaseRewardsDistributorV2 contract.

  • s_delegationConditionValidator (IDelegationConditionValidatorV1) IDelegationConditionValidatorV1 interface for the DelegationConditionValidator contract.

  • s_minLockEywa (uint256) The min EYWA amount in delegatee's lock.

  • s_minLockVeEywa (uint256) The min veEYWA amount in delegatee's lock.

  • s_minLockDuration (uint256) The min duration for delegatee's lock in seconds.

  • s_delegaties (address[]) Array with addresses of all delegates.

  • s_depositedByDelegatee (mapping(address => uint256)) Mapping from delegatee to its EYWA deposit information.

  • s_feeByDelegator (mapping(address => uint256)) Mapping from delegator to its EYWA fee information.

  • s_autoVoteByDelegatee (mapping(address => bool)) Mapping from delegatee to its permission for automatic execution of the autoVote() function.

  • s_delegationParametersByDelegatee (mapping(address => DelegationParameters)) Mapping from delegatee to its delegation parameters.

  • s_delegationInfoByTokenId (mapping(address => DelegationInfo)) Mapping from token ID to its delegation information.

  • s_lastClaimedIncentiveTimeByLockHolder (mapping(address => uint256)) Mapping from LockHolder contract address to its last time claimed incentive.

  • s_lastClaimedCommissionTimeByLockHolder (mapping(address => uint256)) Mapping from LockHolder contract address to its last time claimed commission.

  • s_lockHolders (mapping(address => mapping(address => address))) Nested mapping from delegator and delegatee to their LockHolder contract address.

  • _s_locksByDelegator (mapping(address => uint256)) Mapping from delegator to its amount of delegated locks.

  • _s_locksByDelegatee (mapping(address => uint256)) Mapping from delegatee to its amount of delegated locks.

  • _s_delegationVoteParametersByDelegatee (mapping(address => DelegationVoteParameters)) Mapping from delegatee to its delegation vote parameters.

  • _s_delegationIndexesInfoByTokenId (mapping(address => DelegationIndexesInfo)) Mapping from token ID to its delegation indexes info.

  • _s_lockIdByDelegatorAndIndex (address => mapping(uint256 => uint256)) Nested mapping from delegator and index to its delegated lock ID.

  • _s_lockIdByDelegateeAndIndex (address => mapping(uint256 => uint256)) Nested mapping from delegatee and index to its delegated lock ID.

  • _s_feeByDelegateeAndEpoch (mapping(address => mapping(uint256 => uint256))) Nested mapping of delegatee address and an epoch start to a fee.

  • References the EYWA token, EYWA NFT, escrow manager, escrow vote manager, emission manager, lockHolder factory, rebase rewards distributor, delegation condition validator.
    emissionManager_: IEmissionManagerV1 interface for the EmissionManagerV1 contract.
  • escrowManager_: The IEscrowManagerExtended interface for the EscrowManager contract.

  • escrowVoteManager_: The IEscrowVoteManagerV1 interface for the EscrowVoteManager contract.

  • lockHolderFactory_: ILockHolderFactoryV1 interface for the LockHolderFactoryV1 contract.

  • rebaseRewardsDistributor_: IRebaseRewardsDistributorV2 interface for the RebaseRewardsDistributorV2 contract.

  • delegationConditionValidator_: IDelegationConditionValidatorV1 interface for the DelegationConditionValidator contract.

  • Must be paid rent for all delegated tokens. Otherwise, DelegationUnpaid() is thrown.

  • The value of delegationParameters_.maxDelegatedVeEYWA must not be less than the current total veEYWA value for all locks delegated to this delegate. Otherwise, MaxDelegatedVeEywaExceeded() is thrown.

  • For each lock from tokenIds_, it is checked that its delegation time has not yet expired. Otherwise, DelegateTimeExpired() is thrown.

  • The maximum veEYWA value for dlegation should not be exceeded after extend of the locks. Otherwise, MaxDelegatedVeEywaExceeded() is thrown.

  • For each lock from tokenIds_, it is checked that there exists a LockHolder contract corresponding to the delegate-delegate pair. Otherwise, LockHolderNotExist() is thrown.

  • is thrown.
  • If it is not a self-delegation, additional delegation conditions are checked in the validateDelegations function on the DelegationConditionValidator contract. Otherwise, UnvalidatedDelegation() is thrown.

  • Must be paid rent for all delegated tokens. Otherwise, DelegationUnpaid() is thrown.

  • The delegation's time must be finalized. Otherwise, DelegationWithdrawalForbidden() is thrown.

  • delegatee_
    must be a delegatee. Otherwise,
    WrongDelegatee()
    is thrown.
    delegatee_: The delegate's address.

    InvalidArrayLengths() Thrown if the array has an invalid length.

  • UnauthorizedCaller() Thrown when the caller is not authorized to perform the action.

  • DelegateTimeExpired() Thrown when attempting to perform an action with a delegation with expired time.

  • DelegationEnded() Thrown when the delegation is complete.

  • WrongLockDuration() Thrown when attempting to set a new lock auto-extend time lower than the minimum allowed by the delegation parameters.

  • LockHolderNotExist() Thrown if there is no LockHolder for the current delegate and delegate pair.

  • NotEnoughAmount() Thrown when there is an insufficient deposit or fee for the requested operation.

  • DelegationNotEnded() Thrown when the delegation is not ended.

  • MaxDelegatedVeEywaExceeded() Thrown when the maximum number of delegated veEYWA has been exceeded.

  • UnvalidatedDelegation() Thrown when validation failed on the DelegationConditionValidator contract.

  • WrongVeEywaAmount() Thrown when the voting power of the delegated lock is less than s_minLockVeEywa.

  • LittleTimeToUnlock() Thrown when attempting to delegate a lock that has less time to unlock than the minimum time set by the delegate.

  • NotSetAutoVote() Thrown when attempting to perform auto-voting if no permission is set.

  • NotSetAutoVoteParameters() Thrown when attempting to perform auto-voting if no parameters are set for it.

  • WrongDelegatee() Thrown when attempting to perform an auto-vote if the lock is not delegated to the specified delegate.

  • DelegationWithdrawalForbidden() Thrown when the delegation time has not yet expired, preventing recall.

  • RewardsUnclaimed() Thrown when the delegation time has not yet expired, preventing recall.

  • DelegationUnpaid() Thrown when no awards have been received.

  • uint256 private constant EPOCH_DURATION = 1 weeks;
    uint256 private constant PRECISION = 100_000;
    constructor() {
        _disableInitializers();
    }
    function initialize(
        address owner_,
        IERC20 eywa_,
        ICollection collection_,
        IEmissionManagerV1 emissionManager_,
        IEscrowManagerExtended escrowManager_,
        IEscrowVoteManagerV1 escrowVoteManager_,
        ILockHolderFactoryV1 lockHolderFactory_,
        IRebaseRewardsDistributorV2 rebaseRewardsDistributor_,
        IDelegationConditionValidatorV1 delegationConditionValidator_
    ) external initializer;
    function setAssuranceLockParameters(
        uint256 minLockEywa_,
        uint256 minLockDuration_
    ) external onlyOwner;
    -   `minLockEywa_`: The minimum number of EYWA tokens that must be in the assurance lock.
    -   `minLockDuration_`: The the minimum time before unlocking that a assurance lock should have.
    function setMinLockVeEywa(uint256 minLockVeEywa_) external onlyOwner;
    function setDelegationParameters(InputDelegationParameters memory delegationParameters_) external;
    function setDelegationVoteParameters(
        address[] calldata pools_,
        uint256[] calldata weights_
    ) external;
    function setAutoVotePermission(bool permission_) external;
    function boost(
        uint256 tokenId_,
        uint256[] calldata collectionTokenIds_
    ) external;
    function deboost(
        uint256 tokenId_,
        uint256[] calldata collectionTokenIds_
    ) external;
    function extend(
        uint256[] calldata tokenIds_,
        uint256[] calldata lockDurations_
    ) external;
    function withdrawDeposit(uint256 amount_) external;
    function claim() external;
    function delegate(
        address delegatee_,
        uint256[] calldata tokenIds_
    ) external;
    function paymentAndExtendDelegations(uint256[] calldata tokenIds_) external;
    function claimIncentives(uint256[] calldata tokenIds_) external;
    function revokeDelegations(uint256[] calldata tokenIds_) external;
    function recallDelegations(uint256[] calldata tokenIds_) external;
    function vote(
        uint256[] calldata tokenIds_,
        address[][] calldata pools_,
        uint256[][] calldata weights_
    ) external;
    function autoVote(
        address delegatee_,
        uint256[] calldata tokenIds_
    ) external;
    function reset(uint256[] calldata tokenIds_) external;
    function poke(uint256[] calldata tokenIds_) external;
    function isAvailableDelegate(
        address delegator_,
        address delegatee_,
        uint256[] calldata tokenIds_
    ) external view returns(bool);
    function getDelegationsParameters() external view returns(OutputDelegationParameters[] memory);
    function getDelegationsVoteParametersByDelegate(
        address delegatee_
    ) external view returns(address[] memory pools_, uint256[] memory weights_);
    function getDelegationsInfoByTokenIds(
        uint256[] calldata tokenIds_
    ) external view returns(DelegationInfo[] memory);
    function getDelegationInfoAndParametersByTokenId(
        uint256 tokenId_
    ) 
        external
        view 
        returns(DelegationInfo memory delegationInfo_, DelegationParameters memory delegationParameters_);
    function getLockIdsByDelegator(address delegator_) external view returns(uint256[] memory);
    function getLockIdsByDelegatee(address delegatee_) external view returns(uint256[] memory);
    function getAssuranceLockStatus(
        uint256 tokenId_,
        address delegatee_
    ) public view returns(bool);
    function _delegate(
        IEscrowManagerExtended escrowManager_,
        DelegationParameters memory delegationParameters_,
        uint256[] calldata tokenIds_,
        address delegatee_
    ) private;
    function _recallDelegation(
        address delegator_,
        address delegatee_,
        uint256 tokenId_
    ) internal;
    function _getVotes(
        IEscrowManagerExtended escrowManager_,
        uint256[] calldata tokenIds_
    ) private view returns(uint256);
    function _getLastEpochOfDelegation(
        uint256 timeExpiry_,
        uint256 delegationEnd_
    ) internal view returns (uint256);
    function _getLastEpochOfDelegation(
        uint256 timeExpiry_,
        uint256 delegationEnd_,
        uint256 currentEpochStart_
    ) internal view returns (uint256);
    function _checkDelegationPaid(
        bool isSelfDelegation_,
        uint256 lastPaidEpoch_,
        uint256 paidEpoch_
    ) internal view returns (uint256);
    function _checkRewardsClaimed(
        uint256 tokenId_,
        uint256 currentEpochStart_,
        address lockHolder_
    ) internal view returns (uint256);
    _checkCaller(address caller_) internal view;
    function _checkDelegatorOrDelegatee(
        address delegator_,
        address delegatee_
    ) internal view;
    function _checkTimeExpiry(uint256 timeExpiry_) internal view
    function _checkLockHolder(
        address delegator_,
        address delegatee_
    ) internal view returns(address);
    function _checkAssuranceLock(
        uint256 assuranceLock_,
        address delegatee_
    ) internal view returns(address);
    function _checkDelegation(
        DelegationInfo memory delegationInfo_,
        address caller_,
        uint256 currentEpochStart_
    ) internal view returns(address);
    function _checkForSelfDelegation(uint256 tokenId_) internal view returns(address);
    function _currentEpochStart() internal view returns (uint256);
    function _nextEpochStart() internal view returns (uint256);
    function _getTimeToUnlock(uint256 tokenId_) internal view returns(uint256);
    function _checkDelegateeExist(address delegatee_) internal view;

    Technical Documentation for CrossCurve API

    Make cross-chain swap

    Performing a cross-chain swap consists of 4 steps:

    1. Routing construction

    2. Estimating cross-chain operations

    3. Forming data for the transaction

    4. Sending the transaction

    1. Routing construction

    Request routing for the specified tokens and networks

    Copy

    2. Making a route estimate

    From the obtained array of routes, take the first route (which is the most profitable for swapping) and send it for estimation

    Copy

    3. Forming data for sending the transaction

    Copy

    4. Sending the transaction

    Copy

    Tracking cross-chain swaps

    After initiating the cross-chain swap (sending the transaction), it is necessary to ensure that it reaches the destination network and is executed successfully. Each cross-chain swap involves several transactions and the number of transactions may vary depending on the operation.

    For swapping two stablecoins from Network A to Network B, the route can be depicted as:

    Chain A -----> Hubchain -----> Chain B

    Each transaction is linked with another by a unique identifier, requestId, which represents the cross-chain transition identifier and can be used to track the source status and transaction destinations.

    Searching for requestId

    You can get requestId of a transaction using its hash with the Pusher API:

    Copy

    Getting details about the cross-chain transition by its requestId

    Copy

    In the results, we are interested in the values of destination.status and destination.transactionHash. If destination.transactionHash is empty, this means that the transaction has not yet been executed and the request should be repeated at intervals until the hash appears.

    Then there are 3 scenarios:

    1. Both details.inconsistency and destination.emergency are false This scenario is considered the most correct and will occur in most cases. It means the cross-chain operation has been completed and we have the hash of the destination transaction. Now, using this hash, similarly, you can track the status of the next cross-chain transition (if there is one) and continue doing so until all cross-chain transitions are completed.

    2. details.inconsistency is true This means that the destination transaction was successfully completed, but the token swap did not occur due to slippage. An intermediate result has been returned to your address in this network. The cross-chain operation is considered complete at this point.

    3. The value of destination.emergency is true In this case, the destination network operation could not be executed and your tokens are stuck in the contract. To retrieve them, you need to contact support to request a refund.

    Pusher API Reference

    API Specification

    POST https://api.crosscurve.fi/api-docs/#/

    Routing API

    Get possible cross-chain routes for token exchange

    POST https://api.crosscurve.fi/routing/scan

    Request Body

    Name
    Type
    Description

    Get an estimate for cross-chain exchange

    POST https://api.crosscurve.fi/estimate

    Request Body

    Name
    Type
    Description

    Formulate data for the transaction

    POST https://api.crosscurve.fi/tx/create

    Request Body

    Name
    Type
    Description

    Explorer API

    API link: https://api.crosscurve.fi

    Explorer: https://explorer.eywa.fi/

    Get information about the transaction by its hash or requestId

    GET https://api.crosscurve.fi/search?search={hashOrReqId}&limit={limit}

    Query Parameters

    Name
    Type
    Description

    Get details of the cross-chain transfer by requestId

    GET https://api.crosscurve.fi/transaction/{reqId}

    Path Parameters

    Name
    Type
    Description

    Glossary

    Decryption of router operation codes:

    A - add liquidity

    R - remove liquidity

    S - swap

    LM - lock mint (lock the original token and mint its synthetic token in another network)

    BU - burn unlock (burn the synthetic token and unlock the original in another network)

    BM - burn mint (burn the synthetic token and mint the synthetic token in another network)

    params.tokenIn*

    String

    address of the token that the user is selling on the chainIdIn network

    params.tokemOut*

    String

    address of the token that the user is buying on the chainIdOut network

    params.amountIn*

    String

    query.params.tokenIn*

    String

    query.params.tokenOut*

    String

    query.params.amountIn*

    String

    query.slippage*

    Number

    amountIn*

    String

    amountInWithoutSlippage*

    String

    amountOut*

    String

    amountOutWithoutSlippage*

    String

    route*

    Route

    Uw - unwrap to native token

    W - wrap native token

    M - emergency mint

    U - emergency unlock

    params.chainIdIn*

    Number

    chainId of the sending network

    params.chainIdOut*

    Number

    chainId of the receiving network

    params*

    Object

    slippage*

    Number

    query*

    Object

    query.params*

    Object

    query.params.chainIdIn*

    Number

    query.params.chainIdOut*

    Number

    from*

    String

    recipient*

    String

    routing*

    Routing

    estimate*

    Estimate

    search*

    String

    hash or requestId of the transaction

    limit*

    String

    reqId*

    String

    const requestRoutingParams = {
        params: {
             chainIdIn": 1, // Ethereum
             chainIdOut: 250, // Fantom
             tokenIn: "0xdac17f958d2ee523a2206206994597c13d831ec7", // USDT
             tokenOut: "0xe71286fc887189c562410af12ed521c8e58e5fa3", // s3crypto_e
             amountIn: "100000000", // 100 USDT
        },
        slippage: 1, // 1%
    }
    
    const response = await fetch('https://api.crosscurve.fi/routing/scan', {
        method: 'POST',
        body: JSON.stringify(requestRoutingParams),
        headers: {
            "Content-Type": "application/json",
        },
    })
    
    const routing = await response.json()
    const bestRoute = routing[0]
    
    const response = await fetch('https://api.crosscurve.fi/estimate', {
        method: 'POST',
        body: JSON.stringify(bestRoute),
        headers: {
            "Content-Type": "application/json",
        },
    })
    
    const estimate = await response.json()
    const txCreateParams = {
        from: '0x...', // sender
        recipient: '0x...', // recipient
        routing,
        estimate,
    }
    
    const response = await fetch('https://api.crosscurve.fi/tx/create', {
        method: 'POST',
        body: JSON.stringify(txCreateParams),
        headers: {
            "Content-Type": "application/json",
        },
    })
    
    const rawTx = await response.json()
    import { Contract, JsonRpcProvider } from 'ethers'
     
    const provider = new JsonRpcProvider('RPC_URL_HERE')
    const signer = new Wallet(process.env.PRIVATE_KEY, provider)
    
    const router = new Contract(rawTx.to, [rawTx.abi], signer)
    
    const args = [
      rawTx.args[0],
      rawTx.args[1],
      [
        rawTx.args[2].executionPrice,
        rawTx.args[2].deadline,
        rawTx.args[2].v,
        rawTx.args[2].r,
        rawTx.args[2].s,
      ],
    ]
    
    const value = BigInt(rawTx.value) + BigInt(estimate.executionPrice)
    
    const tx = await router.start(...args, { value })
    const receipt = await tx.wait()
    const searchParams = new URLSearchParams({
    search: '0x...', // transaction hash
    limit: 1,
    }).toString();
    const response = await fetch(`https://api.crosscurve.fi/?${searchParams}`, {
    method: 'GET',
    })
    const result = await response.json()
    const details = result.result[0]
    const requestId = details.requestId
    TypeScript
    const response = await fetch(`https://api.crosscurve.fi/search?search=%7BhashOrReqId%7D&limit=%7Blimit%7D`, {
    method: 'GET',
    })
    const details = await response.json()
    const destination = details.destination
    TypeScript
    [
      {
        "query": {
          "params": {
            "tokenIn": "0xdac17f958d2ee523a2206206994597c13d831ec7",
            "chainIdIn": 1,
            "tokenOut": "0xe71286fC887189C562410af12eD521C8e58e5fA3",
            "chainIdOut": 250,
            "amountIn": "100000000"
          },
          "slippage": 0.5
        },
        "route": [
          {
            "type": "addLiquidity",
            "chainId": 1,
            "params": {
              "tokenIn": {
                "logos": {
                  "16": "https://s2.coinmarketcap.com/static/img/coins/16x16/825.png",
                  "32": "https://s2.coinmarketcap.com/static/img/coins/32x32/825.png",
                  "64": "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png",
                  "128": "https://s2.coinmarketcap.com/static/img/coins/128x128/825.png",
                  "200": "https://s2.coinmarketcap.com/static/img/coins/200x200/825.png"
                },
                "chainId": 1,
                "address": "0xdac17f958d2ee523a2206206994597c13d831ec7",
                "name": "Tether USD",
                "symbol": "USDT",
                "decimals": 6,
                "originalName": "Tether USD",
                "originalSymbol": "USDT",
                "tags": ["erc20", "stable"],
                "permittable": false,
                "permit": false
              },
              "chainIdIn": 1,
              "tokenOut": {
                "chainId": 1,
                "address": "0xc4ad29ba4b3c580e6d59105fff484999997675ff",
                "name": "Curve.fi USD-BTC-ETH",
                "symbol": "crv3crypto",
                "decimals": 18,
                "originalName": "Curve.fi USD-BTC-ETH",
                "originalSymbol": "crv3crypto",
                "tags": ["erc20", "curve_lp"],
                "permittable": false,
                "permit": false,
                "coins": [
                  "0xdAC17F958D2ee523a2206206994597C13D831ec7",
                  "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
                  "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
                ]
              },
              "chainIdOut": 1,
              "amountIn": "100000000",
              "amountInWithoutSlippage": "100000000",
              "amountOut": "54972421143512185",
              "amountOutWithoutSlippage": "55248664465841392",
              "slippage": 0.5
            },
            "pool": {
              "address": "0xd51a44d3fae010294c616388b506acda1bfaae46",
              "coins": [
                "0xdAC17F958D2ee523a2206206994597C13D831ec7",
                "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
                "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
              ],
              "decimals": [6, 8, 18],
              "logos": {
                "16": "https://s2.coinmarketcap.com/static/img/exchanges/16x16/1063.png",
                "32": "https://s2.coinmarketcap.com/static/img/exchanges/32x32/1063.png",
                "64": "https://s2.coinmarketcap.com/static/img/exchanges/64x64/1063.png",
                "128": "https://s2.coinmarketcap.com/static/img/exchanges/128x128/1063.png",
                "200": "https://s2.coinmarketcap.com/static/img/exchanges/200x200/1063.png"
              },
              "lp": {
                "chainId": 1,
                "address": "0xc4ad29ba4b3c580e6d59105fff484999997675ff",
                "name": "Curve.fi USD-BTC-ETH",
                "symbol": "crv3crypto",
                "decimals": 18,
                "originalName": "Curve.fi USD-BTC-ETH",
                "originalSymbol": "crv3crypto",
                "tags": ["erc20", "curve_lp"],
                "permittable": false,
                "permit": false,
                "coins": [
                  "0xdAC17F958D2ee523a2206206994597C13D831ec7",
                  "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
                  "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
                ]
              }
            },
            "fees": [
              {
                "type": "eywaStableSwapFee",
                "token": {
                  "logos": {
                    "16": "https://s2.coinmarketcap.com/static/img/coins/16x16/825.png",
                    "32": "https://s2.coinmarketcap.com/static/img/coins/32x32/825.png",
                    "64": "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png",
                    "128": "https://s2.coinmarketcap.com/static/img/coins/128x128/825.png",
                    "200": "https://s2.coinmarketcap.com/static/img/coins/200x200/825.png"
                  },
                  "chainId": 1,
                  "address": "0xdac17f958d2ee523a2206206994597c13d831ec7",
                  "name": "Tether USD",
                  "symbol": "USDT",
                  "decimals": 6,
                  "originalName": "Tether USD",
                  "originalSymbol": "USDT",
                  "tags": ["erc20", "stable"],
                  "permittable": false,
                  "permit": false
                },
                "percent": "0.0654473",
                "amount": "65447"
              }
            ]
          },
          {
            "type": "bridgeIn",
            "chainId": 1,
            "params": {
              "tokenIn": {
                "chainId": 1,
                "address": "0xc4ad29ba4b3c580e6d59105fff484999997675ff",
                "name": "Curve.fi USD-BTC-ETH",
                "symbol": "crv3crypto",
                "decimals": 18,
                "originalName": "Curve.fi USD-BTC-ETH",
                "originalSymbol": "crv3crypto",
                "tags": ["erc20", "curve_lp"],
                "permittable": false,
                "permit": false,
                "coins": [
                  "0xdAC17F958D2ee523a2206206994597C13D831ec7",
                  "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
                  "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
                ]
              },
              "chainIdIn": 1,
              "tokenOut": {
                "chainId": 250,
                "address": "0xe71286fC887189C562410af12eD521C8e58e5fA3",
                "name": "s3crypto_e",
                "symbol": "s3crypto_e",
                "decimals": 18,
                "originalName": "s3crypto_e",
                "originalSymbol": "s3crypto_e",
                "tags": ["erc20", "synth"],
                "permittable": false,
                "permit": false,
                "real": {
                  "chainId": 1,
                  "address": "0xc4ad29ba4b3c580e6d59105fff484999997675ff",
                  "name": "Curve.fi USD-BTC-ETH",
                  "symbol": "crv3crypto",
                  "decimals": 18,
                  "originalName": "Curve.fi USD-BTC-ETH",
                  "originalSymbol": "crv3crypto",
                  "tags": ["erc20", "curve_lp"],
                  "permittable": false,
                  "permit": false,
                  "coins": [
                    "0xdAC17F958D2ee523a2206206994597C13D831ec7",
                    "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
                    "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
                  ]
                },
                "realToken": {
                  "chainId": 1,
                  "address": "0xc4ad29ba4b3c580e6d59105fff484999997675ff",
                  "name": "Curve.fi USD-BTC-ETH",
                  "symbol": "crv3crypto",
                  "decimals": 18,
                  "originalName": "Curve.fi USD-BTC-ETH",
                  "originalSymbol": "crv3crypto",
                  "tags": ["erc20", "curve_lp"],
                  "permittable": false,
                  "permit": false,
                  "coins": [
                    "0xdAC17F958D2ee523a2206206994597C13D831ec7",
                    "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
                    "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
                  ]
                }
              },
              "chainIdOut": 250,
              "amountIn": "54972421143512185",
              "amountInWithoutSlippage": "55248664465841392",
              "amountOut": "54972421143512185",
              "amountOutWithoutSlippage": "55248664465841392",
              "slippage": 0.5
            },
            "fees": [
              {
                "type": "bridgeFee",
                "amount": "0",
                "percent": "0",
                "token": {
                  "chainId": 250,
                  "address": "0xe71286fC887189C562410af12eD521C8e58e5fA3",
                  "name": "s3crypto_e",
                  "symbol": "s3crypto_e",
                  "decimals": 18,
                  "originalName": "s3crypto_e",
                  "originalSymbol": "s3crypto_e",
                  "tags": ["erc20", "synth"],
                  "permittable": false,
                  "permit": false,
                  "real": {
                    "chainId": 1,
                    "address": "0xc4ad29ba4b3c580e6d59105fff484999997675ff",
                    "name": "Curve.fi USD-BTC-ETH",
                    "symbol": "crv3crypto",
                    "decimals": 18,
                    "originalName": "Curve.fi USD-BTC-ETH",
                    "originalSymbol": "crv3crypto",
                    "tags": ["erc20", "curve_lp"],
                    "permittable": false,
                    "permit": false,
                    "coins": [
                      "0xdAC17F958D2ee523a2206206994597C13D831ec7",
                      "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
                      "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
                    ]
                  },
                  "realToken": {
                    "chainId": 1,
                    "address": "0xc4ad29ba4b3c580e6d59105fff484999997675ff",
                    "name": "Curve.fi USD-BTC-ETH",
                    "symbol": "crv3crypto",
                    "decimals": 18,
                    "originalName": "Curve.fi USD-BTC-ETH",
                    "originalSymbol": "crv3crypto",
                    "tags": ["erc20", "curve_lp"],
                    "permittable": false,
                    "permit": false,
                    "coins": [
                      "0xdAC17F958D2ee523a2206206994597C13D831ec7",
                      "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
                      "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
                    ]
                  }
                }
              }
            ]
          }
        ],
        "amountIn": "100000000",
        "amountOut": "54972421143512185",
        "amountOutWithoutSlippage": "55248664465841392",
        "tokenInPrice": 1,
        "tokenOutPrice": 1811.0144629377985,
        "priceImpact": 0,
        "totalFee": {
          "type": "total",
          "percent": "0.07",
          "amount": 0.06545
        }
      }
    ]
    {
    "priceInDollars": "2.88",
    "executionPrice": "1408116103514941",
    "stablePrice": "0",
    "workerFee": "1408116103514941",
    "deadline": "1699876788",
    "signature": "RiyQlohm2vpof3Nnab4cUwZ/mHey/Su"
    }
    {
    "to": "0x9af02523431E9Ec1Cc649c75aB0322fF34cde337",
    "abi": "function start(string[],bytes[],tuple(uint256,uint256,uint8,bytes32,bytes32)) payable",
    "args": [
    ["LM", "As", "Ss", "Rs", "BU"],
    [
    "0x0000000000000000000000002e1ad108ff1d8c782fcbbb89aad783ac495867560000000000000000000000000000000000000000000000019274b259f6540000000000000000000000000000bd2c008c3467393c6f342a275ec8f2ccd7b4f40d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd2c008c3467393c6f342a275ec8f2ccd7b4f40d",
    "0x0000000000000000000000002827053d2f2c3ed312d2092e57d8537405fdfd0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054cc70a3324cac8308045d027415e4df82ee72b8000000000000000000000000000000000000000000000001906a0a6f860c0d89000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000",
    "0x00000000000000000000000054cc70a3324cac8308045d027415e4df82ee72b8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000da8a6f376f056f0b10980ef0756bd642bc3ecab00000000000000000000000000000000000000000000000018e421e43cc563e5a0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064d09662725ddc8d01a037618906a04326b9985f0000000000000000000000000000000000000000000000000000000000000000",
    "0x00000000000000000000000064d09662725ddc8d01a037618906a04326b9985fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064d09662725ddc8d01a037618906a04326b9985f0000000000000000000000000000000000000000000000000000000001b3d1dc000000000000000000000000000000000000000000000000000000000000000300000000000000000000000074aeed349f3fcae9c158504686f9304c4bbfa39a0000000000000000000000000000000000000000000000000000000000000000",
    "0x00000000000000000000000074aeed349f3fcae9c158504686f9304c4bbfa39affffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd2c008c3467393c6f342a275ec8f2ccd7b4f40d000000000000000000000000000000000000000000000000000000000000a86a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    ],
    {
    "executionPrice": "449952232019487626",
    "deadline": "1698416184651",
    "v": 28,
    "r": "0x178afdb0baacdae7b6e0c920de67e2b981a3a8c141204f26c66f5d6d148cde0a",
    "s": "0x5391489d89f6955281245896199baee4d3a983caf0af027ceb93aac62e5b743f"
    }
    ],
    "value": "0"
    }
    {
    "result": [
    {
    "requestId": "0x5173910105f8c526ed1dbbac0dc3e0d1efd9b18b83f56d460a7a3dd09d4d198e",
    "status": "completed",
    "source": {
    "chainId": "137",
    "transactionHash": "0xad58de57530187afa410d3dc5356e843be0c123075a51fe38aeb46a7f0481133",
    "from": "0xBD2c008C3467393C6F342A275EC8F2Ccd7B4F40D",
    "events": [
    {
    "args": {
    "_to": "0xBf0b5D561b986809924f88099c4FF0e6BccE60c9",
    "_from": "0xBD2c008C3467393C6F342A275EC8F2Ccd7B4F40D",
    "_value": "29000000000000000000"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x2e1AD108fF1D8C782fcBbB89AAd783aC49586756",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "to": "0x0000000000000000000000000000000000000000",
    "from": "0xBD2c008C3467393C6F342A275EC8F2Ccd7B4F40D",
    "token": "0x2e1AD108fF1D8C782fcBbB89AAd783aC49586756",
    "amount": "29000000000000000000"
    },
    "name": "Locked",
    "topic": "0xb5f411fa3c897c9b0b6cd61852278a67e73d885610724a5610a8580d3e94cfdb",
    "address": "0xBf0b5D561b986809924f88099c4FF0e6BccE60c9",
    "signature": "Locked(address,uint256,address,address)"
    },
    {
    "args": {
    "lastOp": 0,
    "result": 1,
    "nextChainId": "250",
    "nextRequestId": "0x5173910105f8c526ed1dbbac0dc3e0d1efd9b18b83f56d460a7a3dd09d4d198e",
    "currentChainId": "137",
    "currentRequestId": "0x0000000000000000000000000000000000000000000000000000000000000000"
    },
    "name": "ComplexOpProcessed",
    "topic": "0x830adbcf80ee865e0f0883ad52e813fdbf061b0216b724694a2b4e06708d243c",
    "address": null,
    "signature": "ComplexOpProcessed(uint64,bytes32,uint64,bytes32,uint8,uint8)"
    },
    {
    "args": {
    "payer": "0xBD2c008C3467393C6F342A275EC8F2Ccd7B4F40D",
    "accountant": "0x94a365CA808029AF8db18257ecd296c16C61AC05",
    "executionPrice": "449952232019487626"
    },
    "name": "FeePaid",
    "topic": "0xbf6afbaffb3b955bebbf43430bbf8eecb8d34ff86f293f592203ab5ed79c5268",
    "address": null,
    "signature": "FeePaid(address,address,uint256)"
    }
    ]
    },
    "destination": {
    "chainId": "250",
    "transactionHash": "0x6969c46c4c8b239486e309155cf75b2b4ea2d1b7a8ca8a868155546cd9ce6edf",
    "to": "0x1C61f207F50acAF3b15D1DE4eb7a02f290c3eE8A",
    "events": [
    {
    "args": {
    "_to": "0x4400671b8238B5E0c7c9d7572746d236cd292845",
    "_from": "0x0000000000000000000000000000000000000000",
    "_value": "0"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x2827053d2F2c3ED312d2092e57D8537405fdFd0f",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "_to": "0x14F98dcf918a451a15f3A11d824C65906bDDc296",
    "_from": "0x0000000000000000000000000000000000000000",
    "_value": "29000000000000000000"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x2827053d2F2c3ED312d2092e57D8537405fdFd0f",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "_to": "0x54cc70A3324cAc8308045D027415e4Df82EE72B8",
    "_from": "0x14F98dcf918a451a15f3A11d824C65906bDDc296",
    "_value": "29000000000000000000"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x2827053d2F2c3ED312d2092e57D8537405fdFd0f",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "_to": "0x14F98dcf918a451a15f3A11d824C65906bDDc296",
    "_from": "0x64D09662725dDc8D01a037618906a04326B9985f",
    "_value": "28994655"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x74aEeD349F3Fcae9C158504686f9304C4Bbfa39A",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "_to": "0x530aF883f135F135BE12A69DC33296fb8149f593",
    "_from": "0x14F98dcf918a451a15f3A11d824C65906bDDc296",
    "_value": "28994655"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x74aEeD349F3Fcae9C158504686f9304C4Bbfa39A",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "_to": "0x0000000000000000000000000000000000000000",
    "_from": "0x530aF883f135F135BE12A69DC33296fb8149f593",
    "_value": "28994655"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x74aEeD349F3Fcae9C158504686f9304C4Bbfa39A",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "to": "0xBD2c008C3467393C6F342A275EC8F2Ccd7B4F40D",
    "from": "0x530aF883f135F135BE12A69DC33296fb8149f593",
    "token": "0x74aEeD349F3Fcae9C158504686f9304C4Bbfa39A",
    "amount": "28994655"
    },
    "name": "Burn",
    "topic": "0xc489dd211b01a11cf2d73490ca466baa426e76a7811070af00cc9a2bfd322f1c",
    "address": "0x530aF883f135F135BE12A69DC33296fb8149f593",
    "signature": "Burn(address,uint256,address,address)"
    },
    {
    "args": {
    "lastOp": 4,
    "result": 1,
    "nextChainId": "43114",
    "nextRequestId": "0x5d685648f8c21405956e570d0796055dcf330e3768cfd27e1d50a5e46c9a1fae",
    "currentChainId": "250",
    "currentRequestId": "0x5173910105f8c526ed1dbbac0dc3e0d1efd9b18b83f56d460a7a3dd09d4d198e"
    },
    "name": "ComplexOpProcessed",
    "topic": "0x830adbcf80ee865e0f0883ad52e813fdbf061b0216b724694a2b4e06708d243c",
    "address": null,
    "signature": "ComplexOpProcessed(uint64,bytes32,uint64,bytes32,uint8,uint8)"
    }
    ]
    }
    }
    ],
    "total": 1
    }
    {
    "status": "completed",
    "inconsistency": false,
    "source": {
    "chainId": "137",
    "transactionHash": "0xad58de57530187afa410d3dc5356e843be0c123075a51fe38aeb46a7f0481133",
    "from": "0xBD2c008C3467393C6F342A275EC8F2Ccd7B4F40D",
    "events": [
    {
    "args": {
    "_to": "0xBf0b5D561b986809924f88099c4FF0e6BccE60c9",
    "_from": "0xBD2c008C3467393C6F342A275EC8F2Ccd7B4F40D",
    "_value": "29000000000000000000"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x2e1AD108fF1D8C782fcBbB89AAd783aC49586756",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "to": "0x0000000000000000000000000000000000000000",
    "from": "0xBD2c008C3467393C6F342A275EC8F2Ccd7B4F40D",
    "token": "0x2e1AD108fF1D8C782fcBbB89AAd783aC49586756",
    "amount": "29000000000000000000"
    },
    "name": "Locked",
    "topic": "0xb5f411fa3c897c9b0b6cd61852278a67e73d885610724a5610a8580d3e94cfdb",
    "address": "0xBf0b5D561b986809924f88099c4FF0e6BccE60c9",
    "signature": "Locked(address,uint256,address,address)"
    },
    {
    "args": {
    "lastOp": 0,
    "result": 1,
    "nextChainId": "250",
    "nextRequestId": "0x5173910105f8c526ed1dbbac0dc3e0d1efd9b18b83f56d460a7a3dd09d4d198e",
    "currentChainId": "137",
    "currentRequestId": "0x0000000000000000000000000000000000000000000000000000000000000000"
    },
    "name": "ComplexOpProcessed",
    "topic": "0x830adbcf80ee865e0f0883ad52e813fdbf061b0216b724694a2b4e06708d243c",
    "address": null,
    "signature": "ComplexOpProcessed(uint64,bytes32,uint64,bytes32,uint8,uint8)"
    },
    {
    "args": {
    "payer": "0xBD2c008C3467393C6F342A275EC8F2Ccd7B4F40D",
    "accountant": "0x94a365CA808029AF8db18257ecd296c16C61AC05",
    "executionPrice": "449952232019487626"
    },
    "name": "FeePaid",
    "topic": "0xbf6afbaffb3b955bebbf43430bbf8eecb8d34ff86f293f592203ab5ed79c5268",
    "address": null,
    "signature": "FeePaid(address,address,uint256)"
    }
    ],
    "status": "completed"
    },
    "oracle": {
    "relayChainId": "137",
    "requestId": "0x5173910105f8c526ed1dbbac0dc3e0d1efd9b18b83f56d460a7a3dd09d4d198e",
    "status": "completed",
    "height": "3942",
    "epoch": 4,
    "time": "2023-10-27T14:13:45.949Z"
    },
    "destination": {
    "chainId": "250",
    "transactionHash": "0x6969c46c4c8b239486e309155cf75b2b4ea2d1b7a8ca8a868155546cd9ce6edf",
    "to": "0x1C61f207F50acAF3b15D1DE4eb7a02f290c3eE8A",
    "events": [
    {
    "args": {
    "_to": "0x4400671b8238B5E0c7c9d7572746d236cd292845",
    "_from": "0x0000000000000000000000000000000000000000",
    "_value": "0"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x2827053d2F2c3ED312d2092e57D8537405fdFd0f",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "_to": "0x14F98dcf918a451a15f3A11d824C65906bDDc296",
    "_from": "0x0000000000000000000000000000000000000000",
    "_value": "29000000000000000000"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x2827053d2F2c3ED312d2092e57D8537405fdFd0f",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "_to": "0x54cc70A3324cAc8308045D027415e4Df82EE72B8",
    "_from": "0x14F98dcf918a451a15f3A11d824C65906bDDc296",
    "_value": "29000000000000000000"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x2827053d2F2c3ED312d2092e57D8537405fdFd0f",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "_to": "0x14F98dcf918a451a15f3A11d824C65906bDDc296",
    "_from": "0x64D09662725dDc8D01a037618906a04326B9985f",
    "_value": "28994655"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x74aEeD349F3Fcae9C158504686f9304C4Bbfa39A",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "_to": "0x530aF883f135F135BE12A69DC33296fb8149f593",
    "_from": "0x14F98dcf918a451a15f3A11d824C65906bDDc296",
    "_value": "28994655"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x74aEeD349F3Fcae9C158504686f9304C4Bbfa39A",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "_to": "0x0000000000000000000000000000000000000000",
    "_from": "0x530aF883f135F135BE12A69DC33296fb8149f593",
    "_value": "28994655"
    },
    "name": "Transfer",
    "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    "address": "0x74aEeD349F3Fcae9C158504686f9304C4Bbfa39A",
    "signature": "Transfer(address,address,uint256)"
    },
    {
    "args": {
    "to": "0xBD2c008C3467393C6F342A275EC8F2Ccd7B4F40D",
    "from": "0x530aF883f135F135BE12A69DC33296fb8149f593",
    "token": "0x74aEeD349F3Fcae9C158504686f9304C4Bbfa39A",
    "amount": "28994655"
    },
    "name": "Burn",
    "topic": "0xc489dd211b01a11cf2d73490ca466baa426e76a7811070af00cc9a2bfd322f1c",
    "address": "0x530aF883f135F135BE12A69DC33296fb8149f593",
    "signature": "Burn(address,uint256,address,address)"
    },
    {
    "args": {
    "lastOp": 4,
    "result": 1,
    "nextChainId": "43114",
    "nextRequestId": "0x5d685648f8c21405956e570d0796055dcf330e3768cfd27e1d50a5e46c9a1fae",
    "currentChainId": "250",
    "currentRequestId": "0x5173910105f8c526ed1dbbac0dc3e0d1efd9b18b83f56d460a7a3dd09d4d198e"
    },
    "name": "ComplexOpProcessed",
    "topic": "0x830adbcf80ee865e0f0883ad52e813fdbf061b0216b724694a2b4e06708d243c",
    "address": null,
    "signature": "ComplexOpProcessed(uint64,bytes32,uint64,bytes32,uint8,uint8)"
    }
    ],
    "status": "completed",
    "emergency": false,
    "error": null
    },
    "data": {
    "callData": "0000000000000089f898c1cbab66ac331e48ad0854bdd7daeee8806c5a1342c68df5f8d3b5ba8c8bdab6060b0f5c53a9cf19a7eb0b478ac03faf58420ef143624e89feb96d5bdd9416d8208c06afb253d3b4d913a45f11f6661837a73706a9272680626e1b84b6c60000000002eefe7b0000000000000f6600000000653bc534",
    "size": 128
    }
    }

    CrossCurve smart contracts

    ss-chain liquidity protocol smart contracts (CrossCurve) are a type of self-executing digital agreement stored on a blockchain that automatically execute when predetermined terms and conditions are met. These contracts facilitate the creation of liquidity pools that enable decentralized trading, offering behaviors that are more predictable and in line with the primary principles of blockchain technology, such as trustless operations without susceptible governance. In general, smart contracts are designed to digitally facilitate, verify, or enforce the negotiation or performance of a contract. They allow transactions to be conducted without the need for intermediaries, while ensuring that these transactions are trackable and irreversible once completed.

    Chain\Name
    AddressBook
    PortalV2
    SynthesisV2
    SynthFactory
    UnifiedRouterV2
    OpsRegistrar
    Whitelist
    FeesTreasury
    VirtualPriceSender
    VirtualPriceReceiver
    VirtualPriceReceiver
    VirtualPriceReceiver
    VirtualPriceReceiverV2
    VirtualPriceReceiver3
    VirtualPriceReceiver4
    Locker
    Chain\Name
    Adapter (stable1)
    Adapter (stable1)
    Adapter (stable2)
    Adapter (stable2)
    Adapter (stable2)
    Adapter (stable3)
    Adapter (stable4)
    Adapter (crypto1)
    Adapter (crypto1)
    Adapter (crypto4)
    Adapter (crypto4)
    Adapter (crypto5)
    Adapter (crypto6)
    Adapter (crypto7)

    Polygon

    Avalanche

    Optimism

    Arbitrum

    Fantom

    Base

    Gnosis

    Mantle

    Blast

    Linea

    Taiko

    Unit0

    Celo

    Fraxtal

    Kava

    Metis

    Mode

    Sonic

    Manta

    Description

    same as v1.5

    same as v1.5

    same as v1.5

    v 2.51 (celo)

    same as v1

    same as v1

    same as v2

    xCRVUSDC

    x3CRYPTO

    xCRVUSDT

    xSTABLE

    xBTC

    xSTABLE2

    Adapter (meta1)

    Ethereum

    BNB

    Ethereum

    link

    link

    link

    link

    link

    link

    link

    link

    link

    BSC

    link

    Polygon

    link

    link

    link

    link

    link

    Avalanche

    link

    link

    link

    link

    link

    Optimism

    link

    link

    link

    link

    Arbitrum

    link

    link

    link

    link

    link

    link

    Fantom

    link

    link

    Base

    link

    link

    Gnosis

    link

    LP

    link

    link

    Taiko

    link

    link

    Celo

    link

    Fraxtal

    link

    link

    Sonic

    link

    link

    Description

    n: 3

    n: 3

    n: 2

    n: 3

    n: 4

    Aave, n: 3

    stableNG/cryptoNG

    n: 3

    n: 2

    n: 2

    zap

    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    link
    LP
    link
    link
    link
    link

    Supported tokens

    Assets available for cross-chain swaps

    Assets

    Chain
    Ticker/Link
    Address

    Ethereum

    0x8cb8C4263EB26b2349d74ea2cB1B27bc40709e12

    Curve LPs

    Chain
    Ticker/Link
    Address

    Ethereum

    0xb7ecb2aa52aa64a717180e030241bc75cd946726

    Arbitrum

    0x82670f35306253222f8a165869b28c64739ac62e

    Arbitrum

    0xec090cf6DD891D2d014beA6edAda6e05E025D93d

    Arbitrum

    0x73aF1150F265419Ef8a5DB41908B700C32D49135

    Arbitrum

    0x7f90122BF0700F9E7e1F688fe926940E8839F353

    Arbitrum

    0x186cf879186986a20aadfb7ead50e3c20cb26cec

    Arbitrum

    0xdadd23929ca8efcbc43aaf8f677d426563cc40d7

    Arbitrum

    0x6579758e9e85434450d638cfbea0f2fe79856dda

    Polygon

    0xdAD97F7713Ae9437fa9249920eC8507e5FbB23d3

    Polygon

    0xb0658482b405496c4ee9453cd0a463b134aef9d0

    Polygon

    0x5225010A0AE133B357861782B0B865a48471b2C5

    Polygon

    0xA70Af99bFF6b168327f9D1480e29173e757c7904

    Polygon

    0xE7a24EF0C5e95Ffb0f6684b813A78F2a3AD7D171

    Polygon

    0xA73EdCf18421B56D9AF1cE08A34E102E23b2C4B6

    Avalanche

    0x1daB6560494B04473A0BE3E7D83CF3Fdf3a51828

    Avalanche

    0x1dc5c0f8668a9f54ed922171d578011850ca0341

    Avalanche

    0x1337BedC9D22ecbe766dF105c9623922A27963EC

    Optimism

    0x03771e24b7C9172d163Bf447490B142a15be3485

    Optimism

    0x4456d13Fc6736e8e8330394c0C622103E06ea419

    Optimism

    0xD1b30BA128573fcd7D141C8A987961b40e047BB6

    Optimism

    0x1337BedC9D22ecbe766dF105c9623922A27963EC

    BNB chain

    0xC4Ec3aB41182E70cA45a764fFc5c45B9A82cCc97

    BNB chain

    0xAE87E5Fa20f335ce14AA3B9E0616308d9AC7d4Ce

    BNB chain

    0xA5E0E46462970C9Ee8C2ECadcde254c483748Ec4

    Base

    0x6e53131F68a034873b6bFA15502aF094Ef0c5854

    Base

    0xf6C5F01C7F3148891ad0e19DF78743D31E390D1f

    Gnosis

    0x1337BedC9D22ecbe766dF105c9623922A27963EC

    Gnosis

    0x7f90122BF0700F9E7e1F688fe926940E8839F353

    Celo

    0x28F209844029755FC563c1bD4FD21f42DC7CE0e4

    Fraxtal

    0xcAEF324bea3Ff5c7a08710081294F3344fFAdC54

    Fantom

    0x7d04f016749c215e52138b06bb35ee8491e739fd

    Fantom

    0x353bb1dfbc52bc3b0e7d264216b1455df00f50be

    Fantom

    0x5ecac5fb1d9634f9e1c2dab2381b9adaada5f80b

    Fantom

    0x3f833ed02629545dd78afc3d585f7f3918a3de62

    Fantom

    0xa3a63276b8668583e1b47b979d1093d9aaf431ee

    Fantom

    0x15ee0d5f92fd869c2fbf26ea785e9d150353568d

    Fantom

    0x3c2fcf53f742345c5c1b3dcb2612a1949bc1f18d

    Fantom

    0xabba40f628f055149f1c7415c4388363392279c3

    Fantom

    0x37F5dae6039C8eC4c32ad7D3e2a07aCaa55C08f9

    Fantom

    0x06a2e1521afde7f7dc30d351dcf04408042f536e

    Sonic

    0x38dd6b3c096c8cbe649fa0039cc144f333be8e61

    Sonic

    0xf1232a1ab5661abdd6e02c6d8ac9940a23bb0b84

    Sonic

    0x346704605c72d9f5f9f02d651e5a3dcce6964f3d

    Sonic

    0x4fe12cf68147e902f4ccd8a3d4c13e89fba92384

    Sonic

    0xf159c51297306839b7d44cbb5cb9360e4623ae5a

    Sonic

    0xdac15649b025ba0047718512111c34096e9545e8

    Sonic

    0xf821404ac19ac1786caca7e3e12658d72ece885e

    Sonic

    0x440bcab62d629ba60ca56b80e565636e0c404e60

    Sonic

    0xd9bf67d8a5d698a028160f62480d456801f0b4b1

    Sonic

    0x435a160ef111ad0aa0867bece7b85cb77dce3c8a

    Sonic

    0x90135d7300c690d786fa8fea071cd4c2ed080d16

    Sonic

    0x20c2e44bbbea698da4a4cb687514e66385996639

    Sonic

    0xedcf9ef9b389a8f52e81958d8212faf6fbd758ae

    Sonic

    0x6988d6eec3ca7d24c0358bab8018787117325c2b

    Sonic

    0x9e63e5d31fd0136290ef99b3cac4515f346fef1c

    Sonic

    0x2b0911095350785fb32a557d1d2e3b36a9bb9252

    Sonic

    0xaa186960df95495084ef1ddc40a3bdac22b0d343

    Sonic

    0xb7bb92ff0ec68e6d79a238174e42c12ff5ef2b00

    Sonic

    0x024cc841cd7fe4e7dd7253676c688146599923cf

    Sonic

    0x2e97cf8da26ce3858950dd85b8f69e39ebd251f5

    Sonic

    0x24479a0d48849781b4386ed91fdd84241673ab1e

    Sonic

    0x9ccaabd2610d467b1f76c8aacec4f567ec61d78e

    Sonic

    0x424757a5169e1f3b45436c9b2e5421dc39dc4897

    Sonic

    0xa5a5da9c386855b199b8928cbb59c7ac6505ba89

    Sonic

    0x6f6522261f89d988d5f5caa5e4e658344517b114

    Sonic

    0x13882f7f207329db487ce99839c26392a233d97b

    Sonic

    0xeb427d3cc29ec4c49e48fccc580b11f15d7d096d

    Sonic

    0xdbb986d7fef61260c7f9a443e62e8a91974c5e3d

    Sonic

    0xa4948da3f2007193dd7404278fed15d48c617417

    Sonic

    0x8bb9b3e45fa6b4bf4bbb66ad09f485c5509a0e4c

    Sonic

    0x601538c805ea9d83a49c132f18417db9666f69d5

    Sonic

    0x759a32b417bb471da76cf41ca2ea42f4e0b143eb

    Sonic

    0xe5a0813a7de6abd8599594e84cb23e4a6d9d9800

    Sonic

    0x6d9f0ff2b7f1397ee731f6370d8e4699ffad7bc5

    Sonic

    0x1008358eecb59723391fba0f8a6b36c5346dab2d

    Sonic

    0x09679c768d17b52bfa059010475f9a0bdb0d6fea

    Sonic

    0x1c404afffba0e70426dc601aeaa6205eca8c9078

    Sonic

    0x7b823067ece11047f83f48647110e7a777e2bf5a

    Sonic

    0x538a5534543752d5abbc8cd11760f8be3625e7b1

    Sonic

    0xdb0a43327626c0e3e87ce936bc0cdf2ee9475c22

    Sonic

    0x5fa5168497db4ec1964b3208c18cb6157e5652e4

    Sonic

    0x1894a7203faa464f7afa3b8c319a3cac8beb6cda

    Sonic

    0xee05755051e8b1ccf85747a83d0ef8b00f161180

    Sonic

    0x9b78e02ddddda4117ddf6be8a0fbd15c45907895

    Sonic

    0x3301e4326cf2939cd6b8f23ddf7bc2a1713fd06a

    Taiko

    0xB391F2D5B83B3900997B4D6880ba7818Bef3591a

    Ethereum

    rEYWA

    0x70980bD7253f8150dDD973CB430374Adaa0A143F

    Ethereum

    crvUSD

    0xf939e0a03fb07f59a73314e73794be0e57ac1b4e

    Ethereum

    USDC

    0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48

    Ethereum

    USDT

    0xdac17f958d2ee523a2206206994597c13d831ec7

    Ethereum

    DAI

    0x6b175474e89094c44da98b954eedeac495271d0f

    Ethereum

    USD0

    0x73a15fed60bf67631dc6cd7bc5b6e8da8190acf5

    Ethereum

    USD0++

    0x35d8949372d46b7a3d5a56006ae77b215fc69bc0

    Ethereum

    FRAX

    0x853d955acef822db058eb8505911ed77f175b99e

    Ethereum

    USDe

    0x4c9edd5852cd905f086c759e8383e09bff1e68b3

    Ethereum

    sDAI

    0x83f20f44975d03b1b09e64809b757c47f942beea

    Ethereum

    sUSDe

    0x9d39a5de30e57443bff2a8307a4256c8797a3497

    Ethereum

    cUSDO

    0xad55aebc9b8c03fc43cd9f62260391c13c23e7c0

    Ethereum

    USDL

    0xbdc7c08592ee4aa51d06c27ee23d5087d65adbcd

    Ethereum

    deUSD

    0x15700b564ca08d9439c58ca5053166e8317aa138

    Ethereum

    DOLA

    0x865377367054516e17014ccded1e7d814edc9ce4

    Ethereum

    PYUSD

    0x6c3ea9036406852006290770bedfcaba0e23a0e8

    Ethereum

    fxUSD

    0x085780639cc2cacd35e474e71f4d000e2405d8f6

    Ethereum

    GHO

    0x40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f

    Ethereum

    USR

    0x66a1e37c9b0eaddca17d3662d6c05f4decf3e110

    Ethereum

    CRV

    0xD533a949740bb3306d119CC777fa900bA034cd52

    Ethereum

    WBTC

    0x2260fac5e5542a773aa44fbcfedf7c193bc2c599

    Ethereum

    tBTC

    0x18084fbA666a33d37592fA2633fD49a74DD93a88

    Ethereum

    ETH

    native coin

    Ethereum

    WETH

    0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

    Arbitrum

    EYWA

    0x7A10F506E4c7658e6AD15Fdf0443d450B7FA80D7

    Arbitrum

    rEYWA

    0xD9879D9DbDc5042D8f1C2710Be293909B985dc90

    Arbitrum

    crvUSD

    0x498bf2b1e120fed3ad3d42ea2165e9b73f99c1e5

    Arbitrum

    USDC.e

    0xff970a61a04b1ca14834a43f5de4533ebddb5cc8

    Arbitrum

    USDC

    0xaf88d065e77c8cC2239327C5EDb3A432268e5831

    Arbitrum

    USDT

    0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9

    Arbitrum

    USDM

    0x59d9356e565ab3a36dd77763fc0d87feaf85508c

    Arbitrum

    eUSD

    0x12275dcb9048680c4be40942ea4d92c74c63b844

    Arbitrum

    CRV

    0x11cDb42B0EB46D95f990BeDD4695A6e3fA034978

    Arbitrum

    ARB

    0x912CE59144191C1204E64559FE8253a0e49E6548

    Arbitrum

    WBTC

    0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f

    Arbitrum

    tBTC

    0x6c84a8f1c29108F47a79964b5Fe888D4f4D0dE40

    Arbitrum

    IBTC

    0x050C24dBf1eEc17babE5fc585F06116A259CC77A

    Arbitrum

    ETH

    native coin

    Arbitrum

    WETH

    0x82af49447d8a07e3bd95bd0d56f35241523fbab1

    Arbitrum

    UNIT0

    0x21ab704b2cdf792e1e84f591ca082fff8de12198

    Arbitrum

    WUNIT0

    0xe80698d9c55d9212c4dae8bed00e1357d804c62a

    Arbitrum

    OGC

    0x21b1b07af26613479e526c058749239e460f8a2f

    Arbitrum

    xcmGEMS1

    0x432D9C4Cc7021dDcF6e1D2Af4886dd29d7709582

    Optimism

    crvUSD

    0xc52d7f23a2e460248db6ee192cb23dd12bddcbf6

    Optimism

    USDC.e

    0x7F5c764cBc14f9669B88837ca1490cCa17c31607

    Optimism

    USDT

    0x94b008aA00579c1307B0EF2c499aD98a8ce58e58

    Optimism

    DAI

    0xda10009cbd5d07dd0cecc66161fc93d7c9000da1

    Optimism

    CRV

    0x0994206dfe8de6ec6920ff4d779b0d950605fb53

    Optimism

    WBTC

    0x68f180fcCe6836688e9084f035309E29Bf0A2095

    Optimism

    tBTC

    0x6c84a8f1c29108F47a79964b5Fe888D4f4D0dE40

    Optimism

    ETH

    native coin

    Optimism

    WETH

    0x4200000000000000000000000000000000000006

    Optimism

    OGC

    0x21b1b07af26613479e526c058749239e460f8a2f

    Avalanche

    DAI.e

    0xd586e7f844cea2f87f50152665bcbc2c279d8d70

    Avalanche

    USDC.e

    0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664

    Avalanche

    USDT.e

    0xc7198437980c041c805a1edcba50c1ce5db95118

    Avalanche

    avDAI

    0x47afa96cdc9fab46904a55a6ad4bf6660b53c38a

    Avalanche

    avUSDC

    0x46a51127c3ce23fb7ab1de06226147f446e4a857

    Avalanche

    avUSDT

    0x532e6537fea298397212f09a61e03311686f548e

    Avalanche

    USDt

    0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7

    Avalanche

    YUSD

    0x111111111111ed1D73f860F57b2798b683f2d325

    Avalanche

    MIM

    0x130966628846BFd36ff31a822705796e8cb8C18D

    Avalanche

    BTC.b

    0x152b9d0FdC40C096757F570A51E494bd4b943E50

    Avalanche

    WETH.e

    0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB

    Polygon

    crvUSD

    0xc4ce1d6f5d98d65ee25cf85e9f2e9dcfee6cb5d6

    Polygon

    USDC.e

    0x2791bca1f2de4661ed88a30c99a7a9449aa84174

    Polygon

    amUSDC

    0x1a13f4ca1d028320a707d99520abfefca3998b7f

    Polygon

    USDT

    0xc2132d05d31c914a87c6611c10748aeb04b58e8f

    Polygon

    amUSDT

    0x60d55f02a771d515e077c9c2403a1ef324885cec

    Polygon

    DAI

    0x8f3cf7ad23cd3cadbd9735aff958023239c6a063

    Polygon

    amDAI

    0x27f8d03b3a2196956ed754badc28d73be8830a6e

    Polygon

    CRV

    0x172370d5cd63279efa6d502dab29171933a610af

    Polygon

    WBTC

    0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6

    Polygon

    WETH

    0x7ceb23fd6bc0add59e62ac25578270cff1b9f619

    Polygon

    OGC

    0x21b1b07af26613479e526c058749239e460f8a2f

    BSC

    EYWA

    0x7A10F506E4c7658e6AD15Fdf0443d450B7FA80D7

    BSC

    crvUSD

    0xe2fb3f127f5450dee44afe054385d74c392bdef4

    BSC

    FDUSD

    0xc5f0f7b66764F6ec8C8Dff7BA683102295E16409

    BSC

    USDC

    0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d

    BSC

    USDT

    0x55d398326f99059fF775485246999027B3197955

    BSC

    USDX

    0xf3527ef8dE265eAa3716FB312c12847bFBA66Cef

    BSC

    sUSDX

    0x7788A3538C5fc7F9c7C8A74EAC4c898fC8d87d92

    BSC

    BTCB

    0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c

    BSC

    ETH

    0x2170Ed0880ac9A755fd29B2688956BD959F933F8

    BSC

    WUNIT0

    0xe80698d9c55d9212c4dae8bed00e1357d804c62a

    BSC

    OGC

    0x21b1b07af26613479e526c058749239e460f8a2f

    Base

    crvUSD

    0x417Ac0e078398C154EdFadD9Ef675d30Be60Af93

    Base

    scrvUSD

    0x646A737B9B6024e49f5908762B3fF73e65B5160c

    Base

    USDbC

    0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA

    Base

    axlUSDC

    0xEB466342C4d449BC9f53A865D5Cb90586f405215

    Base

    USDC

    0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

    Base

    USDM

    0x59D9356E565Ab3A36dD77763Fc0d87fEaf85508C

    Base

    CRV

    0x8Ee73c484A26e0A5df2Ee2a4960B789967dd0415

    Base

    cbBTC

    0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf

    Base

    ETH

    native coin

    Base

    WETH

    0x4200000000000000000000000000000000000006

    Base

    superOETHb

    0xDBFeFD2e8460a6Ee4955A68582F85708BAEA60A3

    Gnosis

    USDC

    0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83

    Gnosis

    USDT

    0x4ECaBa5870353805a9F068101A40E0f32ed605C6

    Gnosis

    WXDAI

    0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d

    Gnosis

    EURe

    0xcB444e90D8198415266c6a2724b7900fb12FC56E

    Gnosis

    EURC.e

    0x54E4cB2a4Fa0ee46E3d9A98D13Bea119666E09f6

    Gnosis

    CRV

    0x712b3d230f3c1c19db860d80619288b1f0bdd0bd

    Gnosis

    WETH

    0x6a023ccd1ff6f2045c3309768ead9e68f978f6e1

    Gnosis

    WBTC

    0x8e5bbbb09ed1ebde8674cda39a0c169401db4252

    Blast

    USDB

    0x4300000000000000000000000000000000000003

    Blast

    ETH

    native coin

    Blast

    WETH

    0x4300000000000000000000000000000000000004

    Blast

    OGC

    0xf08e269cd00c4713fe880d4c550f779d329b6f48

    Mantle

    USDC

    0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9

    Mantle

    WETH

    0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111

    Mantle

    OGC

    0xf08e269cd00c4713fe880d4c550f779d329b6f48

    Linea

    USDC.e

    0x176211869cA2b568f2A7D4EE941E073a821EE1ff

    Linea

    WBTC

    0x3aab2285ddcddad8edf438c1bab47e1a9d05a9b4

    Linea

    ETH

    native coin

    Linea

    WETH

    0xe5d7c2a44ffddf6b295a15c148167daaaf5cf34f

    Linea

    OGC

    0xf08e269cd00c4713fe880d4c550f779d329b6f48

    Taiko

    crvUSD

    0xc8F4518ed4bAB9a972808a493107926cE8237068

    Taiko

    USDC

    0x07d83526730c7438048D55A4fc0b850e2aaB6f0b

    Taiko

    USDT

    0x2def195713cf4a606b49d07e520e22c17899a736

    Taiko

    ETH

    native coin

    Taiko

    WETH

    0xa51894664a773981c6c112c43ce576f315d5b1b6

    Kava

    USDt

    0x919C1c267BC06a7039e03fcc2eF738525769109c

    Celo

    USDC

    0xceba9300f2b948710d2653dd7b07f33a8b32118c

    Celo

    USD₮

    0x48065fbbe25f71c9282ddf5e1cd6d6a887483d5e

    Celo

    cUSD

    0x765de816845861e75a25fca122bb6898b8b1282a

    Fraxtal

    USDT

    0x4d15ea9c2573addaed814e48c148b5262694646a

    Fraxtal

    CRV

    0x331b9182088e2a7d6d3fe4742aba1fb231aecc56

    Fraxtal

    FRAX

    0xfc00000000000000000000000000000000000001

    Fraxtal

    wfrxETH

    0xfc00000000000000000000000000000000000006

    Metis

    m.USDT

    0xbB06DCA3AE6887fAbF931640f67cab3e3a16F4dC

    Metis

    WETH

    0x420000000000000000000000000000000000000A

    Metis

    OGC

    0xf08e269cd00c4713fe880d4c550f779d329b6f48

    Mode

    USDC

    0xd988097fb8612cc24eeC14542bC03424c656005f

    Mode

    WETH

    0x4200000000000000000000000000000000000006

    Manta

    USDT

    0xf417F5A458eC102B90352F697D6e2Ac3A3d2851f

    Manta

    WETH

    0x0Dc808adcE2099A9F62AA87D9670745AbA741746

    Mantle

    USDC

    0x09bc4e0d864854c6afb6eb9a9cdf58ac190d0df9

    Unit Zero

    UNIT0

    GjwAHMjqWzYR4LgoNy91CxUKAGJN79h2hseZoae4nU8t

    Unit Zero

    WUNIT0

    0xCF43F7703d9B4E8835f977eF364B4014fA7e856E

    Unit Zero

    USDC

    0xEb19000D90f17FFbd3AD9CDB8915D928F4980fD1

    Unit Zero

    USDT

    0xb303d80db8415FD1d3C9FED68A52EEAc9a052671

    Unit Zero

    WETH

    0x1B100DE3F13E3f8Bb2f66FE58c1949c32E71248B

    Unit Zero

    WBTC

    0x9CE808657ba90C65a2700b1cA5D943eC72834B52

    Fantom

    USDC

    0x28a92dde19D9989F39A49905d7C9C2FAc7799bDf

    Fantom

    USDC.e

    0x2F733095B80A04b38b0D10cC884524a3d09b836a

    Fantom

    CRV

    0xE6c259bc0FCE25b71fE95A00361D3878E16232C3

    Fantom

    WFTM

    0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83

    Sonic

    USDC.e

    0x29219dd400f2bf60e5a23d13be72b486d4038894

    Sonic

    USDT

    0x6047828dc181963ba44974801FF68e538dA5eaF9

    Sonic

    scUSD

    0xd3dce716f3ef535c5ff8d041c1a41c3bd89b97ae

    Sonic

    frxUSD

    0x80eede496655fb9047dd39d9f418d5483ed600df

    Sonic

    WETH

    0x50c42dEAcD8Fc9773493ED674b675bE577f2634b

    Sonic

    scETH

    0x3bce5cb273f0f148010bbea2470e7b5df84c7812

    Sonic

    frxETH

    0x43edd7f3831b08fe70b7555ddd373c8bf65a9050

    Sonic

    scBTC

    0xBb30e76d9Bb2CC9631F7fC5Eb8e87B5Aff32bFbd

    Sonic

    stS

    0xe5da20f15420ad15de0fa650600afc998bbe3955

    Sonic

    cmGEMS1

    0x3301e4326cf2939cd6b8f23ddf7bc2a1713fd06a

    Ethereum

    crv3crypto

    0xd51a44d3fae010294c616388b506acda1bfaae46

    Ethereum

    crvUSDUSDC-f

    0x4dece678ceceb27446b35c672dc7d61f30bad69e

    Ethereum

    crvUSDUSDT-f

    0x390f3595bCa2Df7d23783dFd126427CCeb997BF4

    Ethereum

    3Crv

    0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490

    EYWA
    tBTC/WBTC
    3c-crvUSD
    crvUSDC
    crvUSDT
    2CRV
    2BTC-ng
    3UNIT
    EYWA/USDT
    crvUSDBTCETH
    WMATIC/TRICRYPTO
    crvusdusdc
    crvusdusdt
    am3CRV
    CRVTRI-f
    crvUSDBTCETH
    2BTC
    av3CRV
    crvUSDC
    Tricrypto-crvUSD
    crvUSDT
    3CRV
    crvusdUSDC
    crvusdUSDT
    b3pool
    tricrypto
    4poolUSD-f
    x3CRV
    3pool
    Tri-Pool
    FRAX/USDT
    xCRVUSDT
    xCRVUSDC
    x3CRYPTO
    xSTABLE
    xSTABLE2
    xSTABLE3
    xWETH
    xWETH2
    xBTC
    wFTM/USDC
    xCRV
    xfrxUSD
    xfrxETH
    xsEthereum
    xsBSC
    xsAvalanche
    xsPolygon
    xsArbitrum
    xsOptimism
    xsBase
    xsBlast
    xsGnosis
    xsTaiko
    xsMantle
    xsLinea
    xsCelo
    xsMetis
    xsMode
    xsManta
    xsKava
    xeEthereum
    xeArbitrum
    xeOptimism
    xeBase
    xeBlast
    xeMantle
    xeBSC
    xePolygon
    xeAvalanche
    xeGnosis
    xeMetis
    xeMode
    xeLinea
    xeTaiko
    xeManta
    xbEthereum
    xbArbitrum
    xbOptimism
    xbAvalanche
    xbPolygon
    xbBSC
    xbBase
    xbLinea
    xbGnosis
    xcmGEMS1
    USDC/USDT

    Hubchain Pools and Assets

    CrossCurve pools and assets are integrated within the Sonic (previously Fantom) and Arbitrum ecosystems.

    CrossCurve facilitates the swapping of s-tokens within Curve pools on the Sonic (in archive pools also Fantom), Arbitrum and Taiko Hubchains. All liquidity in CrossCurve on Hubchain is composed of s-tokens. These s-tokens are collateralized synthetic assets issued by the CrossCurve Consensus Bridge. Each s-token is fully backed by the original asset to which it is pegged, with these assets securely locked in the CrossCurve Token Bridge on the source blockchain. Audited by SmartState.

    Specialized tokenized assets that facilitate cross-chain trading and yield generation. These s-tokens, typically part of CrossCurve's core stable pools, enable the exchange of similar tokens, thereby creating a unified cross-chain liquidity market. By aggregating liquidity across various blockchains, s-tokens play a pivotal role in streamlining cross-chain operations and enhancing the efficiency of decentralized trading within the Curve-based protocol.

    Each paired pool on the Sonic (or Taiko) Hubchain consists of two tokens:

    • A universal token – an asset from Sonic, uniform across all pools of the same type (e.g., xfrxUSD for USD assets, xfrxETH for ETH, and scBTC for BTC). More details

    To understand the naming convention of s-tokens on CrossCurve, particularly when incorporating a list of supported networks within the name, such as "sUSDT_eth," let's break it down:

    • The prefix "s" typically stands for "synthetic", indicating the type of token.

    For archived pools on , each different body of the name, such as "crvUSDT," specifies the supported pool:

    crvUSDT - xCRVUSDT pool

    crvUSDC - xCRVUSDC pool

    3CRV - xCRVUSDT, xCRVUSDC, xSTABLE pools

    CrossCurve supports the use of both standard assets and LP tokens as collateral for s-tokens. Below, you will find a list of cross-chain pools, the s-tokens they contain, and the assets backing them.

    LP tokens in the CrossCurve ecosystem offer liquidity providers a means to engage with various DeFi platforms across multiple blockchains simultaneously. By providing liquidity, participants receive LP tokens, which represent a claim on their share of the pool's assets and its yield. Holding LP tokens allows providers not only to decide when to withdraw their assets but also to benefit from enhanced returns through cumulative rewards from both Curve and the CrossCurve DAO. Essentially, LP tokens signify ownership of a portion of the liquidity pool, enabling providers to earn returns on their stakes and facilitating cross-chain transactions within the Curve finance ecosystem.

    Sonic pools

    Main pools

    CrossCurve frxUSD

    Pool page:

    Pool/token:

    CrossCurve frxUSD pool assets:

    Universal token
    Source chain

    CrossCurve frxETH

    Pool page:

    Pool/token:

    CrossCurve frxETH pool assets:

    Universal token
    Source chain

    xsStable pools

    Synthetic tokens are categorized into three types:

    • s_Stable_chain, where Stable represents a USD asset variant, and chain is the network where the asset is used.

    CrossCurve Stable ETH

    Pool page: Pool/token: CrossCurve Stable ETH pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable BSC

    Pool page: Pool/token: CrossCurve Stable BSC pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable AVA

    Pool page: Pool/token: CrossCurve Stable AVA pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable POL

    Pool page: Pool/token: CrossCurve Stable POL pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable ARB

    Pool page: Pool/token: CrossCurve Stable ARB pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable OP

    Pool page: Pool/token: CrossCurve Stable OP pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable BASE

    Pool page: Pool/token: CrossCurve Stable BASE pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable BL

    Pool page: Pool/token: CrossCurve Stable BL pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable GNO

    Pool page: Pool/token: CrossCurve Stable GNO pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Curve LP (collateral)
    Pool page
    Source chain

    CrossCurve Stable MTL

    Pool page: Pool/token: CrossCurve Stable MTL pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable LIN

    Pool page: Pool/token: CrossCurve Stable LIN pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable CELO

    Pool page: Pool/token: CrossCurve Stable CELO pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable MET

    Pool page: Pool/token: CrossCurve Stable MET pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable MODE

    Pool page: Pool/token: CrossCurve Stable MODE pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable MTA

    Pool page: Pool/token: CrossCurve Stable MTA pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve Stable KAVA

    Pool page: Pool/token: CrossCurve Stable KAVA pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    xeWETH pools

    Synthetic tokens are categorized into three types:

    • s_WETH_network, where WETH represents ETH backing, and chain is the network where the asset is used.

    Each type of synthetic token corresponds to a pool where it can be paired in an LP token:

    CrossCurve WETH ETH

    Pool page: Pool/token: CrossCurve WETH ETH pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve WETH ARB

    Pool page: Pool/token: CrossCurve WETH ARB pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve WETH OP

    Pool page: Pool/token: CrossCurve WETH OP pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve WETH BASE

    Pool page: Pool/token: CrossCurve WETH BASE pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve WETH BL

    Pool page: Pool/token: CrossCurve WETH BL pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve WETH MTL

    Pool page: Pool/token: CrossCurve WETH MTL pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve ETH BSC

    Pool page: Pool/token: CrossCurve WETH BSC pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve WETH POL

    Pool page: Pool/token: CrossCurve WETH POL pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve WETH AVA

    Pool page: Pool/token: CrossCurve WETH AVA pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve WETH GNO

    Pool page: Pool/token: CrossCurve WETH GNO pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve WETH MET

    Pool page: Pool/token: CrossCurve WETH MET pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve WETH MODE

    Pool page: Pool/token: CrossCurve WETH MODE pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve WETH LIN

    Pool page: Pool/token: CrossCurve WETH LIN pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve WETH MTA

    Pool page: Pool/token: CrossCurve WETH MTA pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    xbBTC

    Synthetic tokens are categorized into three types:

    • s_WBTC_network, where WBTC represents BTC backing, and chain is the network where the asset is used.

    Each type of synthetic token corresponds to a pool where it can be paired in an LP token:

    CrossCurve BTC ETH

    Pool page: Pool/token: CrossCurve BTC ETH pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve BTC ARB

    Pool page: Pool/token: CrossCurve BTC ARB pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve BTC OP

    Pool page: Pool/token: CrossCurve BTC OP pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve BTC AVA

    Pool page: Pool/token: CrossCurve BTC AVA pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve BTC POL

    Pool page: Pool/token: CrossCurve BTC POL pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve BTC BSC

    Pool page: Pool/token: CrossCurve BTC BSC pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve BTC BASE

    Pool page: Pool/token: CrossCurve BTC BASE pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve BTC LIN

    Pool page: Pool/token: CrossCurve BTC LIN pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    CrossCurve BTC GNO

    Pool page: Pool/token: CrossCurve BTC GNO pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    xToken pools

    CrossCurve xCRV pool

    Pool page:

    Pool/token:

    CrossCurve xCRV pool assets:

    S-token
    Curve LP (collateral)
    Pool page
    Token
    Source chain

    CrossCurve CRV 2 pool

    Pool page:

    Pool/token:

    CrossCurve xCRV2 pool assets:

    S-token
    Curve LP (collateral)
    Pool page
    Token
    Source chain

    CrossCurve CRV/USD pool

    Pool page:

    Pool/token:

    CrossCurve CRV/USD pool assets:

    S-token
    Curve LP (collateral)
    Pool page
    Token
    Source chain

    CrossCurve cmGEMS1

    Pool page:

    Pool/token:

    CrossCurve cmGEMS1 pool assets:

    Token
    Source chain

    Outdated pools

    CrossCurve Stable TAI

    Pool page: Pool/token: CrossCurve Stable TAI pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Curve LP (collateral)
    Pool page
    Source chain

    CrossCurve WETH TAI

    Pool page: Pool/token: CrossCurve WETH TAI pool assets:

    Universal token
    Synthetic derivative
    S-token collateral
    Source chain

    Arbitrum pools

    CrossCurve EYWAUSDT pool

    Pool page:

    Pool/token:

    CrossCurve EYWAUSDT pool assets:

    Token
    Source chain

    UNIT0/WUNIT0 pool

    Pool page:

    Pool/token:

    UNIT0/WUNIT0 pool assets:

    S-token
    Token
    Source chain

    3UNIT0 pool

    Pool page:

    Pool/token:

    3UNIT0 pool assets:

    S-token
    Token
    Source chain

    Taiko pools

    CrossCurve Stable pool

    Pool page:

    Pool/token:

    CrossCurve Stable pool assets:

    CrossCurve WETH pool

    Pool page:

    Pool/token:

    CrossCurve Stable pool assets:

    Fantom pools

    xToken pools

    CrossCurve wFTM/USDC pool

    Pool page:

    Pool/token:

    Token
    Source chain

    Outdated pools

    xSTABLE pools

    CrossCurve xSTABLE pool (old)

    Pool page:

    Pool/token:

    CrossCurve xSTABLE pool assets:

    S-token
    Curve LP (collateral)
    Pool contract
    Pool page
    Source chain

    CrossCurve xSTABLE2 pool (old)

    Pool page:

    Pool/token:

    CrossCurve xSTABLE2 pool assets:

    S-token
    Curve LP (collateral)
    Pool page
    Token
    Source chain

    CrossCurve xSTABLE3 pool (old)

    Pool page:

    Pool/token:

    CrossCurve xSTABLE3 pool assets:

    S-token
    Curve LP (collateral)
    Pool page
    Token
    Source chain

    xWETH pools

    CrossCurve xWETH pool (old)

    Pool page:

    Pool/token:

    CrossCurve xWETH pool assets:

    S-token
    Token
    Source chain

    CrossCurve xWETH2 pool (old)

    Pool page:

    Pool/token:

    CrossCurve xWETH2 pool assets:

    S-token
    Token
    Source chain

    xBTC pools

    CrossCurve xBTC pool (old)

    Pool page:

    Pool/token:

    CrossCurve xBTC pool assets:

    S-Token
    Curve LP (collateral)
    Pool page
    Token
    Source chain

    xToken pools

    CrossCurve 3crypto pool (old)

    Pool page:

    Pool/token :

    CrossCurve 3crypto pool assets:

    S-token
    Curve LP (collateral)
    Pool contract
    Pool page
    Source chain

    CrossCurve crvUSDC pool (old)

    Pool page:

    Pool/token :

    CrossCurve crvUSDC pool assets:

    S-token
    Curve LP (collateral)
    Pool contact
    Pool page
    Source chain

    CrossCurve crvUSDT pool (old)

    Pool page:

    Pool/token :

    CrossCurve crvUSDT pool assets:

    S-token
    Curve LP (collateral)
    Pool contract
    Pool page
    Source chain
    .
  • A synthetic derivative (s-token), backed by the original asset locked in the Consensus Bridge. These can be either single assets or LP tokens from Curve.

  • Synthetic tokens are categorized into three types:

    • s_Stable_chain, where Stable represents a USD asset variant, and chain is the network where the asset is used.

    • s_WETH_network, where WETH represents ETH backing, and chain is the network where the asset is used.

    • s_WBTC_network, where WBTC represents BTC backing, and chain is the network where the asset is used.

    Each type of synthetic token corresponds to a pool where it can be paired in an LP token:

    • xs_chain, where xs is a stable pool, and chain is the network where the asset is used.

    • xe_chain, where xe is a volatile pool, and chain is the network where the asset is used.

    • xb_chain, where xb is a volatile pool, and chain is the network where the asset is used.

    The main body of the name, such as "USDT" specifies the underlying asset. Here, "USDT" indicates that the token is related to CrossCurve Stable pools.
  • The suffix after an underscore, such as "eth," represents the network on which the token operates. For instance, "eth" might denote the Ethereum network.

  • In this naming structure, "sUSDT_eth" would represent a synthetic version of the CrossCurve s-token operating on the Ethereum network, to work with the liquidity in the CrossCurve Stable ETH pool.

    Each different suffix corresponds to other supported networks, providing a quick reference to the cross-chain capabilities of the s-token within the CrossCurve platform:

    eth - Ethereum network

    arb - Arbitrum network

    op - Optimism network

    av - Avalanche network

    p - Polygon network

    b - Binance Smart Chain network

    ba - Base network

    g - Gnosis network

    m - Mantle network

    me - Metis network

    mo - Mode network

    ma - Manta network

    bl - Blast network

    l - Linea network

    c - Celo network

    ka - Kava nework

    3crypto - x3CRYPTO pool

    2CRV, 3Pool, 4Pool - xSTABLE pool

    USDC, USDT, USDB, USDCe, 3pool, FrUsdt, USDt - xSTABLE2, xSTABLE3 pools

    WETH - xWETH, xWETH2 pools

    ETH, wfrxETH - xWETH2 pool

    2BTC, BTC.b, WBTC, BTCB, cbBTC - xBTC pool

    CRV, CRVTRI - xCRV pool

    Each type of synthetic token corresponds to a pool where it can be paired in an LP token:
    • xs_chain, where xs is a stable pool, and chain is the network where the asset is used.

    Ethereum

    BSC

    Avalanche

    Polygon

    Arbitrum

    Optimism

    Base

    Blast

    Sonic

    Gnosis

    Gnosis

    Gnosis

    Gnosis

    Mantle

    Linea

    Celo

    Metis

    Mode

    Manta

    Kava

  • xe_chain, where xe is a volatile pool, and chain is the network where the asset is used.

  • Ethereum

    Arbitrum

    Optimism

    Base

    Blast

    Mantle

    BSC

    Polygon

    Avalanche

    Gnosis

    Metis

    Mode

    Linea

    Manta

  • xb_chain, where xb is a volatile pool, and chain is the network where the asset is used.

  • Ethereum

    Arbitrum

    Optimism

    Avalanche

    Polygon

    BSC

    Base

    Linea

    Gnosis

    Base

    Optimism

    Polygon

    Gnosis

    Fraxtal

    Fantom

    Sonic

    Sonic

    Taiko

    Taiko

    Taiko

    Taiko

    Optimism

    Avalanche

    Polygon

    BSC

    Base

    Gnosis

    Blast

    Linea

    Taiko

    Celo

    Fraxtal

    Kava

    Metis

    Mode

    Fantom

    Fantom

    Manta

    Sonic

    Mantle

    Blast

    Linea

    Taiko

    Gnosis

    Metis

    Mode

    Optimism

    Avalanche

    Polygon

    BSC

    Base

    Linea

    Avalanche

    Polygon

    Optimism

    Polygon

    BNB chain

    (3pool)

    Avalanche

    Optimism

    Polygon

    BNB chain

    Avalanche

    scUSD

    Sonic

    frxUSD

    Sonic

    scETH

    Sonic

    frxETH

    Sonic

    xfrxUSD

    Sonic

    sUSDT_eth

    Sonic

    xfrxUSD

    Sonic

    sUSDT_b

    Sonic

    xfrxUSD

    Sonic

    sUSDt_av

    Sonic

    xfrxUSD

    Sonic

    sUSDT_p

    Sonic

    xfrxUSD

    Sonic

    sUSDC_arb

    Sonic

    xfrxUSD

    Sonic

    sUSDT_op

    Sonic

    xfrxUSD

    Sonic

    sUSDC_ba

    Sonic

    xfrxUSD

    Sonic

    sUSDB_bl

    Sonic

    xfrxUSD

    Sonic

    sx3CRV_g

    xfrxUSD

    Sonic

    sUSDC_m

    Sonic

    xfrxUSD

    Sonic

    sUSDC_l

    Sonic

    xfrxUSD

    Sonic

    sUSDT_ce

    Sonic

    xfrxUSD

    Sonic

    sm.USDT_me

    Sonic

    xfrxUSD

    Sonic

    sUSDC_mo

    Sonic

    xfrxUSD

    Sonic

    sUSDT_ma

    Sonic

    xfrxUSD

    Sonic

    sUSDt_ka

    Sonic

    xfrxETH

    Sonic

    sWETH_e

    Sonic

    xfrxETH

    Sonic

    sWETH_ar

    Sonic

    xfrxETH

    Sonic

    sWETH_op

    Sonic

    xfrxETH

    Sonic

    sWETH_ba

    Sonic

    xfrxETH

    Sonic

    sWETH_bl

    Sonic

    xfrxETH

    Sonic

    sWETH_m

    Sonic

    xfrxETH

    Sonic

    sETH_b

    Sonic

    xfrxETH

    Sonic

    sWETH_p

    Sonic

    xfrxETH

    Sonic

    sWETH.e_av

    Sonic

    xfrxETH

    Sonic

    sWETH_g

    Sonic

    xfrxETH

    Sonic

    sWETH_me

    Sonic

    xfrxETH

    Sonic

    sWETH_mo

    Sonic

    xfrxETH

    Sonic

    sWETH_l

    Sonic

    xfrxETH

    Sonic

    sWETH_ma

    Sonic

    scBTC

    Sonic

    sWBTC_e

    Sonic

    scBTC

    Sonic

    sWBTC_ar

    Sonic

    scBTC

    Sonic

    sWBTC_op

    Sonic

    scBTC

    Sonic

    sBTC.b_av

    Sonic

    scBTC

    Sonic

    sWBTC_p

    Sonic

    scBTC

    Sonic

    sBTCB_b

    Sonic

    scBTC

    Sonic

    scbBTC_ba

    Sonic

    scBTC

    Sonic

    sWBTC_l

    Sonic

    scBTC

    Sonic

    sWBTC_g

    Sonic

    sCRV_e

    CRV

    Ethereum

    sCRV_ar

    CRV

    Arbitrum

    xCRV

    CrossCurve CRV

    Sonic

    sCRV_t

    CRV

    Taiko

    xCRV2

    CrossCurve CRV 2

    Sonic

    xfrxUSD

    CrossCurve frxUSD

    Sonic

    stS

    Sonic

    cmGEMS1

    Sonic

    xfrxUSD

    Sonic

    s2Pool_t

    xfrxETH

    Sonic

    sWETH_t

    Sonic

    EYWA

    Arbitrum

    USD₮0

    Arbitrum

    synth - Ethereum UNIT0

    UNIT0

    Arbitrum

    synth - Units WUNIT0

    WUNIT0

    Arbitrum

    synth - Units WUNIT0

    WUNIT0

    Arbitrum

    WETH

    WETH

    Arbitrum

    s2CRV_ar

    2CRV

    Arbitrum

    sxfrxUSD_s

    Taiko

    USDC

    Taiko

    Token

    Source chain

    sxfrxETH_s

    Taiko

    WETH

    Taiko

    USDC

    Fantom

    WFTM

    Fantom

    s3CRV_e

    3Crv

    3Pool

    3Pool

    Ethereum

    s2CRV_ar

    2CRV

    2Pool

    2Pool

    Arbitrum

    xSTABLE

    xSTABLE

    Fantom

    sUSDC_m

    USDC

    Mantle

    xSTABLE

    xSTABLE

    Fantom

    xSTABLE2

    xSTABLE2

    Fantom

    sWETH_e

    WETH

    Ethereum

    sWETH_ar

    WETH

    Arbitrum

    sWETH_o

    WETH

    Optimism

    sWETH_ba

    WETH

    Base

    sWETH.e_av

    WETH.e

    Avalanche

    sWETH_p

    WETH

    Polygon

    sETH_b

    ETH

    BSC

    swfrxETH_f

    wfrxETH

    Fraxtal

    s2BTC_e

    tBTC/WBTC

    tBTC/WBTC

    Ethereum

    s2BTC_ar

    2BTC-ng

    2BTC-ng

    Arbitrum

    s3crypto_e

    crv3crypto

    tricrypto2

    tricrypto2

    Ethereum

    s3crypto_ar

    3c-crvUSD

    3c-crvUSD

    Tricrypto-crvUSD

    Arbitrum

    scrvUSDC_e

    crvUSDUSDC-f

    crvUSD/USDC

    crvUSD/USDC

    Ethereum

    scrvUSDC_ar

    crvUSDC

    crvUSD/USDC

    crvUSD/USDC

    Arbitrum

    scrvUSDT_e

    crvUSDUSDT-f

    crvUSD/USDT

    crvUSD/USDT

    Ethereum

    scrvUSDT_ar

    crvUSDT

    crvUSD/USDT

    crvUSD/USDT

    Arbitrum

    Fantom
    https://curve.finance/dex/sonic/pools/factory-stable-ng-25/deposit/
    xfrxUSD
    https://curve.finance/dex/sonic/pools/factory-stable-ng-26/deposit/
    xfrxETH
    https://curve.finance/dex/#/sonic/pools/factory-stable-ng-2/deposit
    xsEthereum
    https://curve.finance/dex/sonic/pools/factory-stable-ng-70/deposit/
    xsBSC
    https://curve.finance/dex/sonic/pools/factory-stable-ng-71/deposit/
    xsAva
    https://curve.finance/dex/sonic/pools/factory-stable-ng-72/deposit/
    xsPolygon
    https://curve.finance/dex/sonic/pools/factory-stable-ng-73/deposit/
    xsArbitrum
    https://curve.finance/dex/sonic/pools/factory-stable-ng-74/deposit/
    xsOptimism
    https://curve.finance/dex/sonic/pools/factory-stable-ng-75/deposit/
    xsBase
    https://curve.finance/dex/sonic/pools/factory-stable-ng-76/deposit/
    xsBlast
    https://curve.finance/dex/sonic/pools/factory-stable-ng-77/deposit/
    xsGnosis
    https://curve.finance/dex/sonic/pools/factory-stable-ng-79/deposit/
    xsMantle
    https://curve.finance/dex/sonic/pools/factory-stable-ng-80/deposit/
    xsLinea
    https://curve.finance/dex/sonic/pools/factory-stable-ng-81/deposit/
    xsCelo
    https://curve.finance/dex/sonic/pools/factory-stable-ng-82/deposit/
    xsMetis
    https://curve.finance/dex/sonic/pools/factory-stable-ng-83/deposit/
    xsMode
    https://curve.finance/dex/sonic/pools/factory-stable-ng-84/deposit/
    xsManta
    https://curve.finance/dex/sonic/pools/factory-stable-ng-85/deposit/
    xsKava
    https://curve.finance/dex/sonic/pools/factory-stable-ng-86/deposit/
    xeEthereum
    https://curve.finance/dex/sonic/pools/factory-stable-ng-87/deposit/
    xeArbitrum
    https://curve.finance/dex/sonic/pools/factory-stable-ng-88/deposit/
    xeOptimism
    https://curve.finance/dex/sonic/pools/factory-stable-ng-89/deposit/
    xeBase
    https://curve.finance/dex/sonic/pools/factory-stable-ng-90/deposit/
    xeBlast
    https://curve.finance/dex/sonic/pools/factory-stable-ng-91/deposit/
    xeMantle
    https://curve.finance/dex/sonic/pools/factory-stable-ng-92/deposit/
    xeBSC
    https://curve.finance/dex/sonic/pools/factory-stable-ng-93/deposit/
    xePolygon
    https://curve.finance/dex/sonic/pools/factory-stable-ng-94/deposit/
    xeAva
    https://curve.finance/dex/sonic/pools/factory-stable-ng-95/deposit/
    xeGnosis
    https://curve.finance/dex/sonic/pools/factory-stable-ng-96/deposit/
    xeMetis
    https://curve.finance/dex/sonic/pools/factory-stable-ng-97/deposit/
    xeMode
    https://curve.finance/dex/sonic/pools/factory-stable-ng-98/deposit/
    xeLinea
    https://curve.finance/dex/sonic/pools/factory-stable-ng-100/deposit/
    xeManta
    https://curve.finance/dex/sonic/pools/factory-stable-ng-60/deposit/
    xbEthereum
    https://curve.finance/dex/sonic/pools/factory-stable-ng-61/deposit/
    xbArbitrum
    https://curve.finance/dex/sonic/pools/factory-stable-ng-62/deposit/
    xbOptimism
    https://curve.finance/dex/sonic/pools/factory-stable-ng-63/deposit/
    xbAva
    https://curve.finance/dex/sonic/pools/factory-stable-ng-64/deposit/
    xbPolygon
    https://curve.finance/#/sonic/pools/factory-stable-ng-65/deposit
    xbBSC
    https://curve.finance/dex/sonic/pools/factory-stable-ng-66/deposit/
    xbBase
    https://curve.finance/dex/sonic/pools/factory-stable-ng-67/deposit/
    xbLinea
    https://curve.finance/dex/sonic/pools/factory-stable-ng-68/deposit/
    xbGnosis
    https://curve.finance/dex/#/sonic/pools/factory-stable-ng-2/deposit
    xCRV
    https://www.curve.finance/dex/sonic/pools/factory-stable-ng-106/deposit/
    xCRV2
    https://www.curve.finance/dex/sonic/pools/factory-twocrypto-29/deposit/
    CRV/USD
    https://curve.finance/dex/sonic/pools/factory-twocrypto-22/deposit/
    xcmGEMS1
    https://curve.finance/dex/sonic/pools/factory-stable-ng-78/deposit/
    xsTaiko
    https://curve.finance/dex/sonic/pools/factory-stable-ng-99/deposit/
    xeTaiko
    https://curve.finance/dex/arbitrum/pools/factory-twocrypto-57/deposit/
    EYWAUSDT
    https://curve.finance/#/arbitrum/pools/factory-stable-ng-109/deposit
    UNIT0/WUNIT0
    https://curve.finance/#/arbitrum/pools/factory-tricrypto-38/deposit
    3UNIT0
    https://www.curve.finance/dex/taiko/pools/factory-stable-ng-5/deposit/
    xsoTaiko
    https://www.curve.finance/dex/taiko/pools/factory-stable-ng-6/deposit/
    xeoTaiko
    https://curve.finance/dex/fantom/pools/factory-twocrypto-53/deposit/
    wFTM/USDC
    https://curve.finance/#/fantom/pools/factory-stable-ng-24/deposit
    xSTABLE
    https://curve.finance/#/fantom/pools/factory-stable-ng-43/deposit
    xSTABLE2
    https://curve.finance/#/fantom/pools/factory-stable-ng-54/deposit
    xSTABLE3
    https://curve.finance/#/fantom/pools/factory-stable-ng-37/deposit
    xWETH
    https://curve.finance/#/fantom/pools/factory-stable-ng-49/deposit
    xWETH2
    https://curve.finance/#/fantom/pools/factory-stable-ng-39/deposit
    xBTC
    https://curve.finance/#/fantom/pools/factory-stable-ng-17/deposit
    x3CRYPTO
    https://curve.finance/#/fantom/pools/factory-stable-ng-16/deposit
    xCRVUSDC
    https://curve.finance/#/fantom/pools/factory-stable-ng-20/deposit
    xCRVUSDT

    here
    USDT
    USDT
    USDt
    USDT
    USDC
    USDT
    USDC
    USDB
    WXDAI
    USDC
    USDT
    3pool
    3Pool
    USDC
    USDC
    USD₮
    m.USDT
    USDC
    USDT
    USDt
    WETH
    WETH
    WETH
    WETH
    WETH
    WETH
    ETH
    WETH
    WETH.e
    WETH
    WETH
    WETH
    WETH
    WETH
    WBTC
    WBTC
    WBTC
    BTC.b
    WBTC
    BTCB
    cbBTC
    WBTC
    WBTC
    sCRV_ba
    CRV
    sCRV_o
    CRV
    sCRV_p
    CRVTRI-f
    CRV/TRICRYPTO
    CRV
    sCRV_g
    CRV
    sCRV_fr
    CRV
    sCRV_ft
    CRV
    CRV
    USDC
    USDT
    USDC/USDT
    USDC/USDT
    WETH
    s3CRV_o
    3CRV
    3Pool
    3Pool
    sav3CRV_av
    av3CRV
    aave
    aave
    sam3CRV_p
    am3CRV
    aave
    aave
    sb3pool_b
    b3pool
    b3pool
    b3pool
    s4pool_ba
    4poolUSD-f
    4pool
    4Pool
    sx3CRV_g
    x3CRV
    3Pool
    3Pool
    sUSDB_bl
    USDB
    sUSDCe_l
    USDC.e
    sUSDC_t
    USDC
    s3Pool_c
    Tri-Pool
    Tri-Pool
    sFrUsdt_t
    FRAX/USDT
    FRAX/USDT
    sUSDt_t
    USDt
    sm.USDT_me
    m.USDT
    sUSDC_mo
    USDC
    USDC.e
    USDC
    sUSDT_ma
    USDT
    sUSDC.e_s
    USDC.e
    sWETH_m
    WETH
    sWETH_bl
    WETH
    sWETH_l
    WETH
    sWETH_t
    WETH
    sWETH_gn
    WETH
    sWETH_me
    WETH
    sWETH_mo
    WETH
    s2BTC_o
    2BTC
    2BTC
    sBTC.b_av
    BTC.b
    sWBTC_p
    WBTC
    sBTCB_b
    BTCB
    scbBTC_ba
    cbBTC
    sWBTC_l
    WBTC
    s3crypto_av
    crvUSDBTCETH
    atricrypto
    atricrypto
    s3crypto_p
    crvUSDBTCETH
    atricrypto3
    atricrypto3
    scrvUSDC_o
    crvUSDC
    crvUSD/USDC
    crvUSD/USDC
    scrvUSDC_p
    crvusdusdc
    crvUSD/USDC
    crvUSD/USDC
    scrvUSDC_b
    crvusdUSDC
    crvUSD/USDC
    crvUSD/USDC
    sav3CRV_av
    av3CRV
    aave
    aave
    scrvUSDT_o
    crvUSDT
    crvUSD/USDT
    crvUSD/USDT
    scrvUSDT_p
    crvusdusdt
    crvUSD/USDT
    crvUSD/USDT
    scrvUSDT_b
    crvusdUSDT
    crvUSD/USDT
    crvUSD/USDT
    sav3CRV_av
    av3CRV
    aave
    aave