# Fly

Explore fly trade's comprehensive documentation covering DeFi concepts, wallet integration, smart contracts, and developer tools for seamless cross-chain swaps.

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

The world of blockchain technology continues to rapidly evolve and spread to more blockchains, we believe that interoperability between blockchains is vital for the growth and development of the DeFi ecosystem. As such, fly.trade can serve as a powerful tool, my acting as the execution and infra layer for DEXs, LSTs, and chains, facilitating swaps and enabling seamless integration between blockchains.

### Fly connects

fly.trade serves as a flightpath for the flock of traders, introducing them to multiple blockchain networks and their corresponding protocols and features.

### Fly leverages

Fly harnesses the liquidity from existing DEXs and bridge liquidity pools, both within chain and cross-chain.

This greatly reduces fragmentation and maximizes liquidity usage, resulting in improved market depth, cost-efficiency, reduced slippage, and better pricing on assets. The more liquidity networks we aggregate, the better our order router becomes. We're able to find the best deal on assets in real time, while ensuring that liquidity providers on these protocols continue to benefit.

### Fly integrates

The integration of multiple protocols through Fly brings together the strengths of each, creating a more user-friendly and robust DeFi experience.

For cross-chain, Fly streamlines the process by using bridges and their messaging layers so users can trade assets cross-chain seamlessly, unlocking a broader range of investment or trading opportunities, without the need to use stablecoins or native assets.

For on-chain, Fly's advanced aggregation and routing algorithm ensures that all users are getting the best prices available in DeFi.

### Fly unifies

These all represent a significant step towards realizing the full potential of DeFi's growth and a multichain future. By connecting users to new blockchains, leveraging liquidity networks, and integrating different blockchain protocols, we pave the way for increased collaboration, innovation, and seamless, user-friendly transactions across all blockchains.

As the DeFi landscape continues to evolve, Fly will be here to be sure to create a more interconnected, efficient, and user-focused DeFi.


# What is Fly solving?

Explore the challenges in DeFi that fly trade addresses, including liquidity fragmentation, slippage, and user experience enhancements.

## Complexity and Fragmentation

Most of the liquidity not on Ethereum in DeFi is spread across over 50 chains and hundreds of DEXs. As a result, DeFi remains fragmented, each with their own interfaces, DEXs, liquidity pools, unique features, and in some cases different wallet requirements. This creates a steep learning curve, especially for new users or those unfamiliar with multi-chain environments, resulting in a complicated and often frustrating user experience where it becomes difficult to both find the token you need or the DEX with the best price and liquidity.

## Slippage and Inefficient Liquidity

With liquidity scattered across chains, users can often encounter significant slippage, high transaction costs, and sub-optimal execution prices during swaps. Identifying the most efficient liquidity paths can be time-consuming and inefficient, further impacting trade outcomes.

## Poor User Experience

Many current DeFi platforms often fall short in delivering a seamless on or cross-chain experience, from unintuitive interfaces to linking users to upwards of 15-20 other protocol options to assist in their transactions, creating complex transaction flows, which leads to friction, frustration, and ultimately, abandonment of platforms.

## Gas Fee Optimization

Gas fees can start to become burdensome when conducting cross-chain transactions, or even when conducting multiple same-chain swaps, particularly when inefficient routing leads to suboptimal trade execution. This is a barrier to DeFi adoption, especially for users who frequently perform cross-chain activities.


# What is DeFi?

Explore the challenges in DeFi that fly trade addresses, including liquidity fragmentation, slippage, and user experience enhancements.

DeFi, or decentralized finance, is an open and permissionless financial ecosystem built on blockchain technology and smart contracts with the goal of enabling users to access financial services like trading, lending, borrowing, and yield generation, all without relying on traditional intermediaries like banks, financial advisors, and brokers.

By leveraging smart contracts and decentralized protocols, DeFi is able to offer greater transparency, composability, and global accessibility, allowing anyone with an internet connection to participate in a truly borderless financial system.

DeFi is the future of finance, and fly is here to help bring it to everyone.

## Core Components of DeFi

### Bridges

Primarily, a bridge for cryptocurrency provides a way to transfer a token between two different blockchains without the need for a third-party intermediary.

A smart contract is used to create a two-way peg between two different chains by locking up or burning (destroying) a token on one blockchain in exchange for an equivalent amount of the same token or asset on the other blockchain. This is done so that the amount of said asset or token does not change, and the user can freely transfer assets between the two blockchains without the need for a third party.

Once the token is bridged/transferred to the new chain, it can be used just like any other token: to swap, provide liquidity, farm, etc.

### DEXs

A DEX is a decentralized exchange. They are blockchain-based trading platforms that allows users to trade cryptocurrencies directly with one another, generally through an automated-market maker or order book, without the need for a central authority or intermediary. Users retain full control of their assets at all times as trades are executed directly from their wallets, giving users privacy and reducing risk.

### Liquidity Aggregation

Liquidity aggregation automated the process of searching multiple DEXs simultaneously so users could get better rates and execute trades accordingly. Additionally, they provided users with governance tokens and incentivized liquidity providers, which helps to foster a growing DeFi community. Without liquidity aggregation, users have to pour through hundreds of protocols to find the tokens and liquidity needed to make their swaps.


# Fly key features

Uncover fly trade’s core features, such as advanced liquidity aggregation, cross-chain capabilities, and infrastructure support for DEXs.

fly is not just focused on providing an efficient swapping experience; it aims to bring several additional innovations to the DEX world:

1. **Advanced Liquidity Aggregation**
   * fly’s unique aggregation and order routing algorithm is built to scale without reliance on third-party aggregators. This allows Fly to deliver superior price quotes, lower gas fees, and scalability in both on-chain and cross-chain environments.
2. **Infra for DEX, LSTs, chains, and protocols**
   * fly makes it easy for everyone to deposit into LSTs, LRTs, and LP tokens with a single click, using any token, even cross-chain. It makes staking and liquidity deposits effortless, and offers an API so other protocols are able to offer the best pricing and swap features to their community of users as well.
3. **Gas Fee Optimization**:
   * fly incorporates mechanisms to minimize gas fees for users. By optimizing the transaction pathways and utilizing the most efficient routes, fly ensures that users save on transaction costs, making DeFi more accessible and affordable.
4. **Chain Abstraction**
   * fly enhances the cross-chain experience by abstracting the complexities of managing multiple chains, balances, and technical details. With a simplified user interface, users can seamlessly swap assets across different chains without the need to interact with multiple blockchains directly, making the process more intuitive and accessible.&#x20;
   * fly is working towards universal aggregation and smart wallet support to create an even better chain abstracted experience.
5. **User-Centric Design**
   * fly has created a seamless and intuitive user experience.
   * One app, one page, one interface: incredibly easy-to-use. We do all of the research and work for you, just choose which blockchain you're on, which one you want to go to, any two assets you want to swap, and we'll do the rest.
6. **AI x Crypto Execution Layer**
   * In DeFAI, users will want access to the latest and greatest that DeFi has to offer, and between our algorithm and API, DeFAI protocols will be able to support everything from executing on- or cross-chain swaps, managing liquidity positions, joining yield farms, buying LSTs, RWAs, minting yield-bearing stablecoins, and much more.
   * With our scalable, low-latency, non-custodial, and cost-efficient infrastructure, fly is the perfect execution layer and key to unlocking the full potential of DeFAI.

With these innovations, fly aims to set new standards in the DEX ecosystem, providing users with unparalleled efficiency, security, and flexibility in their DeFi activities. 🚀


# Use Cases

Delve into practical applications of fly trade, showcasing how users leverage the platform for efficient and secure DeFi transactions.

Cross-chain Swaps

<mark style="color:red;">Without</mark> Fly<mark style="color:red;">:</mark> Users would need to find a DEX to buy and sell the token they wish to on two different chains as well needing to bridge the appropriate gas token to the new chain to make multiple swaps once bridged over. This could result in 2 swaps and 2 needs to bridge: swap into native gas token for destination chain, bridge native gas over to chain, bridge token you want to swap to destination chain, swap for needed token.

<mark style="color:blue;">With</mark> Fly<mark style="color:blue;">:</mark> Swap almost any token across many of the top chains, all in one interface, without the need to use bridges or go to multiple websites, while getting an amazing price due to fly's unique order routing algorithm. Just as easy as swapping on-chain, just approve and click swap and you're done.

### **On-chain Swaps**

<mark style="color:red;">Without</mark> Fly<mark style="color:red;">:</mark> Users need to search multiple DEXs across the blockchain in which they want to swap, searching for the best liquidity source and price.

<mark style="color:blue;">With</mark> Fly<mark style="color:blue;">:</mark> Swap almost any token on-chain while also benefiting from Fly's order routing algorithm to receive the best price price across all major DEXs. Fly will even pull liquidity from multiple DEXs if it gets the user a better price.

### **Cross-chain Yield farming / Lending & Borrowing / NFT purchases**

<mark style="color:red;">Without</mark> Fly<mark style="color:red;">:</mark> Users need to search yield-farming opportunities, going through the same process as cross-chain swaps to make multiple swaps as well as needing to use a bridge multiple times, costing them a lot of time and gas.

<mark style="color:blue;">With</mark> Fly<mark style="color:blue;">:</mark>&#x20;

**Yield-farming:** In a future update, users will be able to join yield-farming opportunities on or cross-chain through the Fly interface, in just a couple of clicks, saving users time and gas fees.

**Lending & Borrowing:** Users will eventually be able to borrow or lend from markets such as AAVE & Compound, all within Fly's easy-to-use interface.

**Cross-chain NFT markets:** Planned for a future update, users will be able to browse NFT marketplaces, and purchase the NFT they want, using any token they want, through Fly's interface.

### Wallet Apps & DEXs

* By abstracting away the complexity of DeFi & order routing, Fly enables wallet providers, DEXs, or other dApps to enable cross-chain staking, trading, and lending through the Fly interface.

### Institutions & Professional Traders

* Fly provides a low-latency and capital efficient infrastructure that is optimal for professional market makers and traders to deploy their automated strategies.

### NFT Marketplaces

* Connect with the Fly API to allow users to buy NFTs with any digital asset across any of the connected blockchains with just a few clicks.

### Web3 Projects

* With Fly, other projects can tap into other blockchains and ecosystems, both multi-chain and single-chain, by enabling one-click lending, staking, yield farming, and more!


# FAQ

Frequently Asked Questions

### Visit to our Help Center for more FAQ and knowledge hub. <https://support.magpiefi.xyz/hc/en-us>


# Supported Networks

This document describes the networks supported by the Magpie protocol 🚀

<div><figure><img src="/files/jenq0a8xQ2l9oYZEOVwk" alt=""><figcaption><p><strong>Sonic</strong></p></figcaption></figure> <figure><img src="/files/5656uD89H0U3hDTlKec0" alt=""><figcaption><p><strong>Ethereum</strong></p></figcaption></figure> <figure><img src="/files/Jm3FUqJJcs5jsoXtZn8B" alt=""><figcaption><p><strong>Ink</strong></p></figcaption></figure> <figure><img src="/files/V8iEwCYdEtEKuBYDMUTS" alt=""><figcaption><p><strong>Berachain</strong></p></figcaption></figure> <figure><img src="/files/MrFrgGsOplifmc7TJ2Am" alt=""><figcaption><p><strong>BNB Smart Chain</strong></p></figcaption></figure></div>

<div><figure><img src="/files/9VmjvUbLfJrZ9tTnCQ42" alt=""><figcaption><p><strong>Base</strong></p></figcaption></figure> <figure><img src="/files/Lm1EQqrpgjCpummDqTPN" alt=""><figcaption><p><strong>Polygon</strong></p></figcaption></figure> <figure><img src="/files/0uoY7piPJtA1vgEWHk67" alt=""><figcaption><p><strong>Optimism</strong></p></figcaption></figure> <figure><img src="/files/ygUqagbdcu7voTGmyPDA" alt=""><figcaption><p><strong>Arbitrum</strong></p></figcaption></figure> <figure><img src="/files/8qq7n5tQqKGGyn68YV35" alt=""><figcaption><p><strong>Avalanche</strong></p></figcaption></figure></div>

<div><figure><img src="/files/q3vfHEhUPJQ5mpcNRB5X" alt=""><figcaption><p><strong>Manta</strong></p></figcaption></figure> <figure><img src="/files/aHDhYHKNnv1O4tyHY6w2" alt=""><figcaption><p><strong>Polygon zkEVM</strong></p></figcaption></figure> <figure><img src="/files/zLuD251RtaMCoEhmFzzX" alt=""><figcaption><p><strong>zkSync</strong></p></figcaption></figure> <figure><img src="/files/O4sCu4xKcEWH8PEFTWu5" alt=""><figcaption><p><strong>Blast</strong></p></figcaption></figure> <figure><img src="/files/XTDmg5hoJam5PGzZ9RU2" alt=""><figcaption><p><strong>Scroll</strong></p></figcaption></figure></div>

<div><figure><img src="/files/XI2bFxmF0ysDbAZ1ZjUH" alt=""><figcaption><p><strong>Linea</strong></p></figcaption></figure> <figure><img src="/files/LJqwS9JNMFyBYoV7kyb2" alt=""><figcaption><p><strong>Metis</strong></p></figcaption></figure> <figure><img src="/files/8vJMSeGpK9IRg2CRGB9b" alt=""><figcaption><p><strong>Fantom</strong></p></figcaption></figure></div>


# Guides

Learn a bit about Magpie and how to use our app here!

{% content-ref url="/pages/SY4NYyowVQO9CujgBLjA" %}
[Glossary of DeFi Terms](/guides/glossary-of-defi-terms)
{% endcontent-ref %}

{% content-ref url="/pages/n5Uq65VHfbvQPf2aCLHc" %}
[Connect Wallet](/guides/connect-wallet)
{% endcontent-ref %}

{% content-ref url="/pages/dgpmdLatZiC75DispemQ" %}
[On-Chain Swap](/guides/on-chain-swap)
{% endcontent-ref %}

{% content-ref url="/pages/DKknfVMyi0LFcB0jq11M" %}
[Cross-Chain Swap](/guides/cross-chain-swap)
{% endcontent-ref %}

{% content-ref url="/pages/VpAcKZsPxasrtjyPqWyt" %}
[Swap configuration](/guides/swap-configuration)
{% endcontent-ref %}

{% content-ref url="/pages/7yQwOfm9K0FZg3sBtyQC" %}
[fly boosts](/guides/fly-boosts)
{% endcontent-ref %}

{% content-ref url="/pages/jnHCQ9ZzotNT9ytyyL7c" %}
[Transaction History](/guides/transaction-history)
{% endcontent-ref %}

{% content-ref url="/pages/lMhNw91VWkHe742MpcRi" %}
[Portfolio](/guides/portfolio)
{% endcontent-ref %}


# Glossary of DeFi Terms

Understand key DeFi terminology with Fly Trade's glossary, covering assets, AMMs, liquidity, slippage, and more to enhance your crypto knowledge.

### Asset

Digital token/cryptocurrency that can be owned, transferred, traded, or staked on the blockchain. fly.trade allows for the trading, staking, and moving of assets.

### Automated Market Makers

AMMs, such as Uniswap, allow users to deposit their tokens into smart contract-based liquidity pools to contribute to liquidity so that they may earn fees on the trades while users get access to asset swaps at market rates.

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

### ERC20

Token standard for Fungible tokens on Ethereum and EVM (Ethereum virtual machine) blockchains.

### Gas Fee

The fee required to initiate a transaction or execute a smart contract on a blockchain. In short, it's the cost of using the network's computational resources, compensating network validators or miners who process and confirm the transaction. Gas is typically paid in the native token of the blockchain (ETH on Ethereum and many EVM chains, S on Sonic, SOL on Solana)

### Liquidity <a href="#docs-internal-guid-0e99ae6a-7fff-9d79-0a7b-b09595090f43" id="docs-internal-guid-0e99ae6a-7fff-9d79-0a7b-b09595090f43"></a>

Assets in pools. Token/asset pairs that are available for trading.

### Liquidity Provider or "LP" <a href="#docs-internal-guid-715d28c3-7fff-fb87-07ec-35e13f66624d" id="docs-internal-guid-715d28c3-7fff-fb87-07ec-35e13f66624d"></a>

Users who pair and pool tokens. Liquidity providers assume impermanent loss and are compensated with swap fees, emissions (on some DEXs), as well as incentives.

### Pair <a href="#docs-internal-guid-ce8cf26d-7fff-0277-ba0f-246aa8cd0b12" id="docs-internal-guid-ce8cf26d-7fff-0277-ba0f-246aa8cd0b12"></a>

A smart contract that enables trading directly between two assets.

### Price Impact <a href="#docs-internal-guid-df51fe51-7fff-6d29-3bf3-4356350ef60d" id="docs-internal-guid-df51fe51-7fff-6d29-3bf3-4356350ef60d"></a>

The effect a trade has on an asset's price due to the size of the order relative to pool liquidity. Larger trades typically result in higher price impact.

### Pools

A smart contract that enables trading between two ERC20 tokens. Blockchains and DEXs can have multiple pools with the same assets, or tokens, with differing amounts of liquidity and slight price variation.

### Slippage <a href="#docs-internal-guid-b84de979-7fff-b166-3d70-406f4aefafa8" id="docs-internal-guid-b84de979-7fff-b166-3d70-406f4aefafa8"></a>

The price change between submitting a transaction and its execution.

### Swap Fees

A small fee which goes to the liquidity providers of the token.


# Connect Wallet

Step-by-step guide to connecting your wallet to fly trade, enabling secure and efficient access to DeFi trading features.

On the fly.trade website, one can connect a wallet by clicking on the "Connect the wallet" button located in the top right corner or in the swap menu.

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

Once the wallet is connected, the user can find their wallet address getting displayed on the top right of the screen.

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

If the current network of the wallet and the chosen network on the swap page do not match, then the button at the end of the swap activity box displays "Change Network To \<selected-network-name>"

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


# On-Chain Swap

Here we will provide you with a step-by-step set of instructions to swap tokens on the same chain using the fly.trade app.

Click under the 'From' field where the cursor shows in the below image in order to select the chain and token. In this example, we are going to swap USDC.E on Sonic to the STS token.

<figure><img src="/files/8z5s2OcWR0sJj3C51qD8" alt="" width="417"><figcaption></figcaption></figure>

Once you've clicked the 'From' field, you'll see the following, where you can select a network and token you would like to swap. If the stS token isn't near the top of the list for you, you can use the search field to find the token. We'll be selecting the Sonic Chain and USDC.e token for this example.

<figure><img src="/files/gFVlQdxNHOnHQwhpV9Rj" alt="" width="415"><figcaption></figcaption></figure>

In the app, you'll now click on the field below the 'To' in order to select the destination chain and token.

<figure><img src="/files/rfAj8r0ukESOPOaTt67n" alt="" width="418"><figcaption><p>As this is an on-chain swap, select the Sonic network and the STS token.</p></figcaption></figure>

Once you have selected the pair and amount, click "Swap USDC.e to stS." Note: the gas tank icon can be clicked to select the option to use the blockchains native gas token for the transactions, and the leaf icon can be selected to use fly.trade's gasless feature, which will use they token you are swapping to pay for the gas, just in case you do not have the native gas token.

<figure><img src="/files/Xxt2ZR6KDOZ64eJk4EgM" alt="" width="419"><figcaption></figcaption></figure>

After clicking 'Swap,' your wallet will prompt you to confirm the transaction with an estimated gas fee. Here is where you can adjust the amount of gas you want to spend if that is something you're comfortable with, but most people leave it at the suggested amount.

<figure><img src="/files/MMy7yF3MpWL9IlUT7kKA" alt="" width="423"><figcaption></figcaption></figure>

After 'Confirming' the transaction, just wait a bit and you can either click on the bar that appears once the swap is completed in the upper right of the screen, or you can click on the Wallet icon in the upper right of the web page to bring up the sidebar and select your history to view all previous transactions.

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

<figure><img src="/files/fjTOwXbjoyDiylrwtGoB" alt="" width="390"><figcaption></figcaption></figure>

You've just completed your first swap through fly.trade!&#x20;


# Cross-Chain Swap

Here we will provide you with a step-by-step set of instructions to swap tokens across chains using the fly.trade app. The process is very similar to on-chain swaps.

For a Cross-Chain swap select a different chain in the receiving network drop-down menu. For this example we will be swapping the 'LINK' token from 'Arbitrum' network for the 'AAVE' token on the 'Optimism' network.

<figure><img src="/files/OZ3Fs7xjhuMgCo95YiAh" alt="" width="375"><figcaption></figcaption></figure>

Just the same as the On-Chain swap instructions, select the box below the 'From' text to select the chain/network we are starting on, in this case, Arbitrum.&#x20;

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

Now select the 'LINK' token. If it's not near the top of your list, you can use the search bar to find it.

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

Next, select the box below the 'To' text and select the 'Optimism' chain/network, then search for and select 'AAVE' as the token to receive.

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

Next, we need to click on the 'Approve LINK' button so that the fly.trade dApp gains permission to swap the tokens.

<figure><img src="/files/9FQTBU1xyYnNOf50j291" alt=""><figcaption></figcaption></figure>

Your wallet app will prompt you to give the fly.trade dApp permission to use the selected token. Click 'Confirm.'

<figure><img src="/files/TnAxz5IwljYcQysZNsDz" alt="" width="361"><figcaption></figcaption></figure>

Once confirmed, the 'Approve' button now says "Swap LINK to AAVE". Click the button to start the swap process.

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

Your wallet will once again prompt you to confirm the transaction, this time with estimated fees for any Gas, Bridge, or Relayer fees that are required for the swap, all-in-one. Click the "Confirm" button to initiate the swap.

<figure><img src="/files/OyWdlOjyuiKD2l7nN8ul" alt="" width="360"><figcaption></figcaption></figure>

Next, you can either click on the bar in the upper right that shows the swap is completed to check the transaction or you can open the sidebar to see your transaction history and view the information there.

It'll look something like this, showing the two steps involved:&#x20;

* Receiving bridge funds
* Executing swap out

<figure><img src="/files/n5z4SeojH64vpNAhsGmw" alt="" width="375"><figcaption></figcaption></figure>

**There are three possible outcomes now:** \
1\. Successful transaction  \
2\. Refunded transaction \
3\. Intended token transaction&#x20;

1. **Successful Transaction:** You have received the chosen token.<br>

<figure><img src="/files/LcfPbrza6MxVubM8sKBF" alt="" width="375"><figcaption></figcaption></figure>

2. Refunded transaction : Something went wrong during the swap, and we have returned your token.

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

3. Intended token transaction  : If, during a cross-chain swap, there is not enough liquidity or high token volatility to receive the selected token, we provide you with a token that you can later swap using an On-chain swap by clicking "Swap to..." :

<figure><img src="/files/S8qmv68itEgVBcuSSXw9" alt="" width="563"><figcaption></figcaption></figure>

\
\
Hopefully that was easy, no bridges, no extra websites, just as simple as a normal on-chain swap.

Depending on the network you are going to or from, there can be a differing amount of time it takes for the transactions, but you can check the status in the 'Transactions' tab in the upper right corner of the screen.


# Swap configuration

Here, we will guide you through the step-by-step process of configuring additional settings using the fly.trade app.

**Gasless feature** :&#x20;

fly.trade executes the transaction on behalf of the user, covering the gas fees, so the user doesn’t need to hold or pay gas in the native currency.

<figure><img src="/files/Xe1ymqD3Mu5toD1pEpdF" alt="" width="375"><figcaption></figcaption></figure>

This feature has two states - ON and OFF:&#x20;

* When the feature is turned **ON** – the gas fee is charged from the **Selected token.**

<figure><img src="/files/0gXkiVtKD8wKwln5XC3M" alt=""><figcaption></figcaption></figure>

* When the feature is turned **OFF** – the fee is charged from the **Native token.**

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

**Setting menu:**

In the **settings**, you can adjust parameters such as Slippage Tolerance, Liquidity Sources, and Bridges.

<figure><img src="/files/juR9J42oYpCgQNJCieev" alt="" width="375"><figcaption></figcaption></figure>

<figure><img src="/files/aCcpEl1xnyhQialsFGwZ" alt="" width="375"><figcaption></figcaption></figure>

* **Slippage tolerance:**&#x20;

  Allows you to set slippage tolerance that sets a limit on how much the price of an asset can change during your trade execution.

<figure><img src="/files/HhaFbusA1oEcylHIvy8U" alt="" width="375"><figcaption></figcaption></figure>

* **Liquidity sources:**

  Allows you to enable or disable liquidity sources that are supported on the connected chain.<br>

<figure><img src="/files/H3bAfj4LRreMf6OU5F7n" alt="" width="375"><figcaption></figcaption></figure>

* **Bridges:**

  Allows you to enable or disable the supported bridges.

<figure><img src="/files/hCkXWXnGMInF6t8GFtgO" alt="" width="375"><figcaption></figcaption></figure>

**Update quote :**&#x20;

Allows you to refresh the quote and get the latest prices.

<figure><img src="/files/Z5RephfIT93U2QtwYsSn" alt="" width="375"><figcaption></figcaption></figure>

**Switch From - To - From asset** :&#x20;

**Switch the "From" and "To" tokens (also switches networks).**

<figure><img src="/files/dpydyVJpSa0ZuSMzjNsV" alt="" width="375"><figcaption></figcaption></figure>

**Explorer link :**&#x20;

Redirects to the selected token's explorer.

<figure><img src="/files/fEcAms53CTABa2RbQNHO" alt="" width="375"><figcaption></figcaption></figure>

**Update recipient's wallet address:**\
You can change the address to which the funds will be sent.

<figure><img src="/files/3mdXupI8gvuVMH76dDjK" alt="" width="375"><figcaption></figcaption></figure>

<figure><img src="/files/9OVYN3DqD2nD09GvqsjQ" alt="" width="375"><figcaption></figcaption></figure>

**More transaction information:**

Here you can see more details about your transaction

<figure><img src="/files/UmnvMouf8k3WNwT0VoRm" alt="" width="375"><figcaption></figcaption></figure>

That's all for now, thanks for using fly! :tada:


# fly boosts

Learn how fly boosts can enhance your trading experience on fly trade, offering incentives and improved functionalities for users.

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

Boosts are tasks that users can complete multiple times for increased rewards that focus on multiple key areas of DeFi to ensure that all ecosystem participants — traders, liquidity providers, and those that borrow/lend have ways to earn meaningful rewards.Boosts are tasks that users can complete multiple times for increased rewards that focus on multiple key areas of DeFi to ensure that all ecosystem participants — traders, liquidity providers, and those that borrow/lend have ways to earn meaningful rewards.

### Incentives

As fly.trade was a Sonic Boom winner, we were awarded an allotment of Sonic Gems to give out to our community. As such, we're calling these Magpie Fragments (Sonic Gems tokenized by[@merkl\_xyz](https://x.com/@merkl_xyz)) and rewarding users who actively engage with different protocols within Sonic’s ecosystem through the fly.trade dApp and Boost campaign. But that's not all, there are more incentives to be had:

* Magpie Fragments: Tokenized Sonic gem rewards for trading and interacting with select protocols through our Boosts, including DEXs, lending platforms, and asset issuers within the Sonic ecosystem.
* Eggs: Eggs are collected through completed Boosts, limited to 100 per user per boost, and will be converted to reward users with FLY post TGE.
* Sonic Points: Due to the nature of aggregation, users can earn Sonic Points by conducting swaps through fly.trade, as your swaps, liquidity provision, or asset minting is all routed through Sonic-native protocols who may also have rewards points for using them.
* Other protocol rewards: Partner protocol’s rewards will also be stacked on top of all fly incentives.

This could mean a swap through our Boost could stack Magpie Fragments, Eggs, Sonic Points, Rings Protocol Points, and Veda points, quintuple dipping on rewards!

fly will be adding more Boost campaigns as time goes on and you can check our Boost page here, or click on the Boost Icon in the upper left of the app, to see all ongoing Boosts.

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

<https://app.fly.trade/boost>


# Convert FLY to xFLY

Before Converting FLY to xFLY, you need to buy FLY token (if you haven't done this already).\
you can do it in a few ways:&#x20;

1. Via fly.trade link <https://app.fly.trade/swap/sonic/S/sonic/FLY>
2. On our platform or other supported platforms using address FLY token official address: [0x6c9b3a74ae4779da5ca999371ee8950e8db3407f](https://sonicscan.org/address/0x6c9b3a74ae4779da5ca999371ee8950e8db3407f)
3. Via Button 'Buy FLY' from <https://app.fly.trade/fly>

<figure><img src="/files/78JJurTUCf9cKZZ6mw3Z" alt=""><figcaption></figcaption></figure>

**Once you've done this, it's time to fly, congratulations! Now we'll tell you how to do it**  🦅<br>

**Here's How to Convert FLY to xFLY:**

* **Launch the fly trade app:** <https://app.fly.trade/fly>
* Choose the 'Convert to xFly' tab (already selected by default)

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

* **Set your amount:** Enter the amount of FLY tokens you want to convert to xFLY

<figure><img src="/files/u4Sxm3FvvTPUrFnDJizM" alt="" width="563"><figcaption></figcaption></figure>

* **Grant permission:** Approve your FLY tokens for conversion to xFly

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

* **Initiate takeoff:** Convert your approved token amount with Signature in your wallet
* You can add xFLY to your EVM wallet using xFLY token address [0x88f8ea30e7c07e2479e39218ade74e3f7f87c7c9](https://sonicscan.org/address/0x88f8ea30e7c07e2479e39218ade74e3f7f87c7c9)&#x20;

<figure><img src="/files/mFiznSJucv7Kc1n9cdzJ" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/HOOMDEzQ4poSpRONLobh" alt="" width="563"><figcaption></figcaption></figure>

&#x20;                        **Welcome aboard!** You're now ready to Fly with us with your xFLY tokens!

&#x20;                                      *Get ready for an incredible journey in the FLY ecosystem!*

&#x20;                         *Get more* information *about xFly token here :* [xFLY and FLY33 tokens information ](/fly/usdfly/xfly-and-fly33)\
\
*Helpful links:* \
*1.* [xFLY 'Vested Exit' / 'Instant Exit'](/guides/xfly-vested-exit-instant-exit)\
2.[ FLY Key Features](/fly/fly-key-features)\
3[. FLY token information ](/)\
4\. [xFLY and FLY33 tokens information ](/fly/usdfly/xfly-and-fly33)


# xFLY 'Vested Exit' / 'Instant Exit'

In this guide, we'll walk you through the vesting process and show you how to convert back from xFLY tokens to FLY tokens. Let's dive in together!

&#x20;                                 **🔄 Want to go back to $FLY? Here Your Flight Path:**

* Open FLY dashboard <https://app.fly.trade/fly>
* Navigate to the 'Exit to FLY' tab&#x20;

<figure><img src="/files/9cw5C9FPtWCM36DjaeEd" alt="" width="563"><figcaption></figcaption></figure>

* **Pick your exit strategy:** You'll see 2 options: 'Vested Exit' and 'Instant Exit'

### **Vested Exit**:&#x20;

xFLY may be converted back to FLY by entering into a mandatory 3-month vesting period.

* 14-day cancellation window: Participants have 14 days from the vesting start date to cancel the vesting commitment. Upon cancellation, the participant retains their xFLY.
  * After this 14-day cancellation window, cancellation is not possible, and the tokens enter into the 3 month (90-day) vesting period.
* Participants may choose to exit their vesting early at any time prior to the 90-day completion
  * Exiting Early will result in a penalty on the amount of xFLY being converted to FLY.
* This penalty starts at 50% from the vesting start date and linearly scales to 0% at the end of the 90-day vesting period.

### ***Instant Exit***:

Participants may convert xFLY to FLY at any time, without vesting, subject to a 50% reduction penalty. Only 50% of the xFLY converted will be redeemable as FLY in this case.

### Tutorial

* **For Vested Exit:** Enter the amount you want to exit and click 'Create Vest'. You'll have access to an interactive chart of your vesting (hover over it to see vesting amounts and time periods) <br>

<figure><img src="/files/A47mzIjIO9guHmVzy1Ay" alt="" width="563"><figcaption></figcaption></figure>

* Sign the transaction and you will see your vest that you created

<figure><img src="/files/G9TAnCrkFP7WheEqWSpe" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/oGNElAHdIposakDqPbEn" alt="" width="563"><figcaption></figcaption></figure>

* **For Instant Exit:** Select the 'Instant Exit' tab and enter your desired amount and click 'Exit xFLY'.

<figure><img src="/files/fOHnMJigSf4wELrWO79o" alt="" width="563"><figcaption></figcaption></figure>

• Confirm Penalty information modal and sign the transaction.<br>

<figure><img src="/files/yI5aiJbyjhhurnRBC9bZ" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/p1o0anxhgr2mvDNYJx3Z" alt="" width="563"><figcaption></figcaption></figure>

* **Mission accomplished!** You've successfully converted xFLY to FLY.

<br>

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

*Choose the exit strategy that works best for your needs and timeline!*\
\
*Helpful links:* \
*1.* [xFLY 'Vested Exit' / 'Instant Exit'](/guides/xfly-vested-exit-instant-exit)\
2.[ FLY Key Features](/fly/fly-key-features)\
3[. FLY token information ](/)\
4\. [xFLY and FLY33 tokens information ](/fly/usdfly/xfly-and-fly33)


# Transaction History

This section shows you how to check your wallet's transaction history through the fly.trade Sidebar.

To Check your transaction history, click on the wallet icon with your address in the upper right hand corner of the webpage.

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

This will bring up the sidebar where you can click where it says 'History' in order to see the transaction history. You will be able to see pending and completed swaps, as well as an easy to read icons to quickly tell which tokens were swapped, which chain it was on, and the date of transaction.

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

If you click on the transaction, it will allow you to view the transaction on the block explorer.

<figure><img src="/files/ZHBt4ariCmIfv5CpuYIc" alt="" width="375"><figcaption></figcaption></figure>


# Portfolio

This feature will show you your assets across all of the fly connected chains from the wallet you have connected to the fly.trade dApp.

It's incredibly easy to check your assets with the fly Sidebar!

Click on the wallet icon in the upper right hand corner as seen below.

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

Click on 'Assets' on the left side to see which assets you have on which chains. If you want to buy or sell more of an asset, simply hover over it and click 'Buy' or 'Sell'

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


# Media Kit

{% embed url="<https://www.magpiefi.xyz/media-kit>" %}


# Developers

Central hub for developers, offering resources, documentation, and tools to build and integrate with fly trade’s DeFi infrastructure.

This section serves as a comprehensive guide for developers navigating the fly.trade smart contracts. It aims to provide a detailed walk-through of the protocol's implementation, focusing particularly on cross-chain swaps and on-chain swaps. By delving into the intricacies of these smart contracts, developers will gain a profound understanding of how fly.trade facilitates seamless asset transfers across different blockchain networks. The comprehensive documentation presented here offers insights into the underlying mechanics, logic, and security measures embedded in the cross-chain and on-chain swap functionalities. Armed with this knowledge, developers can confidently engage with and contribute to the fly.trade ecosystem, ensuring a smooth and informed integration of these innovative features into their blockchain applications.


# fly.trade contracts

Comprehensive overview of fly trade’s smart contracts, including Magpie bridges and libraries essential for DeFi integrations.

<table data-full-width="true"><thead><tr><th width="209">Contract</th><th>Description</th></tr></thead><tbody><tr><td>IAxelarGasService</td><td><p>The IAxelarGasService interface manages gas payments and refunds for cross-chain communication on the Axelar network. It has one function: </p><p>• <mark style="color:red;"><strong>payNativeGasForContractCall</strong></mark>: pays for gas using native currency for a contract call on a destination chain.</p></td></tr><tr><td>IAxelarGateway</td><td><p>The IAxelarGateway interface enables cross-chain communication on the Axelar network. It has two functions: </p><p>• <mark style="color:red;"><strong>callContract</strong></mark>: executes a remote contract call on a destination chain. </p><p>• <mark style="color:red;"><strong>validateContractCall</strong></mark>: verifies the authenticity of a contract call and returns a boolean result.</p></td></tr><tr><td>IReceiver</td><td><p>The IReceiver interface receives messages on the destination chain and forwards them to the IMessageDestinationHandler. It has one function: </p><p>• <mark style="color:red;"><strong>receiveMessage</strong></mark>: receives an incoming message, validates the header, and passes the body to the application-specific handler.</p></td></tr><tr><td>ILiquidityBridge</td><td>The <mark style="color:red;"><strong>ILiquidityBridge</strong></mark> contract defines an interface for a cross-chain liquidity bridge. It specifies several core functions for sending and relaying assets across different blockchain networks, managing transfer status, and handling withdrawals.</td></tr><tr><td>IMessageBus</td><td>The <mark style="color:red;"><strong>IMessageBus</strong></mark> interface facilitates cross-chain message passing and token transfers. It defines structures like <mark style="color:red;"><strong>SwapInfo</strong></mark> (swap details) and <mark style="color:red;"><strong>SwapRequest</strong></mark> (swap operation), and enums such as <mark style="color:red;"><strong>BridgeSendType</strong></mark> (bridge operation types) and <mark style="color:red;"><strong>TransferType</strong></mark> (transfer actions). Core functions include sending and executing messages with transfers, handling refunds, and calculating fees. It supports multiple transfer mechanisms and integrates with a liquidity bridge for cross-chain operations.</td></tr><tr><td>IOFT</td><td>The <mark style="color:red;"><strong>IOFT</strong></mark> interface manages cross-chain token transfers using Omnichain Fungible Tokens (OFT). It defines structures like <mark style="color:red;"><strong>SendParam</strong></mark> for transfer details and <mark style="color:red;"><strong>MessagingReceipt</strong></mark> for transaction receipts. The contract includes functionality for sending tokens across chains, quoting transfer limits and fees, and handling messaging and fee structures. It ensures security through slippage checks and transfer validation.</td></tr><tr><td>IStargate</td><td>The <mark style="color:red;"><strong>IStargate</strong></mark> interface extends the <mark style="color:red;"><strong>IOFT</strong></mark> contract for cross-chain token transfers. It introduces a <mark style="color:red;"><strong>StargateType</strong></mark> enum to define implementation types and a <mark style="color:red;"><strong>Ticket</strong></mark> struct for bus ride operations. Key functionality includes sending tokens across chains via <mark style="color:red;"><strong>sendToken</strong></mark>, which also returns a ticket if bus ride mode is enabled, and retrieving the Stargate type via <mark style="color:red;"><strong>stargateType()</strong></mark>. The interface builds on OFT operations, adding unique Stargate-related logic.</td></tr><tr><td>IBridge</td><td>The <mark style="color:red;"><strong>IBridge</strong></mark> interface defines the core functionality for a token bridge that supports swapping assets across chains. It emits events for swap operations (<mark style="color:red;"><strong>SwapIn</strong></mark>, <mark style="color:red;"><strong>SwapOut</strong></mark>) and allows the contract owner to update internal parameters such as whitelisted callers, WETH address, and network/router details. The <mark style="color:red;"><strong>multicall</strong></mark> function enables executing multiple operations in a single transaction, enhancing operational efficiency.</td></tr><tr><td>IMagpieCCTPBridge</td><td>The <mark style="color:red;"><strong>IMagpieCCTPBridge</strong></mark> interface extends the <mark style="color:red;"><strong>IBridge</strong></mark> contract and adds functionality for cross-chain token and message handling. It allows the owner to update critical addresses such as the CCTP token messenger, Axelar gateway, and gas receiver. Additionally, the interface includes an <mark style="color:red;"><strong>execute</strong></mark> function to handle commands from a source chain, processing them based on the provided command ID, source chain, source address, and encoded payload. This enables seamless communication and execution of cross-chain operations.</td></tr><tr><td>IMagpieCelerBridgeV2</td><td>The <mark style="color:red;"><strong>IMagpieCelerBridgeV2</strong></mark> interface extends the <mark style="color:red;"><strong>IBridge</strong></mark> contract, facilitating interactions with the Celer Network. It allows the owner to update the Celer address and includes functions for executing messages with fund transfers and managing refunds. This ensures efficient cross-chain communication and transaction handling.</td></tr><tr><td>IMagpieRouterV3</td><td>The <mark style="color:red;"><strong>IMagpieRouterV3</strong></mark> interface provides a framework for managing internal callers and bridges, enabling the owner to update their whitelisted statuses. It includes a <mark style="color:red;"><strong>multicall</strong></mark> function for executing multiple actions in a single transaction, and several token swap methods: <mark style="color:red;"><strong>swapWithMagpieSignature</strong></mark>, <mark style="color:red;"><strong>swapWithUserSignature</strong></mark>, and <mark style="color:red;"><strong>swapWithoutSignature</strong></mark>, each facilitating asset exchanges while returning the amount received. Additionally, it features an <mark style="color:red;"><strong>estimateSwapGas</strong></mark> function to assess gas costs for swaps, enhancing transaction efficiency and cost management.</td></tr><tr><td>IMagpieStargateBridgeV3</td><td>The <mark style="color:red;"><strong>IMagpieStargateBridgeV3</strong></mark> interface extends the <mark style="color:red;"><strong>IBridge</strong></mark> contract, enabling management of asset mappings to Stargate pools. It allows the owner to update the asset-to-Stargate and Stargate-to-asset mappings through dedicated functions. Additionally, it includes an <mark style="color:red;"><strong>updateLzAddress</strong></mark> function for modifying the LayerZero address. The interface also features the <mark style="color:red;"><strong>lzCompose</strong></mark> function, enabling Stargate to handle transfers and update deposit amounts, facilitating seamless asset management across the bridge.</td></tr><tr><td>IMagpieSymbiosisBridge</td><td>The <mark style="color:red;"><strong>IMagpieSymbiosisBridge</strong></mark> interface extends the <mark style="color:red;"><strong>IBridge</strong></mark> contract, providing functionalities to manage critical addresses for the Portal, Axelar gateway, and gas receiver, allowing the owner to update these addresses as needed. Additionally, it features an <mark style="color:red;"><strong>execute</strong></mark> function that facilitates the execution of Axelar commands from a source chain, using parameters like command ID, source chain name, source address, and payload. This ensures effective cross-chain communication and command execution.</td></tr><tr><td>IWETH</td><td>The <mark style="color:red;"><strong>IWETH</strong></mark> interface defines essential functions for interacting with Wrapped Ether (WETH). It includes a <mark style="color:red;"><strong>deposit</strong></mark> function to convert Ether to WETH, a <mark style="color:red;"><strong>transfer</strong></mark> function for transferring WETH to a specified address, and a <mark style="color:red;"><strong>withdraw</strong></mark> function for converting WETH back to Ether. This interface facilitates seamless handling of WETH within smart contracts.</td></tr><tr><td>MagpieCCTPBridge</td><td>The <mark style="color:red;"><strong>MagpieCCTPBridge</strong></mark> contract facilitates cross-chain asset swaps and deposits through Circle CCTP bridge. It includes functions for updating router addresses, processing inbound and outbound swaps, and managing deposits. The contract verifies signatures for secure transactions and emits events for asset bridging and deposits.</td></tr><tr><td>MagpieCelerBridgeV2</td><td>The <mark style="color:red;"><strong>MagpieCelerBridgeV2</strong></mark> contract enables cross-chain asset swaps and deposits, incorporating security measures like ownership control and pausable functions. It verifies swap signatures, manages deposit data, and facilitates asset bridging through the Celer Network, ensuring efficient transaction handling and refund management.</td></tr><tr><td>MagpieRouterV3</td><td>The contract is designed to facilitate token swaps. It includes a range of functions for executing commands, handling swaps, and managing gas usage. The contract uses a combination of libraries and interfaces to provide its functionality, including the <mark style="color:red;"><strong>IOFT</strong></mark> interface, <mark style="color:red;"><strong>LibAsset</strong></mark>, <mark style="color:red;"><strong>LibRouter</strong></mark>, and <mark style="color:red;"><strong>Ownable2Step</strong></mark> and <mark style="color:red;"><strong>Pausable</strong></mark> from OpenZeppelin.</td></tr><tr><td>MagpieStargateBridgeV3</td><td>The <mark style="color:red;"><strong>MagpieStargateBridgeV3</strong></mark> contract facilitates cross-chain asset swaps and deposits, ensuring security through ownership control and pausable functions. It verifies swap signatures, manages deposit data, and handles asset bridging via the Stargate network. Key functionalities include updating internal callers, executing swaps, and processing deposits while preventing reentrancy and validating addresses.</td></tr><tr><td>MagpieSymbiosisBridge</td><td>The <mark style="color:red;"><strong>IMagpieSymbiosisBridge</strong></mark> interface extends the IBridge contract and introduces functionalities for cross-chain asset transfers and swaps. It enables the owner to update key addresses, including the <mark style="color:red;"><strong>WETH</strong></mark> token, portal, Axelar gateway, and gas receiver, ensuring flexible asset management. The interface features several swap functions, allowing for inbound and outbound asset operations, supported by rigorous signature verification to enhance security. Furthermore, the <mark style="color:red;"><strong>execute</strong></mark> function processes incoming commands from a source chain, validating them through the Axelar gateway before executing the associated payload. This design facilitates efficient cross-chain communication and execution of transactions.</td></tr><tr><td>LibAsset</td><td>The LibAsset library offers utility functions for handling asset transfers, approvals, and balance checks within Ethereum smart contracts. It identifies native assets (Ether) and provides functions to wrap and unwrap assets securely. The library facilitates balance retrieval for both the contract and specific addresses. Additionally, it ensures safe transfer and approval operations for ERC20 tokens using low-level calls with detailed error handling. Key functions include <mark style="color:red;"><strong>wrap</strong></mark>, <mark style="color:red;"><strong>unwrap</strong></mark>, <mark style="color:red;"><strong>transfer</strong></mark>, <mark style="color:red;"><strong>approve</strong></mark>, and <mark style="color:red;"><strong>permit</strong></mark>, enhancing asset management capabilities in cross-chain contexts.</td></tr><tr><td>LibBridge</td><td>The <mark style="color:red;"><strong>LibBridge</strong></mark> library provides essential functions for managing cross-chain swap operations within smart contracts. It computes bridge fees based on the asset type, ensuring accurate financial handling during swaps. The library enables the encoding and decoding of deposit data hashes, facilitating secure data management across different networks. It also incorporates robust error handling for invalid swap conditions and provides methods for both inbound and outbound swap operations. Key functionalities include fee calculation, deposit data encoding, and executing swaps with native and ERC20 assets, optimizing cross-chain transaction processes.</td></tr><tr><td>LibRouter</td><td>The LibRouter library provides functionalities for handling swap operations in smart contracts. It processes incoming data to create a structured <mark style="color:red;"><strong>SwapData</strong></mark> object while validating transaction deadlines. The library facilitates fee transfers, including gas fees and affiliate fees, while managing permissions through an approval mechanism. It verifies signatures to ensure transaction authenticity, utilizing EIP-712 standards for structured data hashing. Key features include <mark style="color:red;"><strong>getData</strong></mark>, <mark style="color:red;"><strong>transferFees</strong></mark>, <mark style="color:red;"><strong>permit</strong></mark>, and <mark style="color:red;"><strong>verifySignature</strong></mark>, enabling robust and secure cross-chain swap functionality.</td></tr></tbody></table>


# MagpieCCTPBridge

The MagpieCCTPBridge contract is designed for cross-chain token transfers and swaps, integrating various external libraries and interfaces. It inherits from Ownable2Step and Pausable for managing ownership and pausing functionalities. The contract uses the LibAsset library for asset operations and interacts with external interfaces like IMagpieCCTPBridge, IAxelarGateway, IAxelarGasService, and IReceiver. Key features include managing internal callers and deposits, updating critical addresses (WETH, token messenger, message transmitter, gateway, gas receiver), and performing token swaps with Magpie or user signatures. It ensures secure operations through signature verification and handles inbound and outbound swaps, bridging assets, and executing multiple function calls in a single transaction. The contract also supports incoming Ether transfers.

<table data-full-width="false"><thead><tr><th width="235">Function Name</th><th>Description (Business Logic)</th></tr></thead><tbody><tr><td><mark style="color:red;"><strong>verifySignature</strong></mark> </td><td>The <mark style="color:red;"><strong>verifySignature</strong></mark> function is a private function that verifies the signature for a swap operation. It takes <mark style="color:red;"><strong>SwapData</strong></mark> and a boolean flag <mark style="color:red;"><strong>useCaller</strong></mark> as parameters. The function constructs a message based on the swap details, including whether an affiliate is involved, and uses assembly to efficiently handle the message data. It then calls <mark style="color:red;"><strong>LibRouter.verifySignature</strong></mark> to validate the signature, ensuring the integrity and authenticity of the swap operation.</td></tr><tr><td><mark style="color:red;"><strong>swapIn</strong></mark> </td><td>The <mark style="color:red;"><strong>swapIn</strong></mark> function is a private function that executes an inbound swap operation. It increments the <mark style="color:red;"><strong>swapSequence</strong></mark> to ensure each swap has a unique sequence number and retrieves the current network ID and router address using assembly. The function verifies the signature of the swap operation through the <mark style="color:red;"><strong>verifySignature</strong></mark> function, ensuring the authenticity of the transaction. If the swap data includes a permit, the function calls <mark style="color:red;"><strong>LibRouter.permit</strong></mark> to handle the permit. It then transfers any associated fees using <mark style="color:red;"><strong>LibRouter.transferFees</strong></mark>. The function prepares the deposit data by filling an encoded data structure and computing its hash. The actual swap is performed by calling <mark style="color:red;"><strong>LibBridge.swapIn</strong></mark>, which returns the amount received from the swap. Finally, the function calls <mark style="color:red;"><strong>bridgeIn</strong></mark> to handle the bridging of assets and checks for <mark style="color:red;"><strong>reentrancy</strong></mark> by comparing the current swap sequence with the initial value. If they do not match, it reverts the transaction with a <mark style="color:red;"><strong>ReentrancyError</strong></mark>. An event <mark style="color:red;"><strong>BridgeIn</strong></mark> is emitted with the deposit data hash and nonce.</td></tr><tr><td><mark style="color:red;"><strong>bridgeIn</strong></mark> </td><td>The <mark style="color:red;"><strong>bridgeIn</strong></mark> function handles the bridging of an inbound asset transfer into the contract. It approves the token messenger to spend the specified amount of the asset and prepares the data for the bridging operation using assembly. The function calls <mark style="color:red;"><strong>tokenMessengerAddress.execute</strong></mark> to perform the bridging operation and reverts with <mark style="color:red;"><strong>BurnFailed</strong></mark> if the operation fails. It then calls <mark style="color:red;"><strong>dataIn</strong></mark> to handle the inbound data transfer and emits a <mark style="color:red;"><strong>BridgeIn</strong></mark> event with the deposit data hash and nonce.</td></tr><tr><td><mark style="color:red;"><strong>dataIn</strong></mark> </td><td>The <strong>dataIn</strong> function executes an inbound data transfer, preparing the payload with the deposit data hash, amount, and asset address. It calls <mark style="color:red;"><strong>IAxelarGasService.payNativeGasForContractCall</strong></mark> to pay the gas fee for the contract call and <mark style="color:red;"><strong>IAxelarGateway.callContract</strong></mark> to execute the contract call on the destination chain.</td></tr><tr><td><mark style="color:red;"><strong>execute</strong></mark></td><td>The <mark style="color:red;"><strong>execute</strong></mark> function handles the execution of inbound messages from the Axelar gateway. It validates the contract call using <mark style="color:red;"><strong>IAxelarGateway.validateContractCall</strong></mark> and reverts with <mark style="color:red;"><strong>NotApprovedByGateway</strong></mark> if the validation fails. The function then calls <mark style="color:red;"><strong>addDeposit</strong></mark> to add the validated deposit.</td></tr><tr><td><mark style="color:red;"><strong>addDeposit</strong></mark> </td><td>The <mark style="color:red;"><strong>addDeposit</strong></mark> function adds a validated deposit to the contract, updating the deposit mapping with the amount and asset address from the payload. It emits a <mark style="color:red;"><strong>Deposit</strong></mark> event with the deposit data hash and amount.</td></tr><tr><td><mark style="color:red;"><strong>swapOut</strong></mark> </td><td>The <mark style="color:red;"><strong>swapOut</strong></mark> function handles outbound swap operations, restricted to internal callers. It retrieves the network ID and router address using assembly and prepares the message and attestation data for the swap. The function calls <mark style="color:red;"><strong>IReceiver.receiveMessage</strong></mark> to process the message and reverts with <mark style="color:red;"><strong>MintFailed</strong></mark> if the operation fails. It then retrieves the deposit amount from the deposit mapping and performs the swap using <mark style="color:red;"><strong>LibBridge.swapOut</strong></mark>, returning the amount received from the swap.</td></tr><tr><td><mark style="color:red;"><strong>multicall</strong></mark> </td><td>The <mark style="color:red;"><strong>multicall</strong></mark> function allows the contract owner to execute multiple function calls in a single transaction. It iterates over the provided data array and calls each function using <mark style="color:red;"><strong>Address.functionDelegateCall</strong></mark>, returning the results of each call.</td></tr><tr><td><mark style="color:red;"><strong>receive</strong></mark> </td><td><mark style="color:red;"><strong>receive</strong></mark> function handles incoming Ether transfers.</td></tr></tbody></table>


# MagpieCelerBridgeV2

The MagpieCelerBridgeV2 Solidity contract facilitates cross-chain liquidity aggregation using the Celer cBridge. It inherits from Ownable2Step and Pausable contracts, providing ownership management and pausable functionality. The contract manages various state variables, including mappings for internal callers, deposits, and refund addresses, and stores addresses for WETH, Celer addresses, and a combined network ID and router address. It features custom modifiers to restrict access to certain functions and includes functions to update internal callers, WETH address, network ID, router address, and Celer Network address. Key functions like swapInWithMagpieSignature, swapInWithUserSignature, and swapIn handle swap operations, utilizing the LibRouter library for swap data and execution, with additional checks for native assets. The bridgeIn function manages the bridging of assets, while swapOut handles outbound swaps. The contract also processes inbound messages with asset transfers through executeMessageWithTransfer and handles refunds for failed transfers via executeMessageWithTransferRefund. Additionally, it includes a multicall function for executing multiple calls in a single transaction and a receive function to accept Ether payments.

<table data-full-width="false"><thead><tr><th width="263">Function Name</th><th>Description (Business Logic)</th></tr></thead><tbody><tr><td><mark style="color:red;">swapInWithMagpieSignature</mark> </td><td>The <mark style="color:red;"><strong>swapInWithMagpieSignature</strong></mark> function handles swap operations and can be called by anyone when the contract is not paused. It utilizes the <mark style="color:red;"><strong>LibRouter</strong></mark> library to retrieve the necessary swap data and execute the swap. This function ensures that the swap operation is performed correctly, including any additional checks required for native assets.</td></tr><tr><td><mark style="color:red;">swapInWithUserSignature</mark> </td><td>The <mark style="color:red;"><strong>swapInWithUserSignature</strong></mark> function also handles swap operations but is restricted to internal callers. Like <mark style="color:red;"><strong>swapInWithMagpieSignature</strong></mark>, it uses the <mark style="color:red;"><strong>LibRouter</strong></mark> library to retrieve swap data and execute the swap. This function includes additional checks specifically for native assets to ensure the integrity and security of the swap operation.</td></tr><tr><td><mark style="color:red;">verifySignature</mark> </td><td>The <mark style="color:red;"><strong>verifySignature</strong></mark> function is responsible for verifying the signature of a swap operation. This function takes in a <mark style="color:red;"><strong>SwapData</strong></mark> struct, which contains the details of the swap, and a boolean flag <mark style="color:red;"><strong>useCaller</strong></mark> that indicates whether the caller’s address should be used for verification. The function begins by determining the length of the message based on whether the swap includes an affiliate. It then uses inline assembly to construct the message that will be hashed and verified. The message includes various parameters such as the source and destination addresses, asset details, amounts, and network IDs. The assembly code dynamically allocates memory for the message and populates it with the relevant data from the <mark style="color:red;"><strong>swapData</strong></mark> struct. Depending on whether an affiliate is involved, it uses different keccak256 hash values to identify the type of swap. Finally, the function calls <mark style="color:red;"><strong>LibRouter.verifySignature</strong></mark> with the constructed message and other parameters to verify the signature. If the signature is valid, it returns the address of the signer.</td></tr><tr><td><mark style="color:red;">swapIn</mark></td><td>The <mark style="color:red;"><strong>swapIn</strong></mark> function executes a swap operation. It takes a <mark style="color:red;"><strong>SwapData</strong></mark> struct and a boolean flag <mark style="color:red;"><strong>useCaller</strong></mark> as parameters and returns the amount received from the swap operation. The function begins by incrementing the <mark style="color:red;"><strong>swapSequence</strong></mark> to track the current swap operation. It then retrieves the network ID and router address from the stored <mark style="color:red;"><strong>networkIdAndRouterAddress</strong></mark> using inline assembly. Next, the function verifies the signature of the swap operation by calling the <mark style="color:red;"><strong>verifySignature</strong></mark> function. If the swap data includes a permit, it calls <mark style="color:red;"><strong>LibRouter.permit</strong></mark> to handle the permit. It also transfers any associated fees using <mark style="color:red;"><strong>LibRouter.transferFees</strong></mark>. The function then prepares the deposit data by creating a new byte array and filling it with the necessary information using <mark style="color:red;"><strong>LibBridge.fillEncodedDepositData</strong></mark>. It calculates the hash of the deposit data and stores the refund address in the <mark style="color:red;"><strong>refundAddresses</strong></mark> mapping. The actual swap operation is performed by calling <mark style="color:red;"><strong>LibBridge.swapIn</strong></mark>, which returns the output amount. The function then calls <mark style="color:red;"><strong>bridgeIn</strong></mark> to handle the bridging of assets, passing the necessary parameters including the fee, asset address, output amount, deposit data hash, and current swap sequence. Finally, the function checks for reentrancy by comparing the current swap sequence with the stored <mark style="color:red;"><strong>swapSequence</strong></mark>. If they do not match, it reverts with a <mark style="color:red;"><strong>ReentrancyError</strong></mark>.</td></tr><tr><td><mark style="color:red;">bridgeIn</mark></td><td>The <mark style="color:red;"><strong>bridgeIn</strong></mark> function in the MagpieCelerBridgeV2 contract handles the bridging of an inbound asset transfer into the contract. It takes several parameters, including the bridge fee, the address of the asset being bridged, the amount of the asset, the encoded hash related to the cross-chain transaction, and the current swap sequence. The function begins by creating an instance of the <mark style="color:red;"><strong>IMessageBus</strong></mark> interface using the stored <mark style="color:red;"><strong>celerAddress</strong></mark>. It retrieves the address of the liquidity bridge from the message bus. If the asset being bridged is not a native token, it approves the liquidity bridge to transfer the specified amount. Next, the function uses inline assembly to extract the receiver address, chain ID, and slippage from the <mark style="color:red;"><strong>calldata</strong></mark>. These values are necessary for the bridging operation. It then calls the send method of the <mark style="color:red;"><strong>ILiquidityBridge</strong></mark> interface, passing the receiver address, asset address, amount, chain ID, current swap sequence, and slippage. This method handles the actual transfer of assets across chains. To ensure the transaction is tracked, the function calculates a <mark style="color:red;"><strong>transferId</strong></mark> by hashing various parameters, including the contract address, receiver address, asset address, amount, chain ID, current swap sequence, and the current chain Id. Finally, the function calls <mark style="color:red;"><strong>sendMessageWithTransfer</strong></mark> on the message bus, passing the bridge fee, receiver address, chain ID, liquidity bridge address, transfer ID, and the encoded deposit data hash. This method sends a message along with the transfer to ensure the transaction is properly recorded and processed.</td></tr><tr><td><mark style="color:red;">swapOut</mark></td><td>The <mark style="color:red;"><strong>swapOut</strong></mark> function in the <mark style="color:red;"><strong>MagpieCelerBridgeV2</strong></mark> contract handles the outbound swap operation. It is restricted to internal callers and returns the amount received from the swap. The function retrieves the network ID and router address using inline assembly and then gets the swap data from <mark style="color:red;"><strong>LibRouter</strong></mark>. It calculates the deposit data hash and retrieves the deposit amount. If the deposit amount is zero and the asset is native, it unwraps the WETH and updates the deposit amount. The function then calls <mark style="color:red;"><strong>LibBridge.swapOut</strong></mark> to perform the swap and returns the output amount.</td></tr><tr><td><mark style="color:red;">executeMessageWithTransfer</mark></td><td>The <mark style="color:red;"><strong>executeMessageWithTransfer</strong></mark> function processes inbound messages with asset transfers. It decodes the deposit data hash from the payload and updates the deposit mapping with the received amount. An event is emitted to log the deposit, and the function returns a success status.</td></tr><tr><td><mark style="color:red;">executeMessageWithTransferRefund</mark></td><td>The <mark style="color:red;"><strong>executeMessageWithTransferRefund</strong></mark> function handles refunds for failed transfers. It decodes the deposit data hash and retrieves the refund address. If the refund address is invalid, it reverts. The function then transfers the refund amount to the receiver and emits a refund event. It returns a success status.</td></tr><tr><td><mark style="color:red;">Multicall</mark></td><td>The <mark style="color:red;"><strong>multicall</strong></mark> function allows the contract owner to execute multiple function calls in a single transaction. It iterates over the provided data array, executing each call using <mark style="color:red;"><strong>Address.functionDelegateCall</strong></mark>, and returns the results.</td></tr><tr><td><mark style="color:red;">receive</mark></td><td><mark style="color:red;"><strong>receive</strong></mark> function handles incoming Ether transfers.</td></tr></tbody></table>


# MagpieRouterV3

The MagpieRouterV3 contract is designed to facilitate token swaps. It inherits from Ownable2Step and Pausable contracts, ensuring controlled access and the ability to pause operations. The contract utilizes various libraries like Address, LibAsset, and LibRouter to handle different asset types and provide utility functions. It includes custom errors and an enums for different command actions, such as calls, approvals, transfers, and balance checks. Key features include functions for updating internal callers and bridge addresses, executing multiple delegate calls in a single transaction, and handling UniswapV3 swap callbacks. The contract also supports various swap operations, including those requiring signatures from Magpie and user, and provides functions for estimating gas, handling permits, and transferring affiliate fees. Additionally, it includes comprehensive command execution functions for calls, approvals, transfers, wrapping and unwrapping tokens, balance checks, mathematical operations, and comparisons, ensuring efficient and secure swap processes. The contract can also accept Ether payments directly.

<table data-full-width="false"><thead><tr><th width="226">Function Name</th><th>Description (Business Logic)</th></tr></thead><tbody><tr><td><mark style="color:red;"><strong>updateInternalCaller</strong></mark> </td><td>The <mark style="color:red;"><strong>updateInternalCaller</strong></mark> function allows the contract owner to update the list of authorized internal callers, emitting an <mark style="color:red;"><strong>UpdateInternalCaller</strong></mark> event upon execution. Similarly, the <mark style="color:red;"><strong>updateBridge</strong></mark> function updates the list of authorized bridge addresses and emits an <mark style="color:red;"><strong>UpdateBridge</strong></mark> event.</td></tr><tr><td><mark style="color:red;"><strong>multical</strong></mark>l </td><td>The <mark style="color:red;"><strong>multicall</strong></mark> function enables the contract owner to execute multiple delegate calls in a single transaction. It iterates over an array of calldata, performing each delegate call and storing the results in an array, which is then returned. This function enhances the contract’s efficiency by allowing batch processing of multiple operations.</td></tr><tr><td><mark style="color:red;"><strong>fallback</strong></mark> </td><td>It includes a <mark style="color:red;"><strong>fallback</strong></mark> function designed to handle <mark style="color:red;"><strong>uniswapV3SwapCallback</strong></mark> requests from any protocol based on UniswapV3. This function does not check for the factory since the contract is not intended to store tokens. Instead, it protects the user by ensuring the <mark style="color:red;"><strong>amountOutMin</strong></mark> check is performed at the end of execution by comparing the starting and final balances at the destination address. The function uses inline assembly to extract parameters from the calldata, such as <mark style="color:red;"><strong>amount0Delta</strong></mark>, <mark style="color:red;"><strong>amount1Delta</strong></mark>, and <mark style="color:red;"><strong>assetIn</strong></mark>. If the calldata size is not 164 bytes or if both <mark style="color:red;"><strong>amount0Delta</strong></mark> and <mark style="color:red;"><strong>amount1Delta</strong></mark> are non-positive, the function reverts with appropriate errors. The function then transfers the calculated amount of <mark style="color:red;"><strong>assetIn</strong></mark> to the caller.</td></tr><tr><td><mark style="color:red;"><strong>getFromAddress</strong></mark> </td><td>The <mark style="color:red;"><strong>getFromAddress</strong></mark> function retrieves the address to be used for a swap operation. It takes <mark style="color:red;"><strong>swapData</strong></mark>, a boolean <mark style="color:red;"><strong>useCaller</strong></mark>, and a boolean <mark style="color:red;"><strong>checkSignature</strong></mark> as parameters. If <mark style="color:red;"><strong>checkSignature</strong></mark> is true, the function constructs a message based on whether the swap data includes an affiliate and verifies the signature using the <mark style="color:red;"><strong>LibRouter.verifySignature</strong></mark> function. If the signature is valid, it returns the address from the swap data. If <mark style="color:red;"><strong>checkSignature</strong></mark> is false and <mark style="color:red;"><strong>useCaller</strong></mark> is true, it returns the caller’s address. Otherwise, it reverts with an <mark style="color:red;"><strong>InvalidCall</strong></mark> error. This function ensures that the correct address is used for the swap operation, providing flexibility and security in handling swap requests.</td></tr><tr><td><mark style="color:red;"><strong>swap</strong></mark> </td><td>The <mark style="color:red;"><strong>swap</strong></mark> function facilitates token swaps based on the provided <mark style="color:red;"><strong>swapData</strong></mark>. It takes the address initiating the swap (<mark style="color:red;"><strong>fromAddress</strong></mark>) and the full amount used for the operation (<mark style="color:red;"><strong>fullAmountIn</strong></mark>). The function calculates the initial balance of the destination address (<mark style="color:red;"><strong>toAddress</strong></mark>) for the output asset (<mark style="color:red;"><strong>toAssetAddress</strong></mark>). It then executes the swap by calling the execute function, which returns the amount transferred and the gas used. The function calculates the final balance of the destination address and determines the amount of tokens received (<mark style="color:red;"><strong>amountOut</strong></mark>). If the received amount is less than the minimum required (<mark style="color:red;"><strong>amountOutMin</strong></mark>), it reverts with an <mark style="color:red;"><strong>InsufficientAmountOut</strong></mark> error. Additionally, it checks if the input amount matches the transferred amount for non-native assets, reverting with an <mark style="color:red;"><strong>InvalidAmountIn</strong></mark> error if they do not match. If <mark style="color:red;"><strong>fullAmountIn</strong></mark> is greater than zero, it emits a <mark style="color:red;"><strong>Swap</strong></mark> event with the relevant details.</td></tr><tr><td><mark style="color:red;"><strong>estimateSwapGas</strong></mark> </td><td>The <mark style="color:red;"><strong>estimateSwapGas</strong></mark> function estimates the gas required for a swap operation. It retrieves the swap data using <mark style="color:red;"><strong>LibRouter.getData()</strong></mark> and determines the address initiating the swap. If the swap data includes a permit, it calls <mark style="color:red;"><strong>LibRouter.permit</strong></mark> to handle the permit. It then transfers any applicable fees using <mark style="color:red;"><strong>LibRouter.transferFees</strong></mark>. Finally, it calls the <mark style="color:red;"><strong>swap</strong></mark> function and returns the amount of tokens received and the gas used.</td></tr><tr><td><mark style="color:red;"><strong>swapWithMagpieSignature</strong></mark> </td><td>The <mark style="color:red;"><strong>swapWithMagpieSignature</strong></mark> function performs a swap operation using Magpie signature. It retrieves the swap data and the address initiating the swap, handles any permits, transfers fees, and calls the <mark style="color:red;"><strong>swap</strong></mark> function. It returns the amount of tokens received.</td></tr><tr><td><mark style="color:red;"><strong>swapWithUserSignature</strong></mark> </td><td>The <mark style="color:red;"><strong>swapWithUserSignature</strong></mark> function allows internal callers to perform a swap operation using a user-provided signature. It retrieves the swap data and the address initiating the swap, ensuring no native tokens are sent with the transaction. It handles any permits, transfers fees, and calls the <mark style="color:red;"><strong>swap</strong></mark> function, returning the amount of tokens received.</td></tr><tr><td><mark style="color:red;"><strong>swapWithoutSignature</strong></mark> </td><td>The <mark style="color:red;"><strong>swapWithoutSignature</strong></mark> function enables bridge addresses to perform a swap operation without requiring a signature. It retrieves the swap data and the address initiating the swap, then calls the <mark style="color:red;"><strong>swap</strong></mark> function, returning the amount of tokens received. This function is restricted to authorized bridge addresses using the <mark style="color:red;"><strong>onlyBridge</strong></mark> modifier.</td></tr><tr><td><mark style="color:red;"><strong>getCommandData</strong></mark> </td><td>The <mark style="color:red;"><strong>getCommandData</strong></mark> function prepares the necessary command data for iterating through a sequence of commands. It uses inline assembly to calculate the offsets and lengths required for processing the commands. Specifically, it calculates the <mark style="color:red;"><strong>commandsOffset</strong></mark> by adding 70 to the shifted value of the calldata at position 68, the <mark style="color:red;"><strong>commandsOffsetEnd</strong></mark> by adding 68 to the calldata at position 36, and the <mark style="color:red;"><strong>outputsLength</strong></mark> by shifting the calldata at position 70. These values are essential for correctly iterating through the commands during the swap operation.</td></tr><tr><td><mark style="color:red;"><strong>execute</strong></mark> </td><td>The <mark style="color:red;"><strong>execute</strong></mark> function handles the execution of a sequence of commands for the swap operation. It takes the address from which the assets will be swapped (<mark style="color:red;"><strong>fromAddress</strong></mark>) and the address of the asset to be swapped (<mark style="color:red;"><strong>fromAssetAddress</strong></mark>). The function retrieves the command data using <mark style="color:red;"><strong>getCommandData</strong></mark> and initializes a pointer for the output data. It then iterates through the commands using a loop, calling the <mark style="color:red;"><strong>executeCommand</strong></mark> function for each command. The <mark style="color:red;"><strong>executeCommand</strong></mark> function returns the amount transferred, the gas used, and updates the output pointer. If the final output pointer exceeds the allocated output length, the function reverts with an <mark style="color:red;"><strong>InvalidOutput</strong></mark> error. This function ensures that the swap operation is executed correctly and efficiently, handling multiple commands in a single transaction.</td></tr><tr><td><mark style="color:red;"><strong>getInput</strong></mark> </td><td><p>The <mark style="color:red;"><strong>getInput</strong></mark> function constructs the input data for a specific command based on its position (<mark style="color:red;"><strong>i</strong></mark>) and the memory pointer of the currently available output (<mark style="color:red;"><strong>outputPtr</strong></mark>). Using inline assembly, the function calculates the end position of the sequences and initializes the input data and native token amount. It iterates through the sequences, processing each one based on its type, such as <mark style="color:red;"><strong>NativeAmount</strong></mark>, <mark style="color:red;"><strong>Selector</strong></mark>, <mark style="color:red;"><strong>Address</strong></mark>, <mark style="color:red;"><strong>Amount</strong></mark>, <mark style="color:red;"><strong>Data</strong></mark>, <mark style="color:red;"><strong>CommandOutput</strong></mark>, <mark style="color:red;"><strong>RouterAddress</strong></mark>, and <mark style="color:red;"><strong>SenderAddress</strong></mark>. For each sequence type, the function performs specific operations: </p><p>• For NativeAmount, it determines the native token amount either from the output pointer or directly from the calldata. </p><p>• For <mark style="color:red;">Selector</mark>, it loads the function selector from the calldata. </p><p>• For <mark style="color:red;"><strong>Address</strong></mark>, it extracts the address from the calldata. </p><p>• For <mark style="color:red;"><strong>Amount</strong></mark>, it calculates the amount from the calldata. </p><p>• For <mark style="color:red;"><strong>Data</strong></mark>, it copies the data from the calldata to the input. </p><p>• For <mark style="color:red;"><strong>CommandOutput</strong></mark>, it loads the output data from the output pointer. </p><p>• For <mark style="color:red;"><strong>RouterAddress</strong></mark>, it stores the contract’s address. </p><p>• For <mark style="color:red;"><strong>SenderAddress</strong></mark>, it stores the caller’s address.</p><p>If an invalid sequence type is encountered, the function reverts with an <mark style="color:red;"><strong>InvalidSequenceType</strong></mark> error. After processing all sequences, it updates the input data length and the free memory pointer. This function ensures that the input data for each command is correctly constructed, enabling the execution of complex operations within the contract.</p></td></tr><tr><td><mark style="color:red;"><strong>executeCommandCall</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandCall</strong></mark> function executes a command call with the given parameters. It retrieves the input data and native token amount using the <mark style="color:red;"><strong>getInput</strong></mark> function. The function then calculates the output length from the calldata and uses a switch statement to handle different selectors. If the selector is invalid or corresponds to a blacklisted <mark style="color:red;"><strong>transferFrom</strong></mark> call, the function reverts with appropriate errors. For valid selectors, it retrieves the target address from the calldata and ensures it is not the contract’s address. It then performs a call to the target address with the provided input data and native amount. If the call fails, it reverts with the returned data. The function updates the output offset pointer and returns the new position.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandApproval</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandApproval</strong></mark> function handles the execution of a command approval. It retrieves the input data using the <mark style="color:red;"><strong>getInput</strong></mark> function and extracts the <mark style="color:red;"><strong>self</strong></mark> address, <mark style="color:red;"><strong>spender</strong></mark> address, and the <mark style="color:red;"><strong>amount</strong></mark> to be approved from the input data. The function then calls the <mark style="color:red;"><strong>approve</strong></mark> method on the <mark style="color:red;"><strong>self</strong></mark> address, allowing the <mark style="color:red;"><strong>spender</strong></mark> to spend the specified <mark style="color:red;"><strong>amount</strong></mark>. This function ensures that the approval operation is executed correctly, enabling subsequent transactions to utilize the approved amount.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandTransferFrom</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandTransferFrom</strong></mark> function facilitates the execution of a transfer command from a specific address and asset. It retrieves the input data using the <mark style="color:red;"><strong>getInput</strong></mark> function and extracts the amount to be transferred from the input data. If the amount is greater than zero, it also extracts the recipient address and performs the transfer from the specified <mark style="color:red;"><strong>fromAddress</strong></mark> to the recipient using the <mark style="color:red;"><strong>transferFrom</strong></mark> method of the <mark style="color:red;"><strong>fromAssetAddress</strong></mark>. The function then updates the accumulated transfer amount and returns it. This ensures that the specified amount of the asset is correctly transferred from the source address to the destination address.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandTransfer</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandTransfer</strong></mark> function handles the execution of a direct transfer command. It retrieves the input data using the <mark style="color:red;"><strong>getInput</strong></mark> function and extracts the amount to be transferred. If the amount is greater than zero, it also extracts the sender (<mark style="color:red;"><strong>self</strong></mark>) and recipient addresses from the input data. The function then performs the <mark style="color:red;"><strong>transfer</strong></mark> from the sender to the recipient using the transfer method. This function ensures that the specified amount is correctly transferred from the sender to the recipient, facilitating the movement of assets within the contract.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandWrap</strong></mark> </td><td>The executeCommandWrap function handles the execution of a wrap command, which is used to wrap native tokens. It retrieves the input data using the getInput function and extracts the self address and the amount to be wrapped from the input data. The function then calls the wrap method on the self address with the specified amount, ensuring that the native tokens are correctly wrapped.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandUnwrap</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandUnwrap</strong></mark> function is responsible for executing an unwrap command, which is used to unwrap native tokens. Similar to the wrap function, it retrieves the input data and extracts the <mark style="color:red;"><strong>self</strong></mark> address and the <mark style="color:red;"><strong>amount</strong></mark> to be unwrapped. The function then calls the <mark style="color:red;"><strong>unwrap</strong></mark> method on the <mark style="color:red;"><strong>self</strong></mark> address with the specified amount, ensuring that the native tokens are correctly unwrapped.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandBalance</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandBalance</strong></mark> function executes a balance command and returns the resulting balance. It retrieves the input data using the <mark style="color:red;"><strong>getInput</strong></mark> function and extracts the <mark style="color:red;"><strong>self</strong></mark> address. The function then calls the <mark style="color:red;"><strong>getBalance</strong></mark> method on the <mark style="color:red;"><strong>self</strong></mark> address to retrieve the balance. The balance is stored at the output offset pointer in memory, and the function updates the output offset pointer before returning it. This function ensures that the balance of the specified address is correctly retrieved and stored for further use in the contract.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandMath</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandMath</strong></mark> function executes a mathematical command based on the provided parameters. It retrieves the input data using the <mark style="color:red;"><strong>getInput</strong></mark> function and defines a nested assembly function, <mark style="color:red;"><strong>math</strong></mark>, to perform various mathematical operations. The function iterates through a set of commands, processing each one based on its operator type, such as addition, subtraction, multiplication, division, power, absolute value (both 128-bit and 256-bit), bitwise shift right, and bitwise shift left. For each operator, the function retrieves the operands from either the current output pointer or the input data, performs the specified operation, and stores the result in the current output pointer. If an invalid operator is encountered, the function reverts with an <mark style="color:red;"><strong>InvalidSequenceType</strong></mark> error. After processing all commands, the function updates the output offset pointer and returns it. This function ensures that complex mathematical operations can be executed efficiently within the contract, supporting a wide range of arithmetic and bitwise operations.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandComparison</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandComparison</strong></mark> function executes a comparison command based on the provided parameters. It retrieves the input data using the <mark style="color:red;"><strong>getInput</strong></mark> function and defines a nested assembly function, <mark style="color:red;"><strong>comparison</strong></mark>, to perform various comparison operations. The function iterates through a set of commands, processing each one based on its operator type, such as less than (<mark style="color:red;"><strong>Lt</strong></mark>), less than or equal to (<mark style="color:red;"><strong>Lte</strong></mark>), greater than (<mark style="color:red;"><strong>Gt</strong></mark>), greater than or equal to (<mark style="color:red;"><strong>Gte</strong></mark>), equal to (<mark style="color:red;"><strong>Eq</strong></mark>), and not equal to (<mark style="color:red;"><strong>Ne</strong></mark>). For each operator, the function retrieves the operands from either the current output pointer or the input data, performs the specified comparison, and stores the result in the current output pointer. If an invalid operator is encountered, the function reverts with an <mark style="color:red;"><strong>InvalidSequenceType</strong></mark> error. After processing all commands, the function updates the output offset pointer and returns it. This function ensures that complex comparison operations can be executed efficiently within the contract, supporting a wide range of relational operations to facilitate decision-making processes in the contract’s logic.</td></tr><tr><td><mark style="color:red;"><strong>executeCommand</strong></mark> </td><td><p>The <mark style="color:red;"><strong>executeCommand</strong></mark> function is a comprehensive handler for executing various commands within the swap operation. It takes several parameters, including the command data position (<mark style="color:red;"><strong>i</strong></mark>), the address from which assets will be transferred (<mark style="color:red;"><strong>fromAddress</strong></mark>), the asset address (<mark style="color:red;"><strong>fromAssetAddress</strong></mark>), and pointers for output memory (<mark style="color:red;"><strong>outputPtr</strong></mark> and <mark style="color:red;"><strong>outputOffsetPtr</strong></mark>). It also tracks the accumulated transferred amount (<mark style="color:red;"><strong>transferFromAmount</strong></mark>) and the gas used (<mark style="color:red;"><strong>gasUsed</strong></mark>). The function begins by determining the type of command to execute using the <mark style="color:red;"><strong>CommandAction</strong></mark> enumeration. Depending on the command type, it calls the appropriate function to handle the command: • Call: Executes a generic function call using <mark style="color:red;">executeCommandCall</mark>. </p><p>• Approval: Handles token approval operations with <mark style="color:red;"><strong>executeCommandApproval</strong></mark>. </p><p>• TransferFrom: Executes a transfer from a specific address using <mark style="color:red;"><strong>executeCommandTransferFrom</strong></mark>.</p><p>• Transfer: Executes a direct transfer with <mark style="color:red;">executeCommandTransfer</mark>. </p><p>• Wrap: Wraps native tokens using <mark style="color:red;"><strong>executeCommandWrap</strong></mark>. </p><p>• Unwrap: Unwraps native tokens with <mark style="color:red;"><strong>executeCommandUnwrap</strong></mark>. </p><p>• Balance: Retrieves the balance of an address using <mark style="color:red;"><strong>executeCommandBalance</strong></mark>. </p><p>• Math: Performs mathematical operations with <mark style="color:red;"><strong>executeCommandMath</strong></mark>. </p><p>• Comparison: Executes comparison operations using <mark style="color:red;"><strong>executeCommandComparison</strong></mark>. </p><p>• EstimateGasStart: Records the starting gas for estimation. </p><p>• EstimateGasEnd: Calculates the gas used by subtracting the remaining gas from the starting gas.</p><p>If an invalid command is encountered, the function reverts with an <mark style="color:red;"><strong>InvalidCommand</strong></mark> error. The function returns the updated values for <mark style="color:red;"><strong>transferFromAmount</strong></mark>, <mark style="color:red;"><strong>gasUsed</strong></mark>, and <mark style="color:red;"><strong>outputOffsetPtr</strong></mark>, ensuring that the swap operation is executed correctly and efficiently.</p></td></tr><tr><td><mark style="color:red;"><strong>receive</strong></mark> </td><td><mark style="color:red;"><strong>receive</strong></mark> function handles incoming Ether transfers.</td></tr></tbody></table>


# MagpieStargateBridgeV3

The MagpieStargateBridgeV3 contract is designed for cross-chain communication and asset bridging using the Stargate bridge. It inherits from Ownable2Step and Pausable contracts, providing ownership management and pausing capabilities. The contract uses several libraries and interfaces to manage assets and facilitate swaps and deposits. Key features include state variables for tracking internal callers, asset mappings, and deposits, as well as functions for updating these mappings and addresses. It has functions for performing swaps with Magpie or user signatures, verifying signatures, and handling inbound and outbound asset transfers. The contract also includes functions for executing multiple calls in a single transaction, receiving Ether, and composing LayerZero messages. Overall, it provides a comprehensive framework for secure and efficient cross-chain asset management.

<table><thead><tr><th width="241">Function Name</th><th>Description (Business Logic)</th></tr></thead><tbody><tr><td><mark style="color:red;"><strong>updateInternalCaller</strong></mark> </td><td>The <mark style="color:red;"><strong>updateInternalCaller</strong></mark> function allows the owner to update the internal caller list, emitting an <mark style="color:red;"><strong>UpdateInternalCaller</strong></mark> event upon changes. The <mark style="color:red;"><strong>updateWeth</strong></mark> function allows the owner to update the WETH address. The <mark style="color:red;"><strong>updateNetworkIdAndRouterAddress</strong></mark> function allows the owner to update the network ID and router address. The <mark style="color:red;"><strong>updateAssetToStargate</strong></mark> and <mark style="color:red;"><strong>updateStargateToAsset</strong></mark> functions allow the owner to update the mappings between assets and Stargate addresses, emitting corresponding events. The <mark style="color:red;"><strong>updateLzAddress</strong></mark> function allows the owner to update the LayerZero address.</td></tr><tr><td><mark style="color:red;"><strong>swapInWithMagpieSignature</strong></mark> </td><td>The <mark style="color:red;"><strong>swapInWithMagpieSignature</strong></mark> function allows users to perform a swap operation using a Magpie signature. This function can be called externally and requires a calldata parameter. It is payable and can only be executed when the contract is not paused. The function retrieves swap data using the <mark style="color:red;"><strong>LibRouter.getData</strong></mark> method and then calls the <mark style="color:red;"><strong>swapIn</strong></mark> function with the retrieved data and a boolean flag set to true, indicating that the swap is performed with a Magpie signature. The function returns the amount of output tokens received from the swap.</td></tr><tr><td><mark style="color:red;"><strong>swapInWithUserSignature</strong></mark> </td><td>The <mark style="color:red;"><strong>swapInWithUserSignature</strong></mark> function is similar but is restricted to internal callers only, as enforced by the <mark style="color:red;"><strong>onlyInternalCaller</strong></mark> modifier. This function also retrieves swap data using the <mark style="color:red;"><strong>LibRouter.getData</strong></mark> method. However, it includes an additional check to ensure that the <mark style="color:red;"><strong>fromAssetAddress</strong></mark> in the swap data is not a native asset, reverting with an <mark style="color:red;"><strong>InvalidAddress</strong></mark> error if this condition is met. The function then calls the <mark style="color:red;"><strong>swapIn</strong></mark> function with the retrieved data and a boolean flag set to false, indicating that the swap is performed with a user signature. The function returns the amount of output tokens received from the swap.</td></tr><tr><td><mark style="color:red;"><strong>verifySignature</strong></mark> </td><td>The <mark style="color:red;"><strong>verifySignature</strong></mark> function is a private view function that verifies the signature for a swap operation. It takes two parameters: <mark style="color:red;"><strong>swapData</strong></mark>, which is a struct containing the details of the swap, and <mark style="color:red;"><strong>useCaller</strong></mark>, a boolean flag indicating whether to use the caller’s address for verification. The function returns the address of the signer if the signature is valid. The function begins by determining the length of the message based on whether the swap data includes an affiliate. It then uses inline assembly to construct the message that will be hashed and verified. Depending on the presence of an affiliate, it stores the appropriate keccak256 hash of the swap message structure in memory. The function then loads various fields from the calldata into memory, including addresses and amounts related to the swap. Finally, the function calls <mark style="color:red;"><strong>LibRouter.verifySignature</strong></mark> with the constructed message and other relevant parameters to verify the signature. If the signature is valid, the function returns the address of the signer.</td></tr><tr><td><mark style="color:red;"><strong>swapIn</strong></mark> </td><td>The <mark style="color:red;"><strong>swapIn</strong></mark> function executes an inbound swap operation. It increments the <mark style="color:red;"><strong>swapSequence</strong></mark> and stores the current sequence. Using inline assembly, it retrieves the network ID and router address from the <mark style="color:red;"><strong>networkIdAndRouterAddress</strong></mark> state variable. The function then verifies the signature of the swap data using the <mark style="color:red;"><strong>verifySignature</strong></mark> function. If the swap data includes a permit, it calls LibRouter.permit to handle the permit. It also transfers any applicable fees using <mark style="color:red;"><strong>LibRouter.transferFees</strong></mark>. The function constructs the encoded deposit data and calculates its hash. It then calls <mark style="color:red;"><strong>LibBridge.swapIn</strong></mark> to perform the swap and subsequently calls <mark style="color:red;"><strong>bridgeIn</strong></mark> to handle the bridging process. If the <mark style="color:red;"><strong>swapSequence</strong></mark> has changed during execution, it reverts with a <mark style="color:red;"><strong>ReentrancyError</strong></mark>.</td></tr><tr><td><mark style="color:red;"><strong>getExtraOptions</strong></mark> </td><td>The <mark style="color:red;"><strong>getExtraOptions</strong></mark> function retrieves extra options for the <mark style="color:red;"><strong>SendParam</strong></mark> struct, encoding them as bytes. It constructs the options with a gas limit and returns the encoded bytes.</td></tr><tr><td><mark style="color:red;"><strong>getSendParam</strong></mark> </td><td>The <mark style="color:red;"><strong>getSendParam</strong></mark> function constructs a <mark style="color:red;"><strong>SendParam</strong></mark> struct with the specified amount and encoded deposit data hash. It uses inline assembly to retrieve the receiver address, destination endpoint ID, and gas limit from the calldata. It then returns the constructed <mark style="color:red;"><strong>SendParam</strong></mark> struct, including the extra options and encoded deposit data hash.</td></tr><tr><td><mark style="color:red;"><strong>bridgeIn</strong></mark> </td><td>The <mark style="color:red;"><strong>bridgeIn</strong></mark> function facilitates the inbound transfer of assets into the contract. It takes several parameters, including the bridge fee, refund address, target asset address, amount, and a deposit data hash. The function first retrieves the corresponding Stargate address for the asset. If the address is invalid, it reverts with an <mark style="color:red;"><strong>InvalidStargateAddress</strong></mark> error. It calculates the total value to send, including the bridge fee and, if the asset is native, the amount. For non-native assets, it approves the transfer to the Stargate address. The function constructs a <mark style="color:red;"><strong>SendParam</strong></mark> struct using the <mark style="color:red;"><strong>getSendParam</strong></mark> function and then interacts with the Stargate contract to quote the amount received and send the token, including the bridge fee and refund address.</td></tr><tr><td><mark style="color:red;"><strong>swapOut</strong></mark> </td><td>The <mark style="color:red;"><strong>swapOut</strong></mark> function allows internal callers to execute an outbound swap operation. It retrieves the network ID and router address using inline assembly. The function then obtains swap data and calculates the deposit data hash. It checks if the deposit amount is available; if not, it reverts with a <mark style="color:red;"><strong>DepositIsNotFound</strong></mark> error. The function resets the deposit amount to zero and calls <mark style="color:red;"><strong>LibBridge.swapOut</strong></mark> to perform the swap, returning the amount of output tokens received.</td></tr><tr><td><mark style="color:red;"><strong>getDepositAmount</strong></mark> </td><td>The <mark style="color:red;"><strong>getDepositAmount</strong></mark> function is a private pure function that extracts and returns the deposit amount from an encoded bytes array. It uses inline assembly to load the amount from the specified position in the bytes array.</td></tr><tr><td><mark style="color:red;"><strong>lzCompose</strong></mark> </td><td>The <mark style="color:red;"><strong>lzCompose</strong></mark> function handles the composition of LayerZero messages. It verifies the sender and the asset address, ensuring they match the expected values. If the checks pass, it decodes the deposit data hash from the message and updates the deposit amount for the corresponding asset. The function emits a <mark style="color:red;"><strong>Deposit</strong></mark> event with the deposit data hash and the updated deposit amount.</td></tr><tr><td><mark style="color:red;"><strong>multicall</strong></mark> </td><td>The <mark style="color:red;"><strong>multicall</strong></mark> function allows the contract owner to execute multiple function calls in a single transaction. It takes an array of calldata and iterates through each element, performing a delegate call to the contract itself. The results of each call are stored in an array, which is returned at the end.</td></tr><tr><td><mark style="color:red;"><strong>receive</strong></mark> </td><td><mark style="color:red;"><strong>receive</strong></mark> function handles incoming Ether transfers.</td></tr></tbody></table>


# MagpieSymbiosisBridge

The MagpieSymbiosisBridge contract is designed to facilitate cross-chain liquidity aggregation using the Symbiosis bridge, integrating multiple external libraries and interfaces. It inherits from Ownable2Step and Pausable contracts, providing ownership management and pausing capabilities. The contract manages various addresses and mappings to track internal callers, deposits, and configurations. Key features include functions for updating internal callers and addresses, initiating swap transactions with Magpie or user signatures, verifying signatures, and handling inbound and outbound bridging processes. It also includes functions for pausing and unpausing the contract, withdrawing ERC20 tokens, and handling Ether transfers. The contract ensures secure and efficient cross-chain operations with detailed logging and event emission for transparency and traceability.

<table data-full-width="false"><thead><tr><th width="267">Function Name</th><th>Description (Business Logic)</th></tr></thead><tbody><tr><td><mark style="color:red;"><strong>updateInternalCaller</strong></mark> </td><td>The <mark style="color:red;"><strong>updateInternalCaller</strong></mark> function allows the owner to update the list of internal callers, emitting an event to log the changes. The <mark style="color:red;"><strong>updateWeth</strong></mark>, <mark style="color:red;"><strong>updateNetworkIdAndRouterAddress</strong></mark>, <mark style="color:red;"><strong>updatePortalAddress</strong></mark>, <mark style="color:red;"><strong>updateGatewayAddress</strong></mark>, and <mark style="color:red;"><strong>updateGasReceiverAddress</strong></mark> functions enable the owner to update respective addresses and configurations, ensuring the contract can adapt to changes in the underlying infrastructure or requirements.</td></tr><tr><td><mark style="color:red;">swapInWithMagpieSignature</mark> </td><td>The <mark style="color:red;"><strong>swapInWithMagpieSignature</strong></mark> function allows users to initiate a swap transaction using a Magpie signature. This function can only be executed when the contract is not paused, ensuring that operations are halted during maintenance or emergencies. It retrieves swap data using the <mark style="color:red;"><strong>LibRouter.getData</strong></mark> function and then calls the <mark style="color:red;"><strong>swapIn</strong></mark> function with the retrieved data and a boolean flag set to <mark style="color:red;"><strong>true</strong></mark>, indicating that a Magpie signature is being used. The function returns the amount of tokens received from the swap.</td></tr><tr><td><mark style="color:red;"><strong>swapInWithUserSignature</strong></mark> </td><td>The <mark style="color:red;"><strong>swapInWithUserSignature</strong></mark> function, on the other hand, is restricted to internal callers through the <mark style="color:red;"><strong>onlyInternalCaller</strong></mark> modifier. This function also retrieves swap data using LibRouter.getData. However, it includes an additional check to ensure that the <mark style="color:red;"><strong>fromAssetAddress</strong></mark> is not a native asset, reverting the transaction with an <mark style="color:red;"><strong>InvalidAddress</strong></mark> error if this condition is met. The function then calls <mark style="color:red;"><strong>swapIn</strong></mark> with the retrieved data and a boolean flag set to <mark style="color:red;"><strong>false</strong></mark>, indicating that a user signature is being used. It returns the amount of tokens received from the swap.</td></tr><tr><td><mark style="color:red;"><strong>verifySignature</strong></mark> </td><td>The <mark style="color:red;"><strong>verifySignature</strong></mark> function is designed to verify the signature for a swap operation by constructing a message from the provided <mark style="color:red;"><strong>SwapData</strong></mark> and checking it against the expected signature. The function begins by determining the length of the message based on whether the swap includes an affiliate. Using inline assembly, it constructs the message by loading various pieces of data from the calldata into memory, including addresses, amounts, and other relevant details. The function handles both the presence and absence of an affiliate by storing the appropriate keccak256 hash in memory. It then loads data such as <mark style="color:red;"><strong>toAddress</strong></mark>, <mark style="color:red;"><strong>fromAssetAddress</strong></mark>, <mark style="color:red;"><strong>toAssetAddress</strong></mark>, <mark style="color:red;"><strong>amountOutMin</strong></mark>, <mark style="color:red;"><strong>gasFee</strong></mark>, <mark style="color:red;"><strong>recipientNetworkId</strong></mark>, <mark style="color:red;"><strong>recipientAddress</strong></mark>, <mark style="color:red;"><strong>synthesisAddress</strong></mark>, <mark style="color:red;"><strong>symbiosisAddress</strong></mark>, <mark style="color:red;"><strong>bridgeFee</strong></mark>, <mark style="color:red;"><strong>chainId</strong></mark>, and <mark style="color:red;"><strong>clientId</strong></mark> into the message. Additionally, it processes the <mark style="color:red;"><strong>destinationAddress</strong></mark> and <mark style="color:red;"><strong>destinationChain</strong></mark> by copying their lengths and values into memory and computing their keccak256 hashes. Finally, the function calls <mark style="color:red;"><strong>LibRouter.verifySignature</strong></mark> with the constructed message and other parameters to verify the signature. If the signature is valid, it returns the address of the signer, ensuring the integrity and authenticity of the swap operation.</td></tr><tr><td><mark style="color:red;"><strong>swapIn</strong></mark> </td><td>The <mark style="color:red;"><strong>swapIn</strong></mark> function executes an inbound swap operation, handling the entire process from verifying the signature to transferring fees and performing the swap. It begins by incrementing the <mark style="color:red;"><strong>swapSequence</strong></mark> to ensure each swap has a unique identifier. Using inline assembly, it retrieves the <mark style="color:red;"><strong>networkId</strong></mark> and <mark style="color:red;"><strong>routerAddress</strong></mark> from the stored <mark style="color:red;"><strong>networkIdAndRouterAddress</strong></mark> variable. The function then verifies the signature of the swap data using the <mark style="color:red;"><strong>verifySignature</strong></mark> function. If the swap data includes a permit, it calls <mark style="color:red;"><strong>LibRouter.permit</strong></mark> to handle the permit process. It also transfers any associated fees using <mark style="color:red;"><strong>LibRouter.transferFees</strong></mark>. Next, the function prepares the encoded deposit data and calculates its hash. It calls <mark style="color:red;"><strong>LibBridge.swapIn</strong></mark> to perform the actual swap, passing the necessary parameters including the encoded deposit data, the verified address, the router address, and the WETH address. The <mark style="color:red;"><strong>bridgeIn</strong></mark> function is then called to handle the bridging process, including transferring the fee and updating the deposit data hash. Finally, the function checks for reentrancy by comparing the current <mark style="color:red;"><strong>swapSequence</strong></mark> with the incremented value. If they do not match, it reverts the transaction with a <mark style="color:red;"><strong>ReentrancyError</strong></mark>. The function emits a <mark style="color:red;"><strong>BridgeIn</strong></mark> event to log the details of the inbound swap operation.</td></tr><tr><td><mark style="color:red;"><strong>bridgeIn</strong></mark> </td><td>The <mark style="color:red;"><strong>bridgeIn</strong></mark> function facilitates the bridging of an inbound asset transfer into the contract. It takes several parameters, including the transfer fee, refund address, asset address, amount, and a deposit data hash. The function begins by approving the <mark style="color:red;"><strong>portalAddress</strong></mark> to spend the specified amount of the asset. Using inline assembly, it retrieves the bridge fee and other necessary data from the calldata. It constructs a call to the synthesize function, passing in the bridge fee, asset address, amount, receiver address, <mark style="color:red;"><strong>synthesis</strong></mark> address, symbiosis address, refund address, chain ID, and client ID. If the execution of this call fails, the function reverts with a <mark style="color:red;"><strong>SynthesisFailed</strong></mark> error. The function then calls <mark style="color:red;"><strong>dataIn</strong></mark> to handle the transfer fee, deposit data hash, net amount (amount minus bridge fee), asset address, and refund address. Finally, it retrieves the <mark style="color:red;"><strong>crosschainId</strong></mark> from the assembly block and emits a <mark style="color:red;"><strong>BridgeIn</strong></mark> event to log the details of the inbound asset transfer. This ensures that the bridging process is securely executed and properly recorded.</td></tr><tr><td><mark style="color:red;"><strong>dataIn</strong></mark> </td><td>The <mark style="color:red;"><strong>dataIn</strong></mark> function executes an inbound data transfer by taking parameters such as the transfer fee, deposit data hash, amount, asset address, and refund address. It begins by creating a payload and initializing strings for the destination address and chain. Using inline assembly, it retrieves the destination address and chain from the calldata, copies their lengths and values into memory, and constructs the payload with the deposit data hash, amount, and asset address. The function then calls <mark style="color:red;"><strong>IAxelarGasService</strong></mark> to pay the native gas fee for the contract call and <mark style="color:red;"><strong>IAxelarGateway</strong></mark> to execute the contract call to the destination chain and address. If the operation fails, tokens are transferred to the refund address. Finally, the function emits a <mark style="color:red;"><strong>Deposit</strong></mark> event to log the details of the inbound data transfer.</td></tr><tr><td><mark style="color:red;"><strong>execute</strong></mark> </td><td>The <mark style="color:red;"><strong>execute</strong></mark> function handles the execution of cross-chain commands by validating the contract call through the <mark style="color:red;"><strong>IAxelarGateway</strong></mark>. It takes parameters such as the command ID, source chain, source address, and payload. If the validation fails, the function reverts with a <mark style="color:red;"><strong>NotApprovedByGateway</strong></mark> error. Upon successful validation, it calls the <mark style="color:red;"><strong>addDeposit</strong></mark> function to process the payload.</td></tr><tr><td><mark style="color:red;">addDeposit</mark> </td><td>The <mark style="color:red;"><strong>addDeposit</strong></mark> function extracts the deposit data hash, amount, and asset address from the payload using inline assembly and updates the deposit mapping accordingly. It then emits a <mark style="color:red;"><strong>Deposit</strong></mark> event to log the details of the validated deposit, ensuring the integrity and traceability of the cross-chain transaction.</td></tr><tr><td><mark style="color:red;"><strong>swapOut</strong></mark> </td><td>The <mark style="color:red;"><strong>swapOut</strong></mark> function facilitates the outbound swap of assets, restricted to internal callers. It retrieves the network ID and router address using inline assembly, then obtains swap data via <mark style="color:red;"><strong>LibRouter.getData</strong></mark>. The function calculates the deposit data hash and checks the deposit amount. If no deposit is found, it reverts with a <mark style="color:red;"><strong>DepositIsNotFound</strong></mark> error. Otherwise, it resets the deposit amount to zero and calls <mark style="color:red;"><strong>LibBridge.swapOut</strong></mark> to execute the swap, returning the amount received from the swap.</td></tr><tr><td><mark style="color:red;"><strong>multicall</strong></mark> </td><td>The <mark style="color:red;"><strong>multicall</strong></mark> function allows the contract owner to execute multiple delegate calls in a single transaction. It takes an array of calldata, iterates through each item, and performs a delegate call to the contract itself using Address.<mark style="color:red;"><strong>functionDelegateCall</strong></mark>. The results of each call are stored in an array, which is then returned. This function enables batch processing of multiple operations, enhancing efficiency and reducing transaction costs.</td></tr></tbody></table>


# LibAsset

This contract defines a library called LibAsset which provides utility functions for handling assets, particularly focusing on native assets like Ether. The library includes several custom error types for handling various failure scenarios such as AssetNotReceived, ApprovalFailed, TransferFromFailed, TransferFailed, PermitFailed, FailedWrap, and FailedUnwrap. The isNative function checks if a given address represents a native asset (Ether) by comparing it to a constant NATIVE\_ASSETID, which is set to the zero address. The wrap function is designed to wrap a specified asset by using inline assembly to prepare a call to the asset’s contract. If the wrapping operation fails, it reverts with a FailedWrap error. Similarly, the unwrap function unwraps a specified asset, also using inline assembly to prepare the call and reverting with a FailedUnwrap error if the operation fails. Lastly, the getBalance function retrieves the balance of the current contract for a given asset by calling another internal function getBalanceOf.

<table data-full-width="false"><thead><tr><th width="210">Function Name</th><th>Description (Business Logic)</th></tr></thead><tbody><tr><td><mark style="color:red;"><strong>getBalanceOf</strong></mark> </td><td>The <mark style="color:red;"><strong>getBalanceOf</strong></mark> function retrieves the balance of a specified asset for a target address. It uses inline assembly to handle both native assets (Ether) and other ERC-20 tokens. For native assets, it directly retrieves the balance using the <mark style="color:red;"><strong>balance</strong></mark> opcode. For ERC-20 tokens, it constructs a call to the <mark style="color:red;"><strong>balanceOf</strong></mark> function of the token contract, passing the target address as an argument. If the call fails, it reverts with the returned data.</td></tr><tr><td><mark style="color:red;"><strong>transferFrom</strong></mark> </td><td>The <mark style="color:red;"><strong>transferFrom</strong></mark> function performs a safe transfer of a specified asset from one address to another. It uses inline assembly to prepare a call to the <mark style="color:red;"><strong>transferFrom</strong></mark> function of the asset’s contract, passing the sender’s address, the recipient’s address, and the amount to be transferred. If the transfer operation fails, it reverts with a <mark style="color:red;"><strong>TransferFromFailed</strong></mark> error. This function ensures that asset transfers are handled securely and correctly.</td></tr><tr><td><mark style="color:red;"><strong>transfer</strong></mark> </td><td>The <mark style="color:red;"><strong>transfer</strong></mark> function facilitates the transfer of a specified amount of an asset to a recipient address. If the asset is native (Ether), it uses a low-level call to transfer the amount directly. If the transfer fails, it reverts with a <mark style="color:red;"><strong>TransferFailed</strong></mark> error. For non-native assets, it constructs a call to the <mark style="color:red;"><strong>transfer</strong></mark> function of the asset’s contract using inline assembly. If the transfer operation fails, it also reverts with a <mark style="color:red;"><strong>TransferFailed</strong></mark> error. This function ensures that both native and non-native asset transfers are handled securely.</td></tr><tr><td><mark style="color:red;"><strong>approve</strong></mark> </td><td>The <mark style="color:red;"><strong>approve</strong></mark> function allows a spender address to spend a specified amount of an asset on behalf of the owner. It constructs a call to the <mark style="color:red;"><strong>approve</strong></mark> function of the asset’s contract using inline assembly. If the approval operation fails, it attempts to reset the allowance to zero and then re-approve the specified amount. If these attempts fail, it reverts with an <mark style="color:red;"><strong>ApprovalFailed</strong></mark> error. This function ensures that the approval process is robust and handles potential issues with resetting allowances.</td></tr><tr><td><mark style="color:red;"><strong>permit</strong></mark></td><td>The <mark style="color:red;"><strong>permit</strong></mark> function allows for the approval of a spender to spend a specified amount of an asset on behalf of the owner, using a signature. This function is useful for ERC-20 tokens that support the <mark style="color:red;"><strong>permit</strong></mark> function, enabling gasless approvals. It constructs a call to the <mark style="color:red;"><strong>permit</strong></mark> function of the asset’s contract using inline assembly, passing the owner’s address, spender’s address, amount, deadline, and the signature components (v, r, s). If the permit operation fails, it reverts with a <mark style="color:red;"><strong>PermitFailed</strong></mark> error.</td></tr><tr><td><mark style="color:red;"><strong>isSuccessful</strong></mark> </td><td>The <mark style="color:red;"><strong>isSuccessful</strong></mark> function checks if a call to a target contract was successful. It takes the target address, a success flag, and the returned data as inputs. If the call was successful and the returned data is empty, it checks if the target address is a contract by verifying the code length. If the returned data is not empty, it loads the result from the data using inline assembly. This function ensures that the success of a call is accurately determined, handling both contract and non-contract addresses.</td></tr><tr><td><mark style="color:red;"><strong>execute</strong></mark> </td><td>The <mark style="color:red;"><strong>execute</strong></mark> function performs a low-level call to a target contract, handling both native and non-native assets. It uses inline assembly to construct and execute the call, passing the necessary parameters such as the target address (<mark style="color:red;"><strong>self</strong></mark>), the amount of native asset to send (<mark style="color:red;"><strong>currentNativeAmount</strong></mark>), and pointers to the input and output data. The function includes an internal helper function, <mark style="color:red;"><strong>isSuccessfulCall</strong></mark>, which determines if the call was successful by checking the return data size and the existence of code at the target address. If the call fails, it reverts with the returned data. This function ensures that low-level calls are executed safely and correctly, providing a robust mechanism for interacting with other contracts.</td></tr></tbody></table>


# LibBridge

The LibBridge library integrates several interfaces and libraries essential for its functionality, such as IMagpieRouterV3, IBridge, LibAsset, and LibRouter. It defines a DepositData struct to manage deposit details and includes custom error types to handle various error scenarios. The library uses LibAsset for address operations and includes functions like getFee, decodeDepositDataHash, encodeDepositDataHash, and getDepositDataHash to manage deposit data and fees. The fillEncodedDepositData function populates variables with encoded deposit data, while the swap and swapIn functions handle swap operations using specified routers and amounts. The swapOut function manages outbound swaps, verifying deposit amounts and handling different asset scenarios, and emits events detailing the swap operations.

<table data-full-width="false"><thead><tr><th width="246">Function Name</th><th>Description (Business Logic)</th></tr></thead><tbody><tr><td><mark style="color:red;"><strong>decodeDepositDataHash</strong></mark></td><td>This function converts a deposit data hash from a <mark style="color:red;"><strong>bytes</strong></mark> format to a <mark style="color:red;"><strong>bytes32</strong></mark> format. This conversion is essential for handling and verifying deposit data within the contract.</td></tr><tr><td><mark style="color:red;"><strong>encodeDepositDataHash</strong></mark></td><td>This function converts a deposit data hash from a <mark style="color:red;"><strong>bytes32</strong></mark> format back to a <mark style="color:red;"><strong>bytes</strong></mark> format. This is useful for encoding deposit data for storage or transmission.</td></tr><tr><td><mark style="color:red;"><strong>getDepositDataHash</strong></mark></td><td>This function generates a unique hash for the deposit data by assembling various pieces of information from the <mark style="color:red;"><strong>SwapData</strong></mark> struct and other parameters. It ensures the integrity and uniqueness of the deposit data, which is crucial for tracking and verifying deposits accurately.</td></tr><tr><td><mark style="color:red;"><strong>fillEncodedDepositData</strong></mark> </td><td>The <mark style="color:red;"><strong>fillEncodedDepositData</strong></mark> function is designed to populate a given variable with encoded deposit data. It takes three parameters: <mark style="color:red;"><strong>encodedDepositData</strong></mark>, which is the placeholder for the deposit data, <mark style="color:red;"><strong>networkId</strong></mark>, which identifies the sender’s network, and <mark style="color:red;"><strong>swapSequence</strong></mark>, which is the current swap sequence number. The function uses inline assembly to copy the deposit data into the specified variable and then appends the network ID, the address, and the swap sequence to the encoded data.</td></tr><tr><td><mark style="color:red;"><strong>swap</strong></mark> </td><td>The <mark style="color:red;"><strong>swap</strong></mark> function executes a swap operation using a specified router and a given amount of native currency. It takes the router’s address and the native amount as parameters and returns the amount received from the swap operation and a success flag. The function uses inline assembly to prepare the input data for the swap, including the function selector for <mark style="color:red;"><strong>swapWithoutSignature</strong></mark>, and then performs the call to the router. If the call is successful, it retrieves the output amount from the response.</td></tr><tr><td><mark style="color:red;"><strong>swapIn</strong></mark> </td><td>The <mark style="color:red;"><strong>swapIn</strong></mark> function executes an inbound swap operation using the provided data and addresses. It takes several parameters: <mark style="color:red;"><strong>swapData</strong></mark>, which contains the details of the swap; <mark style="color:red;"><strong>encodedDepositData</strong></mark>, which holds the encoded deposit data; <mark style="color:red;"><strong>fromAddress</strong></mark>, the address from which the swap originates; <mark style="color:red;"><strong>routerAddress</strong></mark>, the address of the router contract for the swap; and <mark style="color:red;"><strong>weth</strong></mark>, the address of the Wrapped Ether contract. The function returns the amount received as output from the swap operation. The function first checks if the <mark style="color:red;"><strong>toAddress</strong></mark> in <mark style="color:red;"><strong>swapData</strong></mark> matches the current contract address, reverting with an <mark style="color:red;"><strong>InvalidToAddress</strong></mark> error if it does not. It then verifies if the <mark style="color:red;"><strong>fromAssetAddress</strong></mark> is native and if the <mark style="color:red;"><strong>msg.value</strong></mark> is less than the <mark style="color:red;"><strong>amountIn</strong></mark>, reverting with an <mark style="color:red;"><strong>InvalidAmountIn</strong></mark> error if true. Depending on the asset addresses involved, the function performs different operations. If the fromAssetAddress is native and the <mark style="color:red;"><strong>toAssetAddress</strong></mark> is <mark style="color:red;"><strong>weth</strong></mark>, it wraps the native amount into <mark style="color:red;"><strong>weth</strong></mark>. If the <mark style="color:red;"><strong>fromAssetAddress</strong></mark> is <mark style="color:red;"><strong>weth</strong></mark> and the <mark style="color:red;"><strong>toAssetAddress</strong></mark> is native, it transfers the <mark style="color:red;"><strong>weth</strong></mark> from the <mark style="color:red;"><strong>fromAddress</strong></mark> to the contract and unwraps it. If both asset addresses are the same, it simply transfers the amount from the <mark style="color:red;"><strong>fromAddress</strong></mark> to the contract. For other cases, it handles the swap operation by transferring the <mark style="color:red;"><strong>fromAssetAddress</strong></mark> from the <mark style="color:red;"><strong>fromAddress</strong></mark> to the contract, approving the router to spend the amount, and then calling the swap function. If the swap is unsuccessful, it reverts with the returned data. Finally, the function emits a <mark style="color:red;"><strong>SwapIn</strong></mark> event with details of the swap operation, including the <mark style="color:red;"><strong>fromAddress</strong></mark>, <mark style="color:red;"><strong>toAddress</strong></mark>, asset addresses, total amount, output amount, and the encoded deposit data.</td></tr><tr><td><mark style="color:red;"><strong>swapOut</strong></mark> </td><td>The <mark style="color:red;"><strong>swapOut</strong></mark> function executes an outbound swap operation using the provided swap and deposit data. It takes several parameters: <mark style="color:red;"><strong>swapData</strong></mark>, which contains the swap details; <mark style="color:red;"><strong>depositAmount</strong></mark>, which is the bridged amount to be swapped; <mark style="color:red;"><strong>depositDataHash</strong></mark>, a hash of the deposit data; <mark style="color:red;"><strong>routerAddress</strong></mark>, the address of the router contract for the swap; and <mark style="color:red;"><strong>weth</strong></mark>, the address of the Wrapped Ether contract. The function returns the amount received as output from the swap operation. The function first checks if the <mark style="color:red;"><strong>depositAmount</strong></mark> matches the sum of <mark style="color:red;"><strong>amountIn</strong></mark> and <mark style="color:red;"><strong>gasFee</strong></mark> from <mark style="color:red;"><strong>swapData</strong></mark>, reverting with an <mark style="color:red;"><strong>InvalidDepositAmount</strong></mark> error if it does not. If there is a gas fee, it transfers this fee to the sender. For the main swap operation, the function handles different scenarios based on the asset addresses involved. If the <mark style="color:red;"><strong>fromAssetAddress</strong></mark> is <mark style="color:red;"><strong>weth</strong></mark> and the <mark style="color:red;"><strong>toAssetAddress</strong></mark> is native, it unwraps the <mark style="color:red;"><strong>weth</strong></mark> and transfers the native amount to the <mark style="color:red;"><strong>toAddress</strong></mark>. If the <mark style="color:red;"><strong>fromAssetAddress</strong></mark> is native and the <mark style="color:red;"><strong>toAssetAddress</strong></mark> is <mark style="color:red;"><strong>weth</strong></mark>, it wraps the native amount into <mark style="color:red;"><strong>weth</strong></mark> and transfers it to the toAddress. If both asset addresses are the same, it simply transfers the amount to the <mark style="color:red;"><strong>toAddress</strong></mark>. For other cases, it prepares for the swap by approving the router to spend the <mark style="color:red;"><strong>fromAssetAddress</strong></mark> amount and then calls the swap function. If the <mark style="color:red;"><strong>swap</strong></mark> is unsuccessful, it reverts to transferring the <mark style="color:red;"><strong>fromAssetAddress</strong></mark> amount to the <mark style="color:red;"><strong>toAddress</strong></mark> and sets the <mark style="color:red;"><strong>toAssetAddress</strong></mark> to <mark style="color:red;"><strong>fromAssetAddress</strong></mark>. Finally, the function emits a <mark style="color:red;"><strong>SwapOut</strong></mark> event with details of the swap operation, including the sender, <mark style="color:red;"><strong>toAddress</strong></mark>, asset addresses, total amount, output amount, and the deposit data hash.</td></tr></tbody></table>


# LibRouter

The LibRouter smart contract facilitates efficient and secure swap operations by preparing and managing swap data, transferring necessary fees, and verifying permissions and signatures. The getData function extracts and organizes swap parameters from calldata, ensuring transactions are valid and not expired. The transferFees function handles the transfer of gas and affiliate fees, accommodating both native and non-native assets. The permit function grants the contract permission to use the user’s assets for the swap, covering all associated fees. The recoverSigner function ensures the integrity of signatures by recovering the signer’s address and validating it. Additionally, the getDomainSeparator function generates a domain separator for EIP-712 typed data hashing, crucial for preventing replay attacks. The verifySignature function verifies the signature for a swap operation by constructing a message hash and recovering the signer’s address, ensuring the authenticity of the transaction. Overall, the contract ensures secure and efficient swap operations through meticulous data handling and verification processes.

<table data-full-width="false"><thead><tr><th width="222">Function Name</th><th>Description (Business Logic)</th></tr></thead><tbody><tr><td><mark style="color:red;"><strong>getData</strong></mark> </td><td>The <mark style="color:red;"><strong>getData</strong></mark> function in the <mark style="color:red;"><strong>LibRouter</strong></mark> library is designed to prepare and return a <mark style="color:red;"><strong>SwapData</strong></mark> struct from the calldata. It begins by calculating the <mark style="color:red;"><strong>deadline</strong></mark> from the calldata and checks if the transaction has expired by comparing it with the current timestamp. If the transaction is expired, it reverts with an <mark style="color:red;"><strong>ExpiredTransaction</strong></mark> error. The function then proceeds to populate the <mark style="color:red;"><strong>SwapData</strong></mark> struct with various parameters extracted from the calldata, including <mark style="color:red;"><strong>toAddress</strong></mark>, <mark style="color:red;"><strong>fromAssetAddress</strong></mark>, <mark style="color:red;"><strong>toAssetAddress</strong></mark>, <mark style="color:red;"><strong>deadline</strong></mark>, <mark style="color:red;"><strong>amountOutMin</strong></mark>, <mark style="color:red;"><strong>gasFee</strong></mark>, and <mark style="color:red;"><strong>amountIn</strong></mark>. It also determines if the transaction includes a permit by checking the <mark style="color:red;"><strong>v</strong></mark> value from the calldata and sets the <mark style="color:red;"><strong>hasPermit</strong></mark> flag accordingly. Depending on whether the permit is present, it further checks for the presence of an affiliate and populates the <mark style="color:red;"><strong>affiliateAddress</strong></mark> and <mark style="color:red;"><strong>affiliateFee</strong></mark> fields if applicable. The function uses inline assembly for efficient data manipulation and storage within the <mark style="color:red;"><strong>SwapData</strong></mark> struct.</td></tr><tr><td><mark style="color:red;"><strong>transferFees</strong></mark> </td><td>The <mark style="color:red;"><strong>transferFees</strong></mark> function is responsible for transferring the necessary fees for a swap operation from the user’s account. It first checks if the <mark style="color:red;"><strong>fromAssetAddress</strong></mark> is a native asset, in which case it sets the <mark style="color:red;"><strong>gasFee</strong></mark> to zero. If there is a <mark style="color:red;"><strong>gasFee</strong></mark> greater than zero, it transfers this fee from the user’s address to the contract’s address. Additionally, if there is an <mark style="color:red;"><strong>affiliateFee</strong></mark>, the function checks if the asset is native. If it is, the fee is transferred directly to the affiliate’s address. Otherwise, the fee is transferred from the user’s address to the affiliate’s address using the <mark style="color:red;"><strong>transferFrom</strong></mark> method.</td></tr><tr><td><mark style="color:red;"><strong>permit</strong></mark> </td><td>The <mark style="color:red;"><strong>permit</strong></mark> function grants permission for the user’s asset to be used in a swap operation. It extracts the <mark style="color:red;"><strong>v</strong></mark>, <mark style="color:red;"><strong>r</strong></mark>, and <mark style="color:red;"><strong>s</strong></mark> values, as well as the <mark style="color:red;"><strong>deadline</strong></mark> from the calldata using inline assembly. These values are then used to call the permit method on the <mark style="color:red;"><strong>fromAssetAddress</strong></mark>, allowing the contract to spend the specified amount of the user’s asset. The amount includes the <mark style="color:red;"><strong>amountIn</strong></mark>, <mark style="color:red;"><strong>gasFee</strong></mark>, and <mark style="color:red;"><strong>affiliateFee</strong></mark>, ensuring that all necessary fees are covered by the permission granted.</td></tr><tr><td><mark style="color:red;"><strong>recoverSigner</strong></mark> </td><td>The <mark style="color:red;"><strong>recoverSigner</strong></mark> function is a private, pure function that recovers the signer’s address from a hashed message and its signature components (<mark style="color:red;"><strong>r</strong></mark>, <mark style="color:red;"><strong>s</strong></mark>, and <mark style="color:red;"><strong>v</strong></mark>). This function ensures the uniqueness of the signature by addressing potential malleability issues as outlined in the Ethereum Yellow Paper. It first checks if the <mark style="color:red;"><strong>s</strong></mark> value is within the valid range, reverting with an <mark style="color:red;"><strong>InvalidSignature</strong></mark> error if it is not. It also verifies that the v value is either 27 or 28, reverting with an <mark style="color:red;"><strong>InvalidSignature</strong></mark> error if it is not. The function then uses the <mark style="color:red;"><strong>ecrecover</strong></mark> function to obtain the signer’s address from the hash and the signature components. If the recovered address is the zero address, it reverts with an <mark style="color:red;"><strong>InvalidSignature</strong></mark> error, ensuring that only valid signatures are accepted.</td></tr><tr><td><mark style="color:red;"><strong>getDomainSeparator</strong></mark></td><td>The <mark style="color:red;"><strong>getDomainSeparator</strong></mark> function is a private view function that generates a domain separator for EIP-712 typed data hashing. It first retrieves the current chain ID using inline assembly. The function then returns the keccak256 hash of an encoded EIP-712 domain, which includes the name, version, chain ID, and the contract’s address. The domain separator is crucial for ensuring the integrity and uniqueness of the signed data, preventing replay attacks across different domains.</td></tr><tr><td><mark style="color:red;"><strong>verifySignature</strong></mark> </td><td>The <mark style="color:red;"><strong>verifySignature</strong></mark> function verifies the signature for a swap operation. It takes several parameters, including the <mark style="color:red;"><strong>SwapData</strong></mark> struct, a pointer to the message data in memory, the length of the message data, a flag indicating whether to use the caller’s address for verification, and a slot in the internal callers storage for verification. The function first generates a domain separator using the <mark style="color:red;"><strong>getDomainSeparator</strong></mark> function. It then constructs the message hash by storing various fields from the <mark style="color:red;"><strong>SwapData</strong></mark> struct in memory and computing the keccak256 hash of the message data. The domain separator and message hash are combined to create the final digest. Using inline assembly, the function extracts the r, s, and v components of the signature from the <mark style="color:red;"><strong>calldata</strong></mark>. If the <mark style="color:red;"><strong>useCaller</strong></mark> flag is set, it recovers the signer’s address from the digest and verifies it against the internal callers storage. If the verification fails, it reverts with an <mark style="color:red;"><strong>InvalidSignature</strong></mark> error. If the <mark style="color:red;"><strong>useCaller</strong></mark> flag is not set, it simply recovers the signer’s address from the digest and returns it.</td></tr><tr><td><mark style="color:red;"><strong>swapInWithUserSignature</strong></mark></td><td>The <mark style="color:red;">swapInWithUserSignature</mark> function, restricted to internal callers, facilitates swaps using a user signature.</td></tr><tr><td><mark style="color:red;"><strong>swapInWithMagpieSignature</strong></mark> </td><td>The <mark style="color:red;"><strong>swapInWithMagpieSignature</strong></mark> function allows for token swaps using a Magpie signature, and can only be executed when the contract is not paused.</td></tr></tbody></table>


# Smart Contracts Audit

Review the latest smart contract audit by QuillAudit for fly trade, ensuring security and reliability in DeFi operations.

## EVM Contracts

The most recent audit report for our EVM contracts, conducted by QuillAudit in April 2025, is available [here](https://github.com/Quillhash/QuillAudit_smart_contract_audit_Reports/blob/master/Fly%20Trade%20V4%20Smart%20Contract%20Audit%20Report%20-%20QuillAudits.pdf).

## SVM Contracts

The latest audit report is available [here](https://github.com/Quillhash/QuillAudit_Reports/blob/master/fly.trade%20SVM%20Smart%20Contract%20Audit%20report%20-%20QuillAudits.pdf).


# Protocol Fees

To ensure Fly remains a sustainable, scalable, and high-performance liquidity solution, we’ve introduced a transaction fee model that supports ongoing development, infrastructure growth, and long-term

On most major chains, Fly does not charge any swap fees—users only pay the network gas fee. For long-tail assets and specific asset pairs, we apply a minimal swap fee ranging from **0.01% to 0.03%**, dynamically adjusted based on trading volume, liquidity depth, and other network-specific metrics. This structure allows us to maintain accessibility while reinforcing the protocol’s long-term viability.


# Deployments

Access information on fly trade’s contract deployments across supported networks, ensuring transparency and ease of integration.

## DexAggregator

<table><thead><tr><th width="250">Network</th><th>Explorer</th></tr></thead><tbody><tr><td>Ethereum</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Polygon</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>BSC</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Avalanche</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Arbitrum</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Optimism</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Base</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Polygon zkEVM</td><td>0xf5f3b8faf45023fd92c0c88fedf73fb0529fc1cd</td></tr><tr><td>Blast</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>zkSync</td><td>0xc5b20203b6807e742853c96ce7dcfb1e7b201c0a</td></tr><tr><td>Manta</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Scroll</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Metis</td><td>0xf702814d2e1290f3d5f3202565df46272e1b1b92</td></tr><tr><td>Fantom</td><td>0xf702814d2e1290f3d5f3202565df46272e1b1b92</td></tr><tr><td>Taiko</td><td>0xf5f3b8faf45023fd92c0c88fedf73fb0529fc1cd</td></tr><tr><td>Sonic</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Ink</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Linea</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Berachain</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Unichain</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Abstract</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Plasma</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>HyperEVM</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Monad</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Stable</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>MegaETH</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Morph</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>0g</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Telos</td><td>0xf5f3b8faf45023fd92c0c88fedf73fb0529fc1cd</td></tr><tr><td>Katana</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Tempo</td><td>0x20f6ee51340adeed01a59b0e65cb3703f3dc860c</td></tr><tr><td>Pharos</td><td>0xf702814d2e1290f3d5f3202565df46272e1b1b92</td></tr></tbody></table>

## MagpieRouter on SVM

<table><thead><tr><th width="232">Network</th><th>Address</th></tr></thead><tbody><tr><td>Solana</td><td>2DAtv2URAcb9ZHVMHEB8E3TFBTk9PoNSYknjq8DVr69c</td></tr></tbody></table>

## MagpieRouterV3\_1

<table><thead><tr><th width="250">Network</th><th>Explorer</th></tr></thead><tbody><tr><td>Ethereum</td><td>0xa6e941eab67569ca4522f70d343714ff51d571c4</td></tr><tr><td>Polygon</td><td>0xa6e941eab67569ca4522f70d343714ff51d571c4</td></tr><tr><td>BSC</td><td>0x29ed0a2f22a92ff84a7f196785ca6b0d21aeec62</td></tr><tr><td>Avalanche</td><td>0x3611b82c7b13e72b26eb0e9be0613bee7a45ac7c</td></tr><tr><td>Arbitrum</td><td>0xfb1b08ba6ba284934d817ea3c9d18f592cc59a50</td></tr><tr><td>Optimism</td><td>0xa6e941eab67569ca4522f70d343714ff51d571c4</td></tr><tr><td>Base</td><td>0x5e766616aabfb588e23a8ea854e9dbd1042affd3</td></tr><tr><td>Polygon zkEVM</td><td>0x3950bf2fff93e5d502430f17924aef4c621ea772</td></tr><tr><td>Blast</td><td>0xc9f1a0ba8071685e3529982b59c8645b27734bd0</td></tr><tr><td>zkSync</td><td>0xb44958ff91b4b67d8d4db010e38ccffe52551ecb</td></tr><tr><td>Manta</td><td>0x6d3c9920c7a2617ea98c9afcf7219d0f166ab758</td></tr><tr><td>Scroll</td><td>0x9ee06954418687c6fb3a9966f7c46e0a245f0183</td></tr><tr><td>Metis</td><td>0xda52965937213f51bfe716f338714afa80ff17bf</td></tr><tr><td>Fantom</td><td>0x5affa5312ade198d9527acf058fee1c8ed8fe9f3</td></tr><tr><td>Taiko</td><td>0x5affa5312ade198d9527acf058fee1c8ed8fe9f3</td></tr><tr><td>Sonic</td><td>0xc325856e5585823aac0d1fd46c35c608d95e65a9</td></tr><tr><td>Ink</td><td>0x52bebb970697476313ae2b3383f40d4afd4ad9d3</td></tr><tr><td>Linea</td><td>0x52bebb970697476313ae2b3383f40d4afd4ad9d3</td></tr><tr><td>Berachain</td><td>0x52bebb970697476313ae2b3383f40d4afd4ad9d3</td></tr><tr><td>Unichain</td><td>0x956df8424b556f0076e8abf5481605f5a791cc7f</td></tr><tr><td>Abstract</td><td>0x956df8424b556f0076e8abf5481605f5a791cc7f</td></tr><tr><td>Plasma</td><td>0x956df8424b556f0076e8abf5481605f5a791cc7f</td></tr><tr><td>HyperEVM</td><td>0x956df8424b556f0076e8abf5481605f5a791cc7f</td></tr><tr><td>Monad</td><td>0x956df8424b556f0076e8abf5481605f5a791cc7f</td></tr><tr><td>Stable</td><td>0x956Df8424B556F0076E8abf5481605f5A791cc7f</td></tr><tr><td>MegaETH</td><td>0x956df8424b556f0076e8abf5481605f5a791cc7f</td></tr><tr><td>Morph</td><td>0x956df8424b556f0076e8abf5481605f5a791cc7f</td></tr><tr><td>0g</td><td>0x956df8424b556f0076e8abf5481605f5a791cc7f</td></tr><tr><td>Telos</td><td>0x956df8424b556f0076e8abf5481605f5a791cc7f</td></tr><tr><td>Katana</td><td>0x956df8424b556f0076e8abf5481605f5a791cc7f</td></tr><tr><td>Tempo</td><td>0x956df8424b556f0076e8abf5481605f5a791cc7f</td></tr><tr><td>Pharos</td><td>0x956df8424b556f0076e8abf5481605f5a791cc7f</td></tr></tbody></table>

## MagpieStargateBridgeV3

<table><thead><tr><th width="250">Network</th><th>Explorer</th></tr></thead><tbody><tr><td>Ethereum</td><td>0x73731dacb1ee5906aa515512fcda2074d690487a</td></tr><tr><td>Polygon</td><td>0x73731dacb1ee5906aa515512fcda2074d690487a</td></tr><tr><td>BSC</td><td>0x73731dacb1ee5906aa515512fcda2074d690487a</td></tr><tr><td>Avalanche</td><td>0x15392211222b46a0ea85a9a800830486d144848d</td></tr><tr><td>Arbitrum</td><td>0xeb57de1f78304cf925405efc1089793aabddb0d5</td></tr><tr><td>Optimism</td><td>0x73731dacb1ee5906aa515512fcda2074d690487a</td></tr><tr><td>Base</td><td>0x1b3bbce7241b357d8a8e3523f6d91ee50f37333a</td></tr><tr><td>Polygon zkEVM</td><td>-</td></tr><tr><td>Blast</td><td>-</td></tr><tr><td>zkSync</td><td>-</td></tr><tr><td>Manta</td><td>-</td></tr><tr><td>Scroll</td><td>0x3ca605083506096fba34461b471db7ed03290b2d</td></tr><tr><td>Metis</td><td>0x596384bdffc9f563b53791aeec50a42ff51c3e42</td></tr><tr><td>Fantom</td><td>-</td></tr><tr><td>Taiko</td><td>-</td></tr><tr><td>Sonic</td><td>-</td></tr><tr><td>Ink</td><td>-</td></tr><tr><td>Linea</td><td>-</td></tr><tr><td>Berachain</td><td>-</td></tr></tbody></table>

## MagpieCelerBridgeV2

<table><thead><tr><th width="250">Network</th><th>Explorer</th></tr></thead><tbody><tr><td>Ethereum</td><td>0x34cdce58cbdc6c54f2ac808a24561d0ab18ca8be</td></tr><tr><td>Polygon</td><td>0x34cdce58cbdc6c54f2ac808a24561d0ab18ca8be</td></tr><tr><td>BSC</td><td>0x34cdce58cbdc6c54f2ac808a24561d0ab18ca8be</td></tr><tr><td>Avalanche</td><td>0x73731dacb1ee5906aa515512fcda2074d690487a</td></tr><tr><td>Arbitrum</td><td>0x44f6c16720e9b3d7b6b188d65b6808e1e54057b9</td></tr><tr><td>Optimism</td><td>0x34cdce58cbdc6c54f2ac808a24561d0ab18ca8be</td></tr><tr><td>Base</td><td>0x2b14763c27b9661182c2503f6c9c4d47ba747dd2</td></tr><tr><td>Polygon zkEVM</td><td>0x2bcff213edff099019172eb95c025cc385849cb0</td></tr><tr><td>Blast</td><td>-</td></tr><tr><td>zkSync</td><td>0x9a82d959bfbcb1677585f111eca12a53c369c1b3</td></tr><tr><td>Manta</td><td>0x6a1431bb23e08e3209dae3130b441863855fc14b</td></tr><tr><td>Scroll</td><td>0x5affa5312ade198d9527acf058fee1c8ed8fe9f3</td></tr><tr><td>Metis</td><td>-</td></tr><tr><td>Fantom</td><td>-</td></tr><tr><td>Taiko</td><td>-</td></tr><tr><td>Sonic</td><td>-</td></tr><tr><td>Ink</td><td>-</td></tr><tr><td>Linea</td><td>-</td></tr><tr><td>Berachain</td><td>-</td></tr></tbody></table>

## MagpieCCTPBridge

<table><thead><tr><th width="250">Network</th><th>Explorer</th></tr></thead><tbody><tr><td>Ethereum</td><td>0xeb57de1f78304cf925405efc1089793aabddb0d5</td></tr><tr><td>Polygon</td><td>0xeb57de1f78304cf925405efc1089793aabddb0d5</td></tr><tr><td>BSC</td><td>-</td></tr><tr><td>Avalanche</td><td>0x34cdce58cbdc6c54f2ac808a24561d0ab18ca8be</td></tr><tr><td>Arbitrum</td><td>0xd0daa14d983a40b4c91f7b6875faa8d27f024e73</td></tr><tr><td>Optimism</td><td>0xeb57de1f78304cf925405efc1089793aabddb0d5</td></tr><tr><td>Base</td><td>0x6c9b3a74ae4779da5ca999371ee8950e8db3407f</td></tr><tr><td>Polygon zkEVM</td><td>-</td></tr><tr><td>Blast</td><td>-</td></tr><tr><td>zkSync</td><td>-</td></tr><tr><td>Manta</td><td>-</td></tr><tr><td>Scroll</td><td>-</td></tr><tr><td>Metis</td><td>-</td></tr><tr><td>Fantom</td><td>-</td></tr><tr><td>Taiko</td><td>-</td></tr><tr><td>Sonic</td><td>-</td></tr><tr><td>Ink</td><td>-</td></tr><tr><td>Linea</td><td>-</td></tr><tr><td>Berachain</td><td>-</td></tr></tbody></table>


# API Reference

Access detailed API documentation for Fly Trade, including endpoints for on-chain and cross-chain swaps, authentication, and integration guidelines.

This section explains how to use Magpie APIs to execute on-chain or cross-chain swaps.

&#x20;[Swagger Link](https://api.fly.trade/swagger)


# EVM Swap Integration Guide

How to execute same-chain swaps on EVM networks using Fly Trade's APIs

## EVM Swap Integration Guide

This guide shows how to execute a swap on **EVM networks** (Ethereum, Polygon, BSC, Arbitrum, etc.) using Fly Trade's API in 3 steps:

1. **Get a quote** (pricing + route + constraints)
2. **Fetch transaction payload** with the quote ID
3. **Sign and send** the transaction to the network

### Prerequisites

* An EVM RPC connection (Infura, Alchemy, QuickNode, or self-hosted node)
* A wallet that can sign EVM transactions (MetaMask, WalletConnect, ethers.js Signer, or backend private key)
* Sufficient balance of the tokens you want to swap and their token contract addresses

## How the Flow Works

The high-level swap flow is:

* Call `/aggregator/quote` to receive a `quoteId`, estimated output amount, and swap details
* Call `/aggregator/transaction` with the `quoteId` to receive the transaction data (to, data, value, gas parameters)
* Sign the transaction with the user's wallet
* Send the signed transaction to the network
* Wait for confirmation

**Alternative:** Instead of calling quote and transaction separately, you can use the `/aggregator/quote/transaction` endpoint to get both in a single request. Note that this combined endpoint does not provide gas estimation.

### Step 1 — Get a Quote

**Endpoint:**

* Method: `GET`
* Path: `/aggregator/quote`

**Required Parameters:**

| Parameter          | Description                                                                                                                                                                                               |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `network`          | Network name (e.g., `ethereum`, `polygon`, `bsc`, `arbitrum`, `base`). See the [network dropdown on Swagger](https://api.fly.trade/swagger#/Quotes/%2Faggregator%2Fquote) for all supported network names |
| `fromTokenAddress` | Token contract address to swap from. Use `0x0000000000000000000000000000000000000000` for native token (ETH/MATIC/BNB)                                                                                    |
| `toTokenAddress`   | Token contract address to swap to. Use `0x0000000000000000000000000000000000000000` for native token                                                                                                      |
| `sellAmount`       | Amount in smallest unit (wei). For 1 ETH write `1000000000000000000`                                                                                                                                      |
| `slippage`         | Allowed slippage (e.g., `0.005` for 0.5%, `0.01` for 1%)                                                                                                                                                  |
| `fromAddress`      | Wallet address initiating the swap                                                                                                                                                                        |
| `toAddress`        | Wallet address receiving the swapped tokens                                                                                                                                                               |
| `gasless`          | Must always be set to `false`. Gasless transactions are not supported — setting this to `true` will cause the quote to fail                                                                               |

**Optional Parameters**

**Affiliate Fee:**

* `affiliateAddress`: Address to receive affiliate fees
* `affiliateFee`: The fee percentage. For example: 1% = 0.01

Affiliate fees are deducted from the `fromTokenAddress` amount and sent to the specified address.

**Example Request:**

```
GET /aggregator/quote?network=ethereum&fromTokenAddress=0x....&toTokenAddress=0x....&fromAddress=0x....&toAddress=0x....&sellAmount=1000000000000000&slippage=0.005&gasless=false
```

**Example Response:**

{% code expandable="true" %}

```json
{
    "id": "0d180427-53d7-479b-a91d-c4ec88de1522",
    "amountOut": "2334548",
    "targetAddress": "0x....",
    "fees": [
        {
            "type": "gas",
            "value": "1.3746"
        }
    ],
    "resourceEstimate": {
        "gasLimit": "209993"
    },
    "typedData": {
        "types": {
            "Swap": [
                { "name": "router", "type": "address" },
                { "name": "sender", "type": "address" },
                { "name": "recipient", "type": "address" },
                { "name": "fromAsset", "type": "address" },
                { "name": "toAsset", "type": "address" },
                { "name": "deadline", "type": "uint256" },
                { "name": "amountOutMin", "type": "uint256" },
                { "name": "expectedAmountOut", "type": "uint256" },
                { "name": "consumerId", "type": "bytes32" },
                { "name": "maxRetentionBps", "type": "uint256" },
                { "name": "transferFromRouter", "type": "bool" }
            ]
        },
        "domain": {
            "name": "Dex Aggregator",
            "version": "1",
            "chainId": "1",
            "verifyingContract": "0x...."
        },
        "message": {
            "router": "0x....",
            "sender": "0x....",
            "recipient": "0x....",
            "fromAsset": "0x....",
            "toAsset": "0x....",
            "deadline": "1778165284",
            "amountOutMin": "2322875",
            "expectedAmountOut": "2334548",
            "consumerId": "0x....",
            "maxRetentionBps": "500",
            "transferFromRouter": false
        }
    }
}
```

{% endcode %}

Save the `id` as `quoteId` for Step 2.

**Important Quote Constraints:**

**Quote Expiry:** Each quote has a **5-minute expiration window**. After 5 minutes, the `quoteId` becomes invalid and you will not be able to fetch the transaction payload. If your quote has expired, you must request a fresh quote before proceeding.

**Single-Use Quotes:** Each quote can only be used to fetch the transaction payload **once**. After successfully calling `/aggregator/transaction` with a `quoteId`, that quote is consumed and cannot be reused. If you need to execute another swap or retry, you must fetch a new quote.

### Step 2 — Get Transaction Payload

**Endpoint:**

* Method: `GET`
* Path: `/aggregator/transaction`

**Required Parameters:**

| Parameter | Description                         |
| --------- | ----------------------------------- |
| `quoteId` | The quote `id` returned from Step 1 |

**Optional Parameters:**

| Parameter     | Description                                                                                                                                                                                 | Default |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `estimateGas` | Whether to estimate gas when building the transaction. If `true`, ensures token approval and balance checks are performed. If gas estimation fails, returns error `"Couldn't estimate gas"` | `true`  |

**Important:** When `estimateGas=true`, you must have:

* Sufficient token approval for the router contract (for ERC-20 swaps)
* Enough token balance for the swap
* Otherwise, the endpoint will return an error and fail to generate the transaction

**Example Request:**

```
GET /aggregator/transaction?quoteId=8de05661-09d6-4b82-ab63-1e32ee1fa297
```

**Example Response:**

```json
{
    "from": "0x....",
    "to": "0x....",
    "data": "0x....",
    "chainId": 1,
    "type": 2,
    "gasLimit": "314086",
    "maxFeePerGas": "228922087",
    "maxPriorityFeePerGas": "190605439",
    "value": "10000000000000000"
}
```

### Alternative: Combined Quote + Transaction Endpoint

For faster integration, you can fetch both quote and transaction data in a single request.

**Endpoint:**

* Method: `GET`
* Path: `/aggregator/quote/transaction`

**Parameters:**

Accepts all parameters from the `/aggregator/quote` endpoint (network, fromTokenAddress, toTokenAddress, sellAmount, slippage, fromAddress, toAddress). Always set `gasless=false`.

**Note:** `fromAddress` and `toAddress` are **required** for this endpoint and it doesn't estimate gas.

**Example Request:**

```
GET /aggregator/quote/transaction?network=ethereum&fromTokenAddress=0x0000000000000000000000000000000000000000&toTokenAddress=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48&sellAmount=1000000000000000&slippage=0.005&gasless=false&toAddress=0x6820587e343da884230b6611d1802b92359e5a72&fromAddress=0x6820587e343da884230b6611d1802b92359e5a72
```

**Example Response:**

Returns both quote data and transaction payload in one response:

{% code expandable="true" %}

```json
{
  "quote": {
    "id": "4181b2b4-4b36-4641-9136-f6ce0dce4345",
    "amountOut": "2334548",
    "targetAddress": "0x....",
    "fees": [
      {
        "type": "gas",
        "value": "0.8261"
      }
    ],
    "resourceEstimate": {
      "gasLimit": "209993"
    },
    "typedData": {
      "types": {
        "Swap": [
          { "name": "router", "type": "address" },
          { "name": "sender", "type": "address" },
          { "name": "recipient", "type": "address" },
          { "name": "fromAsset", "type": "address" },
          { "name": "toAsset", "type": "address" },
          { "name": "deadline", "type": "uint256" },
          { "name": "amountOutMin", "type": "uint256" },
          { "name": "expectedAmountOut", "type": "uint256" },
          { "name": "consumerId", "type": "bytes32" },
          { "name": "maxRetentionBps", "type": "uint256" },
          { "name": "transferFromRouter", "type": "bool" }
        ]
      },
      "domain": {
        "name": "Dex Aggregator",
        "version": "1",
        "chainId": "1",
        "verifyingContract": "0x...."
      },
      "message": {
        "router": "0x....",
        "sender": "0x....",
        "recipient": "0x....",
        "fromAsset": "0x....",
        "toAsset": "0x....",
        "deadline": "1778166079",
        "amountOutMin": "2322875",
        "expectedAmountOut": "2334548",
        "consumerId": "0x....",
        "maxRetentionBps": "500",
        "transferFromRouter": false
      }
    }
  },
  "transaction": {
    "from": "0x....",
    "to": "0x....",
    "data": "0x....",
    "chainId": 1,
    "type": 2,
    "gasLimit": "0",
    "maxFeePerGas": "2542178902",
    "maxPriorityFeePerGas": "845661810",
    "value": "1000000000000000"
  }
}
```

{% endcode %}

### Updating Amount In (Optional)

After fetching transaction data from `/aggregator/transaction` or `/aggregator/quote/transaction`, you can dynamically override the `amountIn` before executing the transaction. This is useful when your integration manages token balances or allowances at execution time rather than at quote time.

**Two Modes:**

* **Specify an exact amount** — Pass any non-zero `uint256` value to set a precise `amountIn`.
* **Use balance or allowance (whichever is lower)** — Pass `0` as the `amountIn`. The contract will automatically use `min(balance, allowance)` at execution time.

**How It Works:**

The `DexAggregator` contract exposes a pure helper function `updateAmountIn`. You pass it the raw transaction `data` bytes returned by the API along with your desired `amountIn`, and it returns adjusted calldata ready to execute.

```solidity
function updateAmountIn(bytes memory data, uint256 amountIn) external pure returns (bytes memory) {
    assembly {
        mstore(add(data, 164), amountIn) // 32 + 132
    }
    return data;
}
```

**TypeScript Example:**

{% code expandable="true" %}

```typescript
import { ethers } from 'ethers';

async function executeSwapWithCustomAmount() {
  const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
  const wallet = new ethers.Wallet(PRIVATE_KEY, provider);

  // Step 1: Fetch transaction data from the API
  const quoteUrl = new URL('https://api.fly.trade/aggregator/quote/transaction');
  quoteUrl.searchParams.set('network', 'ethereum');
  quoteUrl.searchParams.set('fromTokenAddress', '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'); // USDC
  quoteUrl.searchParams.set('toTokenAddress', '0x0000000000000000000000000000000000000000'); // ETH
  quoteUrl.searchParams.set('sellAmount', '1000000'); // 1 USDC
  quoteUrl.searchParams.set('slippage', '0.005');
  quoteUrl.searchParams.set('fromAddress', wallet.address);
  quoteUrl.searchParams.set('toAddress', wallet.address);
  quoteUrl.searchParams.set('gasless', 'false');

  const response = await fetch(quoteUrl.toString());
  const { transaction } = await response.json();

  // Step 2: Use updateAmountIn to override the amountIn
  const dexAggregator = new ethers.Contract(
    DEX_AGGREGATOR_ADDRESS,
    ['function updateAmountIn(bytes memory data, uint256 amountIn) external pure returns (bytes memory)'],
    wallet
  );

  // Option A: Set a specific amountIn (e.g. 500000 = 0.5 USDC)
  const adjustedData = await dexAggregator.updateAmountIn(transaction.data, '500000');

  // Option B: Use min(balance, allowance) automatically
  // const adjustedData = await dexAggregator.updateAmountIn(transaction.data, 0);

  // Step 3: Execute the swap with the adjusted calldata
  const tx = await wallet.sendTransaction({
    to: transaction.to,
    data: adjustedData,
    value: transaction.value,
    gasLimit: transaction.gasLimit,
  });

  const receipt = await tx.wait();
  console.log('Swap executed with custom amountIn:', receipt.transactionHash);
}
```

{% endcode %}

### Step 3 — Execute the Swap Transaction

Once you have the transaction payload (from Step 2 or the combined endpoint), you can execute it using your preferred web3 library.

**Important:** Depending on the blockchain, the transaction response may use EIP-1559 format with `maxFeePerGas` and `maxPriorityFeePerGas` (if the chain supports EIP-1559) or legacy format with `gasPrice`. Make sure your wallet/library supports both transaction types.

#### Integration Examples

**Example 1: Frontend Integration (React + Ethers.js)**

Example for integrating swaps in a React frontend application:

{% code expandable="true" %}

```typescript
import { useState } from 'react';
import { ethers } from 'ethers';

function SwapComponent() {
  const [loading, setLoading] = useState(false);
  const [status, setStatus] = useState('');

  async function handleSwap() {
    if (!window.ethereum) {
      alert('Please install MetaMask');
      return;
    }

    setLoading(true);
    setStatus('Connecting wallet...');

    try {
      // Connect wallet
      const provider = new ethers.providers.Web3Provider(window.ethereum);
      await provider.send('eth_requestAccounts', []);
      const signer = provider.getSigner();
      const userAddress = await signer.getAddress();

      // Swap parameters
      const fromToken = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; // USDC
      const toToken = '0x0000000000000000000000000000000000000000'; // ETH
      const amount = '1000000'; // 1 USDC (6 decimals)

      // Check and approve if needed (ERC-20 only)
      if (fromToken !== '0x0000000000000000000000000000000000000000') {
        setStatus('Checking token approval...');
        
        // Get router address from a sample quote
        const sampleQuoteUrl = `https://api.fly.trade/aggregator/quote?network=ethereum&fromTokenAddress=${fromToken}&toTokenAddress=${toToken}&sellAmount=${amount}&slippage=0.005&fromAddress=${userAddress}&toAddress=${userAddress}&gasless=false`;
        const sampleQuoteRes = await fetch(sampleQuoteUrl);
        const sampleQuote = await sampleQuoteRes.json();
        const routerAddress = sampleQuote.targetAddress;

        // Check allowance
        const tokenContract = new ethers.Contract(
          fromToken,
          ['function allowance(address,address) view returns (uint256)', 'function approve(address,uint256) returns (bool)'],
          signer
        );
        const allowance = await tokenContract.allowance(userAddress, routerAddress);

        if (allowance.lt(amount)) {
          setStatus('Approving tokens...');
          const approveTx = await tokenContract.approve(routerAddress, ethers.constants.MaxUint256);
          await approveTx.wait();
          setStatus('Approval confirmed');
        }
      }

      // Get quote and transaction in one call
      setStatus('Fetching quote...');
      const quoteUrl = new URL('https://api.fly.trade/aggregator/quote/transaction');
      quoteUrl.searchParams.set('network', 'ethereum');
      quoteUrl.searchParams.set('fromTokenAddress', fromToken);
      quoteUrl.searchParams.set('toTokenAddress', toToken);
      quoteUrl.searchParams.set('sellAmount', amount);
      quoteUrl.searchParams.set('slippage', '0.005');
      quoteUrl.searchParams.set('fromAddress', userAddress);
      quoteUrl.searchParams.set('toAddress', userAddress);
      quoteUrl.searchParams.set('gasless', 'false');

      const response = await fetch(quoteUrl.toString());
      if (!response.ok) {
        const error = await response.text();
        throw new Error(error);
      }

      const { quote, transaction } = await response.json();
      
      setStatus(`Swapping for ${ethers.utils.formatUnits(quote.amountOut, 18)} ETH...`);

      // Execute swap
      const tx = await signer.sendTransaction({
        to: transaction.to,
        data: transaction.data,
        value: transaction.value,
        gasLimit: transaction.gasLimit,
      });

      setStatus('Transaction sent. Waiting for confirmation...');
      const receipt = await tx.wait();

      setStatus(`✅ Swap completed! Tx: ${receipt.transactionHash}`);
      
    } catch (error) {
      console.error('Swap failed:', error);
      setStatus(`❌ Error: ${error.message}`);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div>
      <button onClick={handleSwap} disabled={loading}>
        {loading ? 'Processing...' : 'Swap 1 USDC → ETH'}
      </button>
      {status && <p>{status}</p>}
    </div>
  );
}

export default SwapComponent;
```

{% endcode %}

**Example 2: Smart Contract Integration**

If you're building a smart contract that needs to execute swaps, here's how to integrate:

**Solidity Contract Example:**

{% code expandable="true" %}

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IERC20 {
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
}

contract MySwapContract {
    address public flyRouter = 0xa6e941eab67569ca4522f70d343714ff51d571c4;
    
    // Execute swap by calling Fly Trade router with transaction data
    function executeSwap(
        address fromToken,
        uint256 amountIn,
        bytes calldata swapCallData
    ) external payable returns (bool) {
        // If swapping ERC-20 token, transfer it from user and approve router
        if (fromToken != address(0)) {
            require(
                IERC20(fromToken).transferFrom(msg.sender, address(this), amountIn),
                "Transfer failed"
            );
            require(
                IERC20(fromToken).approve(flyRouter, amountIn),
                "Approval failed"
            );
        }
        
        // Execute swap by calling the router with the provided calldata
        (bool success, ) = flyRouter.call{value: msg.value}(swapCallData);
        require(success, "Swap failed");
        
        return true;
    }
    
    // Allow contract to receive ETH
    receive() external payable {}
}
```

{% endcode %}

**Off-chain Script to Call Contract:**

{% code expandable="true" %}

```typescript
import { ethers } from 'ethers';

async function executeContractSwap() {
  const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
  const wallet = new ethers.Wallet(PRIVATE_KEY, provider);
  
  // Your contract instance
  const mySwapContract = new ethers.Contract(
    CONTRACT_ADDRESS,
    ['function executeSwap(address,uint256,bytes) payable returns (bool)'],
    wallet
  );
  
  // Step 1: Get quote and transaction data from Fly Trade API
  const quoteUrl = new URL('https://api.fly.trade/aggregator/quote/transaction');
  quoteUrl.searchParams.set('network', 'ethereum');
  quoteUrl.searchParams.set('fromTokenAddress', '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'); // USDC
  quoteUrl.searchParams.set('toTokenAddress', '0x0000000000000000000000000000000000000000'); // ETH
  quoteUrl.searchParams.set('sellAmount', '1000000'); // 1 USDC
  quoteUrl.searchParams.set('slippage', '0.005');
  quoteUrl.searchParams.set('fromAddress', CONTRACT_ADDRESS); // Your contract address
  quoteUrl.searchParams.set('toAddress', wallet.address); // User receives tokens
  quoteUrl.searchParams.set('gasless', 'false');
  quoteUrl.searchParams.set('estimateGas', 'false'); // Disable gas estimation for contracts
  
  const response = await fetch(quoteUrl.toString());
  const { quote, transaction } = await response.json();
  
  // Step 2: Approve USDC for your contract (if user hasn't already)
  const usdcContract = new ethers.Contract(
    '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
    ['function approve(address,uint256) returns (bool)'],
    wallet
  );
  
  const approveTx = await usdcContract.approve(CONTRACT_ADDRESS, '1000000');
  await approveTx.wait();
  
  // Step 3: Call your contract's executeSwap function with the transaction calldata
  const swapTx = await mySwapContract.executeSwap(
    '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // fromToken (USDC)
    '1000000', // amountIn
    transaction.data, // calldata from Fly Trade
    { value: 0 } // msg.value (0 for ERC-20 → ETH swap)
  );
  
  const receipt = await swapTx.wait();
  console.log('Swap executed:', receipt.transactionHash);
}
```

{% endcode %}

**Important Notes for Contract Integration:**

* Set `estimateGas=false` when getting transaction data for contract calls
* The contract must approve the Fly router before swapping ERC-20 tokens
* Pass the transaction data from Fly Trade API directly to the router as calldata

***

### Network Support

Fly Trade supports swaps on multiple EVM networks. You must use the **network name** (not chain ID) in API requests:

For the complete and up-to-date list of supported network names, refer to the network dropdown in our [Swagger documentation](https://api.fly.trade/swagger#/Quotes/%2Faggregator%2Fquote) for `aggregator/quote` endpoint or get it from `/token-manager/networks` endpoint.

***

## Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fly.trade/developers/api-reference/evm-swap-integration-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language. The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.


# Cross chain swap

How to execute cross chain swap using Magpie APIs

## Architecture diagram

<figure><img src="/files/qE2MHONQJDvRAxHB9n4l" alt="" width="375"><figcaption><p>Architecture diagram - cross chain swap</p></figcaption></figure>

## Overview of Cross-Chain Swap Flow

Magpie provides two execution options for cross-chain swaps:

### **Self-Execution**

Users execute the transaction themselves and cover gas costs.

### **Gasless Transaction**

Magpie executes the transaction on behalf of the user and covers the gas fees, so no gas payment is required in the native currency.

Each cross-chain swap involves two main steps:

1. **Quote-In**: Get an estimated swap amount and route on the source chain.
2. **Transaction Execution**: Complete the swap by either self-execution or letting Magpie handle it.

## Step-by-Step Cross-Chain Swap Process

### Step 1: Get a Quote-In

In this step, you retrieve a quote that provides details for the cross-chain swap on the source chain, including the estimated output amount and swap route.

* **Endpoint**: `/aggregator/quote-in`
* **Method**: `GET`

#### **Required Parameters**

* **fromTokenAddress**: Address of the token on the source chain that you want to swap from.
  * If you want to use a native token, please use this address `0x0000000000000000000000000000000000000000`
* **toTokenAddress**: Address of the token on the destination chain that you want to receive.
  * If you want to use a native token, please use this address `0x0000000000000000000000000000000000000000`
* **amount**: The amount of `fromToken` in the smallest unit (e.g., wei for ETH).
* **slippage**: Allowed slippage percentage (e.g., `0.005` for 0.5%).
* **fromAddress**: Wallet address initiating the swap.
* **toAddress**: Wallet address receiving the swapped tokens on the destination chain.
* **gasless**: Set `true` to let Magpie handle gas costs (gasless mode) or `false` if you will cover the gas cost.
* **enableRFQ**: Optional parameter to enable RFQ protocols. Default is `false`&#x20;

> Affiliate Fee: API consumer can implement their own affiliate fees and define their affiliate address, the fees will be deducted from their user from the from asset (asset sold by their user) and distributed to the affiliate address in the same transaction. They can set an affiliate fee by including **affiliateAddress** and **affiliateFeeInPercentage** in the quote request. **affiliateFeeInPercentage** is the percentage fee, such as 0.01 for 1%.

#### **Example Request**:

```
GET /aggregator/quote-in?fromTokenAddress=0x...&toTokenAddress=0x...&amount=1000000000000000000&slippage=0.005&fromAddress=0x...&toAddress=0x...&gasless=true&affiliateAddress=0xPartnerAddress&affiliateFeeInPercentage=0.01
```

#### **Response**:

This request returns a `quote-id` and details such as `toTokenAmount` (estimated output) and fees.

***

### Step 2: Approve tokens

If you are swapping a token that is not the native token, you must first grant approval for the transaction. This requires calling the `approve` function on the token contract associated with the `fromTokenAddress` that you intend to swap.

When retrieving a quote via the endpoint, the response includes `targetAddress`. This address must be used as the spender when granting approval.

***

### Step 3: Execute the Cross-Chain Transaction

Based on the `gasless` option chosen in Step 1, there are two ways to execute the transaction:

1. **Self-Execution** (`gasless = false`): Users retrieve transaction data and broadcast it themselves.
2. **Gasless Transaction** (`gasless = true`): Magpie executes the transaction on behalf of the user.

***

### Self-Execution Path

If `gasless` is set to `false`, users execute the cross-chain transaction on-chain themselves.

* **Endpoint**: `/aggregator/transaction-in`
* **Method**: `GET`

#### **Parameters**:

* **quoteId**: Use the `quote-id` from Step 1 to retrieve the transaction data.

***

### Gasless Transaction Path

If `gasless` is set to `true`, Magpie will execute the transaction on behalf of the user.

* **Endpoint**: `/user-manager/execute-swap-in`
* **Method**: `POST`&#x20;

#### **Parameters**:

* **networkName:** The target network, where the transaction takes place.
* **quoteId**: The `quote-id` from Step 1 is required to execute the swap.
* **swapSignature**: Signed quote using EIP-712
* **permitSignature**: Signed approval using EIP-2612
* **permitDeadline**: The time at which the signature expires (unix time)

#### Generating swapSignature

To generate a `swapSignature` using Ethers v5, follow these steps:

1. Obtain Parameters: Retrieve the `message` parameter from the response of quote API.
2. Generate the Signature: `const signature = await signer._signTypedData(domain, types, message);`&#x20;

Magpie handles the swap and covers the gas fees. No additional action or gas payment is required from the user.

***

## Checking Swap Status

After initiating a swap, you can monitor the swap status through the following endpoints:

1. **Get Swap Details**
   * **Endpoint**: `/user-manager/swap`
   * **Method**: `GET`
   * Use this endpoint to retrieve details of a completed swap.
2. **Get Swap Status Counts**
   * **Endpoint**: `/user-manager/status-counts`
   * **Method**: `GET`
   * This endpoint provides counts of swaps that are in `pending`, `error`, or other states based on the wallet address.

***

### Additional Endpoints: Get Distribution

To check the route and distribution of the swap on both source and destination chains, use the following endpoints with the `quote-id` from Step 1:

* **Source Chain Distribution**: `/aggregator/distribution-in`
* **Destination Chain Distribution**: `/aggregator/distribution-out`

#### **Example Request for Source Chain Distribution**:

```
GET /aggregator/distribution-in?quote-id=YOUR_QUOTE_ID
```

#### **Example Request for Destination Chain Distribution**:

```
GET /aggregator/distribution-out?quote-id=YOUR_QUOTE_ID
```


# Solana Swap Integration Guide

How to execute same chain swap on Solana chain using Fly Trade's APIs

This guide shows how to execute a swap on **Solana** using the Fly Trade's API in 2 steps:

1. **Get a quote** (pricing + route + constraints)
2. **Fetch transaction payload**, then **build, sign, and send** the Solana transaction

## Prerequisites

* A Solana RPC connection
* A wallet that can sign Solana transactions (Phantom / Backpack / Solflare / or a backend Keypair)
* Token mint addresses for the assets you want to swap

## How the Flow Works

Magpie supports two ways to execute a swap on Solana. Regardless of the method, the high-level flow is:

* Call `/aggregator/quote` to receive a `quoteId` and estimated output.
* Call `/aggregator/transaction` with the `quoteId` to receive the transaction payload.
* Depending on your integration, either:
  * Deserialize the provided serialized transaction (recommended), or
  * Construct the transaction manually from `rawData`, `accounts`, LUTs, and compute budget fields.
* Sign the transaction with the user wallet (or fee payer).
* Send it to the Solana network.

## Step 1 — Get a Quote

### Endpoint

* **Method:** `GET`
* **Path:** `/aggregator/quote`

### Required parameters

| Parameter          | Description                                                                                                                                     |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `network`          | `solana`                                                                                                                                        |
| `fromTokenAddress` | Token mint to swap from. For native SOL use `11111111111111111111111111111111`                                                                  |
| `toTokenAddress`   | Token mint to swap to. For native SOL use `11111111111111111111111111111111`                                                                    |
| `sellAmount`       | Amount in the smallest unit (e.g., lamports for SOL, for 1 SOL write 1000000000)                                                                |
| `slippage`         | Allowed slippage (e.g., `0.005` for 0.5%)                                                                                                       |
| `fromAddress`      | Wallet address initiating the swap                                                                                                              |
| `toAddress`        | Wallet address receiving the swapped tokens                                                                                                     |
| `gasless`          | Please use `false` on Solana. Setting `true` will be overridden to `false`for now, gasless support for Solana will be added in a future release |

### Optional Notes

#### **Affiliate Fee**

Affiliate fees are not supported on Solana. This feature is available only on EVM chains. If you need affiliate fee logic on Solana, you must implement it on your side (e.g., adjusting balances before/after the swap).

#### **feePayer (PDA Flow)**

You can use a PDA (Program Derived Address) as the `fromAddress` as long as a normal wallet address is supplied as the `feePayer`.

* The `feePayer` must be a *real wallet*, not a PDA.
* The `feePayer` must be whitelisted by Fly Trade before use.\
  Contact us with the address to whitelist it.

This allows advanced workflows where a PDA owns the source tokens, but another wallet pays the transaction fees.

#### **Using a Non-ATA Token Account**

If the source token is stored in a **non-ATA (Associated Token Account)**, you must explicitly specify **which token account** should be used for the swap.

To do this, set the `fromAddress` parameter to:

```
<owner_address>-<token_account_address>
```

This tells us which SPL token account to read from.

**Example**

```
fromAddress=7VHUFJHWu2CuExkJcJrzhQPJ2oygupTWkL2A2For4BmE-3emsAVdmGKERbHjmGfQ6oZ1e35dkf5iYcS6U4CPKFVaa
```

Where:

* `7VHUFJHWu2CuExkJcJrzhQPJ2oygupTWkL2A2For4BmE` → the owner wallet
* `3emsAVdmGKERbHjmGfQ6oZ1e35dkf5iYcS6U4CPKFVaa` → the specific SPL token account (non-ATA)

If your user has multiple token accounts for the same mint, this ensures the correct one is used during the swap.

### Example request

```http
GET /aggregator/quote?network=solana&fromTokenAddress=11111111111111111111111111111111&toTokenAddress=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&fromAddress=TCKx8giNDmWRJQ6Q6WZw56NcXFQmaUMnqUfvpphoxN8&toAddress=TCKx8giNDmWRJQ6Q6WZw56NcXFQmaUMnqUfvpphoxN8&sellAmount=1000000000&slippage=0.005&gasless=false
```

### Example response

{% code overflow="wrap" expandable="true" %}

```json
{
    "id": "fce0bda2-4e2a-4d28-ab47-1cc7f2dcce03",
    "amountOut": "7267983",
    "targetAddress": "2DAtv2URAcb9ZHVMHEB8E3TFBTk9PoNSYknjq8DVr69c",
    "fees": [
        {
            "type": "gas",
            "value": "0.0333"
        }
    ],
    "resourceEstimate": {
        "computeUnitLimit": "236700"
    },
    "typedData": {
        "types": {
            "Swap": [
                {
                    "name": "router",
                    "type": "address"
                },
                {
                    "name": "sender",
                    "type": "address"
                },
                {
                    "name": "recipient",
                    "type": "address"
                },
                {
                    "name": "fromAsset",
                    "type": "address"
                },
                {
                    "name": "toAsset",
                    "type": "address"
                },
                {
                    "name": "deadline",
                    "type": "uint256"
                },
                {
                    "name": "amountOutMin",
                    "type": "uint256"
                },
                {
                    "name": "swapFee",
                    "type": "uint256"
                },
                {
                    "name": "amountIn",
                    "type": "uint256"
                }
            ]
        },
        "domain": {
            "name": "Magpie Router",
            "version": "3",
            "chainId": "900",
            "verifyingContract": "2DAtv2URAcb9ZHVMHEB8E3TFBTk9PoNSYknjq8DVr69c"
        },
        "message": {
            "router": "2DAtv2URAcb9ZHVMHEB8E3TFBTk9PoNSYknjq8DVr69c",
            "sender": "TCKx8giNDmWRJQ6Q6WZw56NcXFQmaUMnqUfvpphoxN8",
            "recipient": "TCKx8giNDmWRJQ6Q6WZw56NcXFQmaUMnqUfvpphoxN8",
            "fromAsset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
            "toAsset": "11111111111111111111111111111111",
            "deadline": "1765371635",
            "amountOutMin": "7231643",
            "swapFee": "0",
            "amountIn": "1000000"
        }
    }
}
```

{% endcode %}

Save the `id` as **`quoteId`** for Step 2.

## Step 2 — Get Transaction Payload

### Endpoint

* **Method:** `GET`
* **Path:** `/aggregator/transaction`

### Required parameters

| Parameter | Description                         |
| --------- | ----------------------------------- |
| `quoteId` | The quote `id` returned from Step 1 |

### Example request

```http
GET /aggregator/transaction?quoteId=fce0bda2-4e2a-4d28-ab47-1cc7f2dcce03
```

The response contains:

* `rawData` (base64 instruction data)
* `accounts` (account metas)
* `addressLookupTables` (LUTs)
* `gasLimit` / `gasPrice` (compute budget hints)

### Example response

{% code overflow="wrap" expandable="true" %}

```json
{
    "from": "TCKx8giNDmWRJQ6Q6WZw56NcXFQmaUMnqUfvpphoxN8",
    "to": "2DAtv2URAcb9ZHVMHEB8E3TFBTk9PoNSYknjq8DVr69c",
    "data": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAFCQa16IDB9cvg17zCAT1LaDskbNvRZEpm3p5sfql9U+vVfXdJvRhcmF4jMlskIDdyWUaEFL3TT618VBpWUT6/KK1Gp8F8NM8KD0t3H5nbFja2HYuGKK4ti+Fcu3aUAwgYTydlJkVbMxbUWi7UY8Md9WRXRtGaExjrfC6sFV2xokdpAwZGb+UhFzL/7K26csOb57yM5bvF9xJrLEObOkAAAAAR+dhT4TMou0pDyV43T7ClH69cy/8FNeAne8lX3UwKT4QCuZOVQBJghwsIVTHU2DGwgWy94EnbO+XLt73nTSIuBHGbeZ/fKizkT6tVFsVuxkH1pX/d90Af0BDNiWOdcMYGp9UXGSxcUSGMyUw9SvF/WNruCJuh/UTj29mKAAAAAGtYHMeDEQKbyXO9PrVeCUIc9M7+n++moxVhaCjaCR0fAwQABQJOBQMABAAJAxm3AAAAAAAABRYQDAECDQ4AAAMFBRESExQGDwkKCwcIXvjGnpHhdYfIUgAAADAAAAWP5m4Fm1huCAVAQg8BAUBCDwcB/////////////////////wEBAwwABBcAEAAKACcAMgASDQ4PBAMQEQIBAAIBABIJCgwTBgIAAgACBQICEQqC/DKXf/8+H+lN61IKG7rQ3+3ixipxg+IdBMZQtzcDaGZwA28baQMiYqJeZwMAv7rN5ynqIMDvxQvD/ZHQ0IdvBdatwbGYASYFJwIDBAU=",
    "chainId": 900,
    "gasLimit": "236700",
    "gasPrice": "46873",
    "value": "0",
    "rawData": "+MaekeF1h8hSAAAAMAAABY/mbgWbWG4IBUBCDwEBQEIPBwH/////////////////////AQEDDAAEFwAQAAoAJwAyABINDg8EAxARAgEAAgEAEgkKDBMGAgACAAIFAg==",
    "accounts": [
        {
            "pubkey": "Gdkvc4gBWuHgnsGrzXFDJwv9qd7HQmu9tWhqtxSyPFh1",
            "isWritable": false,
            "isSigner": false
        },
        {
            "pubkey": "DJxat3ybx6UbEZgaQrTfV2ov78RecoffPTiPZmokrS6",
            "isWritable": true,
            "isSigner": false
        },
        {
            "pubkey": "9SmTkNajPiDWjd6u3aAsC8Bg2a2ytSSxYma49GuoBTiC",
            "isWritable": true,
            "isSigner": false
        },
        {
            "pubkey": "5kouNSQxM2rXkrkCNiyv2DDJWkECWcFi8RdbymcVNdUz",
            "isWritable": true,
            "isSigner": false
        },
        {
            "pubkey": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
            "isWritable": false,
            "isSigner": false
        },
        {
            "pubkey": "So11111111111111111111111111111111111111112",
            "isWritable": false,
            "isSigner": false
        },
        {
            "pubkey": "TCKx8giNDmWRJQ6Q6WZw56NcXFQmaUMnqUfvpphoxN8",
            "isWritable": true,
            "isSigner": true
        },
        {
            "pubkey": "TCKx8giNDmWRJQ6Q6WZw56NcXFQmaUMnqUfvpphoxN8",
            "isWritable": true,
            "isSigner": false
        },
        {
            "pubkey": "3enMj6EPjroS68MB2Go1rxKELYBhYw7N327MdZiivfRi",
            "isWritable": true,
            "isSigner": false
        },
        {
            "pubkey": "2DAtv2URAcb9ZHVMHEB8E3TFBTk9PoNSYknjq8DVr69c",
            "isWritable": false,
            "isSigner": false
        },
        {
            "pubkey": "2DAtv2URAcb9ZHVMHEB8E3TFBTk9PoNSYknjq8DVr69c",
            "isWritable": false,
            "isSigner": false
        },
        {
            "pubkey": "11111111111111111111111111111111",
            "isWritable": false,
            "isSigner": false
        },
        {
            "pubkey": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
            "isWritable": false,
            "isSigner": false
        },
        {
            "pubkey": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb",
            "isWritable": false,
            "isSigner": false
        },
        {
            "pubkey": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
            "isWritable": false,
            "isSigner": false
        },
        {
            "pubkey": "9tKE7Mbmj4mxDjWatikzGAtkoWosiiZX9y6J4Hfm2R8H",
            "isSigner": false,
            "isWritable": false
        },
        {
            "pubkey": "BE5YRQ6N6LCw7UL3JwzVp317EWa4mzJY6JKDaudcXu7A",
            "isSigner": false,
            "isWritable": false
        },
        {
            "pubkey": "8GmMLucoAARw9X6g2aUVBdzRpxF6egeHMDtLJen2Kkq7",
            "isSigner": false,
            "isWritable": true
        },
        {
            "pubkey": "3wgma9BjSfFKNZnWXB4YtyxFwCZ94teWJ2XbjKa7WKtp",
            "isSigner": false,
            "isWritable": true
        },
        {
            "pubkey": "GKobg2LGwECPuTw8D65upawRm5EEX9ih3yzfh1wUtf3W",
            "isSigner": false,
            "isWritable": true
        },
        {
            "pubkey": "JM78XNzeQRmZXDAP4DSq88ZdErbuSXSLE6fkRsVDKSu",
            "isSigner": false,
            "isWritable": false
        },
        {
            "pubkey": "SysvarRent111111111111111111111111111111111",
            "isSigner": false,
            "isWritable": false
        }
    ],
    "addressLookupTables": [
        "29XEC4vp5fJCa7MnD4E21AswiMSXBNrMjUcVPVV3yZUz",
        "DEdkVVtBXdxTQRKnLyvKHPggtTf9wP2XAKaWZd5KDyh"
    ]
}
```

{% endcode %}

## Step 3 — Execute the Swap Transaction

`GET /aggregator/transaction` returns everything you need to execute the swap on Solana. There are two valid ways to construct the transaction:

* Method A (Recommended): deserialize the returned `data` directly into a `VersionedTransaction`
* Method B (Manual construction): build the v0 message yourself from `rawData`, `accounts`, LUTs, and compute budget settings

### Method A (Recommended): Deserialize `data` → sign → send

The `/aggregator/transaction` response includes:

* `data`: a base64-encoded, fully-formed Solana VersionedTransaction
* `from`: user / fee payer (informational)
* `addressLookupTables`: optional metadata (not required for this method)

#### Example (TypeScript)

{% code overflow="wrap" expandable="true" %}

```ts
import {
  Connection,
  VersionedTransaction,
} from "@solana/web3.js";

type TxResponse = {
  data: string; // base64 VersionedTransaction
};

export async function executeSwapFromSerializedTx(params: {
  connection: Connection;
  walletAdapter: {
    signTransaction: (tx: VersionedTransaction) => Promise<VersionedTransaction>;
  };
  txResponse: TxResponse; // response from GET /aggregator/transaction
}) {
  const { connection, walletAdapter, txResponse } = params;

  // 1) Deserialize to VersionedTransaction
  const vTx = VersionedTransaction.deserialize(
    Buffer.from(txResponse.data, "base64")
  );

  // 2) Sign with the user's wallet / fee payer
  const signed = await walletAdapter.signTransaction(vTx);

  // 3) Send + confirm
  const sig = await connection.sendTransaction(signed);
  await connection.confirmTransaction(sig, "confirmed");

  return sig;
}
```

{% endcode %}

#### Usage example

{% code overflow="wrap" expandable="true" %}

```ts
// 1) Fetch tx payload from Magpie
const txResponse = await getTransactionPayload(quoteId); // GET /aggregator/transaction

// 2) Execute (frontend wallet)
const signature = await executeSwapFromSerializedTx({
  connection,
  walletAdapter,
  txResponse,
});

console.log("Swap submitted:", signature);
```

{% endcode %}

### Method B (Manual): Build v0 transaction from `rawData` + `accounts` + LUTs

Use this method if you need to:

* add custom instructions
* override compute budget settings
* or construct the tx explicitly for advanced flows

This is the “manual build” approach: fetch LUT accounts, add compute budget ixs, create the router instruction from `rawData`, then compile to v0.

#### Example (TypeScript)

{% code overflow="wrap" expandable="true" %}

```ts
import {
  Connection,
  PublicKey,
  ComputeBudgetProgram,
  TransactionInstruction,
  TransactionMessage,
  VersionedTransaction,
} from "@solana/web3.js";

type TxAccountMeta = { pubkey: string; isWritable: boolean; isSigner: boolean };

type TxPayload = {
  to: string; // router program id
  gasLimit: string;
  gasPrice: string;
  rawData: string; // base64 instruction payload
  accounts: TxAccountMeta[];
  addressLookupTables: string[];
};

export async function buildSwapTxManually(params: {
  connection: Connection;
  feePayer: PublicKey;
  txPayload: TxPayload;
}) {
  const { connection, feePayer, txPayload } = params;

  // 1) Resolve LUT accounts
  const lutAccounts = await Promise.all(
    txPayload.addressLookupTables.map(async (lut) => {
      const { value } = await connection.getAddressLookupTable(new PublicKey(lut));
      if (!value) throw new Error(`Missing address lookup table: ${lut}`);
      return value;
    })
  );

  // 2) Compute budget + priority fee
  const computeUnitLimitIx = ComputeBudgetProgram.setComputeUnitLimit({
    units: Number(txPayload.gasLimit),
  });
  const priorityFeeIx = ComputeBudgetProgram.setComputeUnitPrice({
    microLamports: Number(txPayload.gasPrice),
  });

  // 3) Router instruction
  const routerIx = new TransactionInstruction({
    keys: txPayload.accounts.map((a) => ({
      pubkey: new PublicKey(a.pubkey),
      isWritable: a.isWritable,
      isSigner: a.isSigner,
    })),
    programId: new PublicKey(txPayload.to),
    data: Buffer.from(txPayload.rawData, "base64"),
  });

  // 4) Fresh blockhash
  const { blockhash } = await connection.getLatestBlockhash();

  // 5) Build v0 transaction
  const messageV0 = new TransactionMessage({
    payerKey: feePayer,
    recentBlockhash: blockhash,
    instructions: [computeUnitLimitIx, priorityFeeIx, routerIx],
  }).compileToV0Message(lutAccounts);

  return new VersionedTransaction(messageV0);
}
```

{% endcode %}

#### Sign + send

```ts
const vTx = await buildSwapTxManually({
  connection,
  feePayer: walletAdapter.publicKey,
  txPayload,
});

const signed = await walletAdapter.signTransaction(vTx);
const sig = await connection.sendTransaction(signed);
await connection.confirmTransaction(sig, "confirmed");
```

### End-to-End (Recommended): Quote → Transaction → Deserialize → Sign → Send

{% code overflow="wrap" expandable="true" %}

```ts
import { Connection, VersionedTransaction } from "@solana/web3.js";

export async function swapEndToEndRecommended(params: {
  connection: Connection;
  walletAdapter: {
    publicKey: { toBase58: () => string };
    signTransaction: (tx: VersionedTransaction) => Promise<VersionedTransaction>;
  };
  apiBaseUrl: string;
  fromTokenAddress: string;
  toTokenAddress: string;
  amount: string; // smallest unit
  slippage: string; // e.g. "0.005"
  toAddress?: string;
}) {
  const {
    connection,
    walletAdapter,
    apiBaseUrl,
    fromTokenAddress,
    toTokenAddress,
    amount,
    slippage,
  } = params;

  const fromAddress = walletAdapter.publicKey.toBase58();
  const toAddress = params.toAddress ?? fromAddress;

  // 1) Quote
  const quoteUrl = new URL(`${apiBaseUrl}/aggregator/quote`);
  quoteUrl.searchParams.set("network", "solana");
  quoteUrl.searchParams.set("fromTokenAddress", fromTokenAddress);
  quoteUrl.searchParams.set("toTokenAddress", toTokenAddress);
  quoteUrl.searchParams.set("sellAmount", amount); // or "amount" depending on your API
  quoteUrl.searchParams.set("slippage", slippage);
  quoteUrl.searchParams.set("fromAddress", fromAddress);
  quoteUrl.searchParams.set("toAddress", toAddress);
  quoteUrl.searchParams.set("gasless", "false");

  const quoteRes = await fetch(quoteUrl.toString());
  if (!quoteRes.ok) throw new Error(await quoteRes.text());
  const quote = await quoteRes.json();

  // 2) Transaction payload
  const txUrl = new URL(`${apiBaseUrl}/aggregator/transaction`);
  txUrl.searchParams.set("quoteId", quote.id);

  const txRes = await fetch(txUrl.toString());
  if (!txRes.ok) throw new Error(await txRes.text());
  const txPayload = await txRes.json(); // includes `data`

  // 3) Deserialize VersionedTransaction from `data`
  const vTx = VersionedTransaction.deserialize(
    Buffer.from(txPayload.data, "base64")
  );

  // 4) Sign + send
  const signed = await walletAdapter.signTransaction(vTx);
  const sig = await connection.sendTransaction(signed);
  await connection.confirmTransaction(sig, "confirmed");

  return { signature: sig, quoteId: quote.id, amountOut: quote.amountOut };
}
```

{% endcode %}


# Requesting and Using API Key

Guide on obtaining and utilizing API keys for fly trade, enabling developers to integrate and interact with the platform's services.

## How to request API key

If you'd like an API key, open a support ticket on our [Discord](https://discord.com/invite/flytrade) in order to request one. In your request, please include detailed information about your project and/or how you intend to utilize our APIs.

## How to use API key

Include the `apikey` header alongside the request. To verify that the API key is working, check if the response contains `x-auth-status: authenticated` header.

```
$ curl -I -H 'apikey: <APIKEY>' https://api.magpiefi.xyz/ | grep -i 'x-auth-status'
```

### Endpoint Guidelines

* Public Access Endpoint: <https://api.fly.trade>
  * This endpoint is intended for general public use and does not require API key authentication.
* Authenticated Access Endpoint: <https://api.magpiefi.xyz>
  * You must use this endpoint with your API key included as described above.


# Deprecated Magpie Contracts

The magpie contracts consists of:

1. **MagpieAggregator Diamond Proxy**: This contract serves as the core module overseeing crucial functions like  "swapIn," and "swapOut," pivotal for users conducting cross-chain asset transfers. These essential operations empower users to effortlessly navigate and initiate transfers within the Magpie Protocol ecosystem.
2. **MagpieRouterV2:** This smart contract is designed for executing token swaps on the Ethereum blockchain, with features for handling various swap strategies, ensuring transaction deadlines, and integrating with multiple DeFi protocols.
3. **MagpieCelerBridge**: Designed to seamlessly integrate with the Celer Bridge, this contract plays a crucial role in receiving funds and subsequently transferring them to the Magpie Aggregator. Its primary function is to act as a bridge between the Celer Bridge and the MagpieAggregator, facilitating the smooth flow of funds.
4. **MagpieStargateBridge**: Designed to seamlessly integrate with the Stargate Bridge, this contract plays a crucial role in receiving funds and subsequently transferring them to the Magpie Aggregator. Its primary function is to act as a bridge between the Celer Bridge and the MagpieAggregator, facilitating the smooth flow of funds.
5. **MagpieStargateBridgeV2**: Similar functionality like MagpieStargateBridge. This contract was created because Stargate released a new version of their bridge.


# Why Diamond Proxy?

The diamond proxy pattern, also known as diamond dependency injection, is a design pattern used in software development to manage dependencies between objects in a flexible and modular way. Some of the benefits of using the diamond proxy pattern include:

<table><thead><tr><th width="228">Benefit</th><th>Reasoning</th></tr></thead><tbody><tr><td>Modularity</td><td>The diamond proxy pattern allows for greater modularity in software design. By encapsulating dependencies between objects within a proxy, you can modify or replace objects without affecting the rest of the system. This makes it easier to develop, test, and maintain complex systems.</td></tr><tr><td>Separation of Concerns</td><td>The diamond proxy pattern separates concerns between different objects in the system. Each object is responsible for a specific set of functionalities, and communication between objects is managed by the proxy. This makes it easier to understand and reason about the system.</td></tr><tr><td>Encapsulation</td><td>The diamond proxy pattern encapsulates dependencies and implementation details within the proxy object. This reduces coupling between objects and improves the overall design of the system. It also makes it easier to modify or replace objects without affecting the rest of the system.</td></tr><tr><td>Lazy initialization</td><td>With the diamond proxy pattern, objects are only created when they are actually needed. This reduces memory usage and improves the performance of the system.</td></tr><tr><td>Testing</td><td>The diamond proxy pattern makes it easier to test individual components of the system in isolation. You can test the behavior of each object separately and use mocks or stubs to simulate interactions between objects.</td></tr></tbody></table>

\
Overall, the diamond proxy pattern is a powerful tool for creating more modular, maintainable, and flexible software systems. By encapsulating dependencies between objects within a proxy, you can create more reliable and efficient systems that are easier to modify and extend over time.


# MagpieRouterV2

Router Contracts, facets and libraries implements a set of rules or logic to determine the correct destination for a given transaction. They can handle tasks such as validating user inputs, authorizing access to specific functions or contracts, or enforcing certain business rules before forwarding the transaction.&#x20;


# Router

Currently we are working with the following Protocols, we will add more to the list in near future:

1. UniswapV3


# LibUniswapV3

This is a Solidity library called LibUniswapV3 that provides functions for swapping assets on Uniswap v3.&#x20;

### swapUniswapV3():

The `swapUniswapV3` function is tailored for executing token swaps on Uniswap V3, a more advanced and flexible version of the Uniswap protocol. It begins by extracting key parameters from the `input` byte array using assembly for efficiency, including the amount of the input token (`amountIn`), recipient's address, pool address (`poolAddress`), input and output token addresses (`assetIn` and `assetOut`), and the swap fee (`fee`). A special `data` byte array is prepared, embedding the `assetIn` address, to be used in the swap call. The function then determines the swap direction (`zeroForOne`) based on the order of the input and output assets. It executes the swap by calling the `swap` method on the Uniswap V3 pool contract, passing parameters like the recipient, swap direction, input amount, and a price limit determined by the constants `MIN_SQRT_RATIO` and `MAX_SQRT_RATIO`. Finally, it calculates the output amount (`amountOut`) based on the returned values from the swap, ensuring the correct output amount is obtained whether swapping for token 0 or token 1 in the pool.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>input</td><td>bytes memory </td><td>A byte array containing necessary swapping parameters.</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amountOut
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount received after swapping.</td></tr></tbody></table>

### uniswapV3SwapCallback():

\
The `uniswapV3SwapCallback` function is an internal callback function used in Uniswap V3 swaps, typically called by the Uniswap V3 pool contract during a swap operation. The function first checks if both `amount0Delta` and `amount1Delta` are non-positive, in which case it reverts the transaction as this indicates an invalid state. Then, it extracts the `assetIn` address from the `data` byte array using assembly for efficient memory access. Finally, the function transfers the appropriate amount of `assetIn` (determined by whether `amount0Delta` or `amount1Delta` is positive) to the sender of the transaction (`msg.sender`), fulfilling the liquidity requirements of the swap on Uniswap V3.

**input**

| Field        | Type         | Description                                                             |
| ------------ | ------------ | ----------------------------------------------------------------------- |
| amount0Delta | int256       | the changes in the amount of the first token involved in the swap       |
| amount1Delta | int256       | the changes in the amount of the second token involved in the swap      |
| data         | bytes memory | a byte array containing additional information needed for the callback. |


# LibCommand

```solidity
enum MathOperation {
    None,
    Add,
    Sub,
    Mul,
    Div,
    Pow,
    Abs128,
    Abs256,
    Shr,
    Shl
}


```

<table><thead><tr><th>Field</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>None
</code></pre></td><td>A default operation indicating no mathematical operation is to be performed or possibly used as a placeholder.</td></tr><tr><td><pre><code>Add
</code></pre></td><td>Represents addition, the operation of adding two numbers together to find their sum.</td></tr><tr><td><pre><code>Sub
</code></pre></td><td>Represents subtraction, the operation of taking one number away from another to find the difference.</td></tr><tr><td><pre><code>Mul
</code></pre></td><td>Represents multiplication, the operation of scaling one number by another to find the product.</td></tr><tr><td><pre><code>Div
</code></pre></td><td>Represents division, the operation of determining how many times one number is contained within another to find the quotient.</td></tr><tr><td><pre><code>Pow
</code></pre></td><td>Stands for power, an operation that raises a number to the exponent of another number, essentially multiplying a number by itself a specified number of times.</td></tr><tr><td><pre><code>Abs128
</code></pre></td><td>Likely represents an operation to find the absolute value of a number within a 128-bit context, ensuring the result is positive or zero.</td></tr><tr><td><pre><code>Abs256
</code></pre></td><td>Similar to <code>Abs128</code>, this likely refers to finding the absolute value of a number within a 256-bit context, which allows for handling larger numbers.</td></tr><tr><td><pre><code>Shr
</code></pre></td><td>Stands for "shift right", a bitwise operation that shifts all bits in a binary representation of a number to the right by a specified number of positions, effectively dividing the number by a power of two.</td></tr><tr><td><pre><code>Shl
</code></pre></td><td>Stands for "shift left", a bitwise operation that shifts all bits in a binary representation of a number to the left by a specified number of positions, effectively multiplying the number by a power of two.</td></tr></tbody></table>

```solidity
enum CommandAction {
    Call,
    Approval,
    TransferFrom,
    Transfer,
    Wrap,
    Unwrap,
    Balance,
    UniswapV2,
    UniswapV3,
    TraderJoeV2_1,
    Solidly,
    KyberSwapClassic,
    Ambient
}
```

<table><thead><tr><th>Field</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>Call
</code></pre></td><td>This action representa a generic call to a function within a contract.</td></tr><tr><td><pre><code>Approval
</code></pre></td><td>Represents an approval operation.</td></tr><tr><td><pre><code>TransferFrom
</code></pre></td><td>Indicates a transfer-from operation.</td></tr><tr><td><pre><code>Transfer
</code></pre></td><td>Represents a direct transfer operation.</td></tr><tr><td><pre><code>Wrap
</code></pre></td><td>This action is used for wrapping tokens, such as converting Ether to Wrapped Ether (WETH).</td></tr><tr><td><pre><code>Unwrap
</code></pre></td><td>The opposite of Wrap, this is used for unwrapping tokens, like converting WETH back to Ether.</td></tr><tr><td><pre><code>Balance
</code></pre></td><td>to check the balance of an account or contract for a specific asset.</td></tr><tr><td><pre><code>UniswapV2
</code></pre></td><td>Represents an swap operation related to the Uniswap V2 protocol.</td></tr><tr><td><pre><code>UniswapV3
</code></pre></td><td>For swap operation specific to Uniswap V3.</td></tr><tr><td><pre><code>TraderJoeV2_1
</code></pre></td><td>Indicates swap operation related to Trader Joe V2.1.</td></tr><tr><td><pre><code>Solidly
</code></pre></td><td>Represents swap operation related to the Solidly protocol.</td></tr><tr><td><pre><code>KyberSwapClassic
</code></pre></td><td>Indicates swap operation related to KyberSwap Classic</td></tr><tr><td><pre><code>Ambient
</code></pre></td><td>Indicates swap operation related to Ambient Protocol.</td></tr></tbody></table>

```solidity
enum SequenceType {
    NativeAmount,
    Selector,
    Address,
    Amount,
    Data,
    LastAmountOut,
    RouterAddress,
    SenderAddress
}
```

<table><thead><tr><th>Field</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>NativeAmount
</code></pre></td><td>The amountIn in native tokens. </td></tr><tr><td><pre><code>Selector
</code></pre></td><td>The function selector for the command.</td></tr><tr><td><pre><code>Address
</code></pre></td><td>The recipient address.</td></tr><tr><td><pre><code>Amount
</code></pre></td><td>The amount in.</td></tr><tr><td><pre><code>Data
</code></pre></td><td>The data that contains information for the command to be performed.</td></tr><tr><td><pre><code>LastAmountOut
</code></pre></td><td>The amount received after the previous swap.</td></tr><tr><td><pre><code>RouterAddress
</code></pre></td><td>The address of the protocol router used for swapping.</td></tr><tr><td><pre><code>SenderAddress
</code></pre></td><td>The address who requested the command to be performed.</td></tr></tbody></table>

```solidity
struct CommandData {
    CommandAction commandAction;
    uint8 outputType;
    uint16 inputLength;
    uint16 sequencesPosition;
    uint16 sequencesPositionEnd;
    address targetAddress;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>commandAction
</code></pre></td><td><pre><code>CommandAction
</code></pre></td><td>This field uses the previously defined CommandAction enum to specify the type of action this command represents.</td></tr><tr><td><pre><code>outputType
</code></pre></td><td><pre><code>uint8
</code></pre></td><td>The specific meaning of this value would depend on the context in which the CommandData struct is used.</td></tr><tr><td><pre><code>inputLength
</code></pre></td><td><pre><code>uint16
</code></pre></td><td>indicating the length of the input data for this command.</td></tr><tr><td><pre><code>sequencesPosition
</code></pre></td><td><pre><code>uint16
</code></pre></td><td>specifies the starting position of a sequence of data related to this command.</td></tr><tr><td><pre><code>sequencesPositionEnd
</code></pre></td><td><pre><code>uint16
</code></pre></td><td>marks the end position of the sequence of data.</td></tr><tr><td><pre><code>targetAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>the address of a contract or an account that is the target of this command.</td></tr></tbody></table>

### getData():

The `getData` function in Solidity is designed to extract and assemble a `CommandData` structure from transaction calldata using low-level assembly operations for efficiency. It takes a single `uint16` parameter `i`, which specifies the starting position in the calldata from where data extraction should begin.

**input**

| Field | Type   | Description                                                                    |
| ----- | ------ | ------------------------------------------------------------------------------ |
| i     | uint16 | the starting position in the calldata from where data extraction should begin. |

**output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>commandData</td><td><pre><code>CommandData
</code></pre></td><td><pre><code>struct CommandData {
    CommandAction commandAction;
    uint8 outputType;
    uint16 inputLength;
    uint16 sequencesPosition;
    uint16 sequencesPositionEnd;
    address targetAddress;
}
</code></pre></td></tr></tbody></table>

### getInput():

The `getInput` function is a complex and versatile internal function designed for processing a sequence of commands encoded in a `CommandData` structure, typically used in a blockchain transaction context. It starts by initializing a dynamic `input` byte array and other local variables, including `nativeAmount`, `selector`, and various counters. The function iterates over a range of command sequences, each identified by a `SequenceType` (like `NativeAmount`, `Selector`, `Address`, etc.), and processes each sequence differently based on its type. For instance, it extracts and stores native token amounts, contract function selectors, addresses, and other data into the `input` array, adjusting the offset for each entry. The function also handles special cases, such as using the `lastAmountOut` as an input or rejecting certain types of transactions (like `transferFrom` calls in custom actions). It ensures that the length of the processed sequences matches the expected `inputLength` from `commandData`, and validates the selector for contract calls. Overall, `getInput` is a sophisticated function that dynamically constructs a transaction input from a series of encoded commands, ensuring flexibility and security in executing complex transaction sequences on the blockchain.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>lastAmountOut</td><td>uint256</td><td>The amount received after the previous swap.</td></tr><tr><td>commandData</td><td>CommandData</td><td><pre><code>struct CommandData {
    CommandAction commandAction;
    uint8 outputType;
    uint16 inputLength;
    uint16 sequencesPosition;
    uint16 sequencesPositionEnd;
    address targetAddress;
}
</code></pre></td></tr></tbody></table>

**Output**

| Field        | Type    | Description                                                         |
| ------------ | ------- | ------------------------------------------------------------------- |
| nativeAmount | uint256 | The amountIn in native tokens.                                      |
| selector     | bytes4  | The function selector for the command.                              |
| input        | bytes   | The data that contains information for the command to be performed. |

### approve():

the approve function is a utility function within a smart contract to perform an ERC-20 token approval operation. It extracts the token address, spender address, and amount from a byte array and then calls the approve function on the specified ERC-20 token contract.

**input**

| Field | Type         | Description                                           |
| ----- | ------------ | ----------------------------------------------------- |
| input | bytes memory | A byte array containing necessary approve parameters. |

### transferFrom():

the transferFrom function is a utility function within a smart contract to perform an ERC-20 token transfer from one address to another. It extracts the token address, sender address, recipient address, and amount from a byte array and then calls the transferFrom function on the specified ERC-20 token contract.

**input**

| Field | Type         | Description                                                |
| ----- | ------------ | ---------------------------------------------------------- |
| input | bytes memory | A byte array containing necessary transferFrom parameters. |

### transfer():

the transfer function is a utility function within a smart contract to perform an ERC-20 token transfer to a specified address. It extracts the token address, recipient address, and amount from a byte array and then calls the transfer function on the specified ERC-20 token contract.

**input**

| Field | Type         | Description                                            |
| ----- | ------------ | ------------------------------------------------------ |
| input | bytes memory | A byte array containing necessary transfer parameters. |

### wrap():

the wrap function is a utility function within a smart contract to convert Ether into Wrapped Ether (WETH). It extracts the WETH contract address and the amount of Ether to be wrapped from a byte array and then calls the deposit function on the WETH contract, sending the specified amount of Ether.

**input**

| Field | Type         | Description                                        |
| ----- | ------------ | -------------------------------------------------- |
| input | bytes memory | A byte array containing necessary wrap parameters. |

### unwrap():

the unwrap function is a utility function within a smart contract to convert Wrapped Ether (WETH) back into Ether. It extracts the WETH contract address and the amount of WETH to be unwrapped from a byte array and then calls the withdraw function on the WETH contract.

**Input**

| Field | Type         | Description                                          |
| ----- | ------------ | ---------------------------------------------------- |
| input | bytes memory | A byte array containing necessary unwrap parameters. |

### balance():

the balance function is a utility function within a smart contract to query the balance of a specific asset (like an ERC-20 token) held by the contract. It extracts the asset's address from a byte array and then queries the balance of that asset for the contract's address.

**Input**

| Field | Type         | Description                                           |
| ----- | ------------ | ----------------------------------------------------- |
| input | bytes memory | A byte array containing necessary balance parameters. |

### execute():

the execute function is a central part of a smart contract that needs to perform a variety of operations based on dynamic inputs. It can handle standard ERC-20 operations like approvals and transfers, wrap and unwrap Ether, interact with various DeFi protocols, and make generic contract calls.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>commandData</td><td>CommandData</td><td><pre><code>struct CommandData {
    CommandAction commandAction;
    uint8 outputType;
    uint16 inputLength;
    uint16 sequencesPosition;
    uint16 sequencesPositionEnd;
    address targetAddress;
}
</code></pre></td></tr><tr><td>nativeAmount</td><td>uint256</td><td>The amountIn in native tokens. </td></tr><tr><td>selector</td><td>bytes4</td><td>The function selector for the command.</td></tr><tr><td>input</td><td>bytes</td><td>The data that contains information for the command to be performed.</td></tr></tbody></table>

**Output**

| Field     | Type    | Description                         |
| --------- | ------- | ----------------------------------- |
| amountOut | uint256 | The amount received after the swap. |


# MagpieRouterV2

The MagpieRouterV2 contract serves as the implementation of the IMagpieRouterV2 interface. It provides functions for executing token swaps, managing operational states, and dynamically updating function selectors for handling commands. The functions enforce necessary checks and interact with underlying libraries like LibSwap, LibCommand, and LibUniswapV3 to execute operations. Key functionalities include pausing and unpausing the contract, handling swaps and silent swaps, and estimating gas usage for swaps. Access control is strictly enforced using OpenZeppelin's Ownable2Step, ensuring that only the contract owner can perform critical updates and operations.

### pause():

this function is used to pause the contract incase of any emergency.

### unpause():

this function is used to unpause the contract after the crisis has been resolved the the contract is redy to be used again.

### getSelector():

this function is used to retrieve the selector for the given command type from the Magpie Storage.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">commandType
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>The different commands like approval, transfer, transferFrom etc.</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes4
</code></pre></td><td>The function selector for each of the commands.</td></tr></tbody></table>

### updateSelector():

the updateSelector function is an administrative tool within a smart contract that allows the owner to update the mapping of command types to function selectors.

**Input**

| Field       | Type   | Description                                                       |
| ----------- | ------ | ----------------------------------------------------------------- |
| commandType | uint16 | The different commands like approval, transfer, transferFrom etc. |
| selector    | bytes4 | The function selector for each of these commands.                 |

### getSelector():

Gets the selector at the specific commandType.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">commandType
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>Identifier for each command. We have one selector / command.</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">selector
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes4
</code></pre></td><td>The function selector for the specified command.</td></tr></tbody></table>

### enforceDeadline():

the enforceDeadline function is used to enforce time constraints on certain operations within a smart contract. By checking if the current time has exceeded a specified deadline and reverting if it has, the function ensures that operations are only executed within their valid time windows.

**Input**

| Field    | Type    | Description                                                            |
| -------- | ------- | ---------------------------------------------------------------------- |
| deadline | uint256 | The timestamp in epochs beyond which the transaction will get expired. |

### fallback():

Handle uniswapV3SwapCallback requests from any protocol that is based on UniswapV3.&#x20;

**Input**

| Field        | Type           | Description                                                             |
| ------------ | -------------- | ----------------------------------------------------------------------- |
| amount0Delta | int256         | the changes in the amount of the first token involved in the swap       |
| amount1Delta | int256         | the changes in the amount of the second token involved in the swap      |
| data         | bytes calldata | a byte array containing additional information needed for the callback. |

### isTokenMovement():

This function is useful for determining whether a specific command action within a swap sequence involves moving tokens.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>commandAction</td><td>CommandAction</td><td><pre><code>enum CommandAction {
    Call,
    Approval,
    TransferFrom,
    Transfer,
    Wrap,
    Unwrap,
    Balance,
    UniswapV2,
    UniswapV3,
    TraderJoeV2_1,
    Solidly,
    KyberSwapClassic,
    Ambient
}
</code></pre></td></tr></tbody></table>

**Output**

| Field | Type | Description                                                                                                  |
| ----- | ---- | ------------------------------------------------------------------------------------------------------------ |
|       | bool | It will return true if there is a movement in tokens like approval, transfer, transferFrom, wrap and unwrap. |

### estimateSwapGas():

the estimateSwapGas function provides an external interface for estimating the gas cost of a token swap operation without actually executing the swap.

**Input**

| Field | Type           | Description                                             |
| ----- | -------------- | ------------------------------------------------------- |
|       | bytes calldata | A bytes array containing input parameters for swapping. |

**Output**

| Field     | Type    | Description                                |
| --------- | ------- | ------------------------------------------ |
| amountOut | uint256 | The amount received after swapping.        |
| gasUsed   | uint256 | The cost of gas while performing the swap. |

### swap():

the swap function provides an external interface for performing token swaps, with the additional feature of triggering events. It simplifies the swap process for external callers by handling the complexities internally through the execute function. The inclusion of event triggering makes this function suitable for scenarios where tracking swap operations is necessary

**Input**

| Field | Type           | Description                                             |
| ----- | -------------- | ------------------------------------------------------- |
|       | bytes calldata | A bytes array containing input parameters for swapping. |

**Output**

| Field     | Type    | Description                         |
| --------- | ------- | ----------------------------------- |
| amountOut | uint256 | The amount received after swapping. |

### silentSwap():

the silentSwap function provides an external interface for performing token swaps. It simplifies the swap process for external callers by handling the complexities internally through the execute function. The function's design allows for straightforward token swaps without additional overhead like event logging or gas estimation, making it suitable for users or contracts seeking to perform swaps with minimal extra features.

**Input**

| Field | Type           | Description                                             |
| ----- | -------------- | ------------------------------------------------------- |
|       | bytes calldata | A bytes array containing input parameters for swapping. |

**Output**

| Field     | Type    | Description                         |
| --------- | ------- | ----------------------------------- |
| amountOut | uint256 | The amount received after swapping. |

### execute():

the execute function is a comprehensive and versatile function that handles the execution of a sequence of commands, typically for the swap operation. It includes advanced features like gas estimation and event triggering.

**Input**

| Field        | Type | Description                                                   |
| ------------ | ---- | ------------------------------------------------------------- |
| triggerEvent | bool | An indicator if the function needs to trigger the swap event. |

**Output**

| Field     | Type    | Description                         |
| --------- | ------- | ----------------------------------- |
| amountOut | uint256 | The amount received after swapping. |
| gasUsed   | uint256 | The gas utilised during swapping.   |


# MagpieAggregator Diamond Proxy

It is a diamond proxy smart contract that handles the core logic of the magpie cross-chain swap aggregator. It includes functions for updating contract settings, performing token swaps, managing deposits, and ensuring security and access control. The use of the Diamond standard suggests a focus on modularity and upgradeability in the contract's design.


# Bridge

A bridge is used in a cross-chain swap to facilitate the transfer of digital assets between two different blockchain networks. This document contains details about how the Magpie protocol interacts with different bridges.

It contains the details about how Magpie protocol interacts with different bridges


# LibCeler

These functions manage the configuration, addition, and execution of Celer bridge transactions. They handle the interaction with the Celer bridge and logs events related to their actions. Additionally, they decode payload data and perform the necessary transaction actions for both inbound and outbound asset transfers between Celer networks and other networks. The functions include validations to ensure the Celer bridge is active and functional before executing these transactions.

### updateSetting():

Updates the Celer bridge settings in the application storage.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">celerBridgeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">CelerBridgeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct CelerBridgeSettings {
    address messageBusAddress;
}
</code></pre></td></tr></tbody></table>

### addCelerChainIds():

Adds Celer chain IDs to the application storage.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array containing identifiers for networks.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">chainIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64[]
</code></pre></td><td>An array containing chain identifiers corresponding to the networks in <code>networkIds</code>.</td></tr></tbody></table>

### addMagpieCelerBridgeAddresses():

Adds Magpie Celer bridge addresses to the application storage.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[] 
</code></pre></td><td>An array containing identifiers for networks.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieCelerBridgeAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes32[]
</code></pre></td><td>An array containing chain identifiers corresponding to the networks in <code>networkIds</code>.</td></tr></tbody></table>

### decodeBridgeInPayload():

Decodes the payload used in a Celer bridge transaction.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeInPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td><p></p><p>A bytes array that represents the input payload.</p></td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeInData
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">CelerBridgeInData
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct CelerBridgeInData {
    uint32 slippage;
    uint256 fee;
}
</code></pre></td></tr></tbody></table>

### bridgeIn():

Executes the bridge in operation for a Celer bridge, facilitating the transfer from one network to another.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct BridgeInArgs {
    uint16 recipientNetworkId;
    BridgeArgs bridgeArgs;
    uint256 amount;
    address toAssetAddress;
    TransferKey transferKey;
}
</code></pre></td></tr></tbody></table>

### bridgeOut():

Performs the bridge out operation, transferring assets from the Celer network back to the original network.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct BridgeOutArgs {
    BridgeArgs bridgeArgs;
    Transaction transaction;
    TransferKey transferKey;
}
</code></pre></td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount received after the bridgining</td></tr></tbody></table>

### Events:

```solidity
event UpdateCelerBridgeSettings(address indexed sender, CelerBridgeSettings celerBridgeSettings);
```

```solidity
event AddCelerChainIds(address indexed sender, uint16[] networkIds, uint64[] chainIds);
```

```solidity
event AddMagpieCelerBridgeAddresses(
        address indexed sender,
        uint16[] networkIds,
        bytes32[] magpieCelerBridgeAddresses
    );
```


# BridgeFacet

This is a Solidity contract that implements the `IBridge` interface. The contract has the following functions:

### updateStargateSettings():

updates the settings of the Stargate bridge.

**Input**

<table><thead><tr><th width="220.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">stargateSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">StargateSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct StargateSettings {
    address routerAddress;
}
</code></pre></td></tr></tbody></table>

### updateWormholeBridgeSettings():

updates the settings of the Wormhole bridge.

**Input**

<table><thead><tr><th width="271">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">wormholeBridgeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">WormholeBridgeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct WormholeBridgeSettings {
    address bridgeAddress;
}
</code></pre></td></tr></tbody></table>

The `updateStargateSettings` and `updateWormholeBridgeSettings` functions enforce that only the contract owner can call them, using the `enforceIsContractOwner` function from the LibDiamond library.

### updateCelerBridgeSettings():

It's a way to update and manage the settings associated with the Celer Bridge, and its execution is permissioned for the contract owner.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">celerBridgeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">CelerBridgeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct CelerBridgeSettings {
    address messageBusAddress;
}
</code></pre></td></tr></tbody></table>

### addCelerChainIds():

The function is responsible for updating the contract's settings related to chain IDs. It utilizes a modular approach where logic for handling chain IDs is encapsulated in the `LibCeler` library. The ownership check at the beginning guarantees that only the contract owner can execute this function.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array containing identifiers for networks.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">chainIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64[]
</code></pre></td><td>An array containing chain identifiers corresponding to the networks in <code>networkIds</code>.</td></tr></tbody></table>

### addMagpieCelerBridgeAddress():

This function is responsible for adding Magpie Celer bridge addresses to the contract's settings, associating them with specific network IDs.

**Input**

<table><thead><tr><th width="297.3333333333333">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array containing identifiers for networks.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieCelerBridgeAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes32[]
</code></pre></td><td>An array of <code>bytes32</code> values representing Magpie Celer Bridge addresses.</td></tr></tbody></table>

### addMagpieStargateBridgeAddresses():

This function is responsible for adding the given bridge addresses to the corresponding network IDs.

**Input**

<table><thead><tr><th width="336">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of identifier defined by the magpie team for each network</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieStargateBridgeAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes32[]
</code></pre></td><td>An array of magpieStargateBridge addresses for each network in the form of bytes32</td></tr></tbody></table>

### addMagpieStargateBridgeV2Address():

This function is responsible for adding the given bridge addresses to the corresponding network IDs.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of identifier defined by the magpie team for each network</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieStargateBridgeAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes32[]
</code></pre></td><td>An array of magpieStargateBridge addresses for each network in the form of bytes32</td></tr></tbody></table>

### getWormholeTokenSequence():

This function takes a `uint64` parameter `tokenSequence` and returns a `uint64`. It calls the `getTokenSequence` function from the `LibWormhole` library, passing the `tokenSequence` as an argument. The purpose of this function is to retrieve and return a transformed version of the `tokenSequence` using the `LibWormhole` library.

**Input**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">tokenSequence
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64
</code></pre></td><td>The token sequence defined by magpie</td></tr></tbody></table>

**Output**:

| Field | Type | Description                                |
| ----- | ---- | ------------------------------------------ |
|       |      | The token sequence receiver from wormhole. |

### bridgeIn():

This function takes a `BridgeInArgs` struct as a `calldata` parameter and does not return a value. It overrides a function declared in an interface or parent contract. It calls the `bridgeIn` function from the `LibBridge` library, passing the `bridgeInArgs` as an argument.

**Input**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct BridgeInArgs {
    uint16 recipientNetworkId;
    BridgeArgs bridgeArgs;
    uint256 amount;
    address toAssetAddress;
    TransferKey transferKey;
}
</code></pre></td></tr></tbody></table>

### bridgeOut():

This function takes a `BridgeOutArgs` struct as a `calldata` parameter and returns a `uint256` value. It overrides a function declared in an interface or parent contract. It calls the `bridgeOut` function from the `LibBridge` library, passing the `bridgeOutArgs` as an argument.

**Input**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct BridgeOutArgs {
    BridgeArgs bridgeArgs;
    Transaction transaction;
    TransferKey transferKey;
}
</code></pre></td></tr></tbody></table>


# Interface - IBridge

```solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

import {IMessageBus} from "../../interfaces/celer/IMessageBus.sol";
import {StargateSettings, WormholeBridgeSettings, CelerBridgeSettings} from "../../libraries/LibMagpieAggregator.sol";
import {TransferKey} from "../../libraries/LibTransferKey.sol";
import {BridgeInArgs, BridgeOutArgs, RefundArgs} from "../LibCommon.sol";

interface IBridge {
    event UpdateStargateSettings(address indexed sender, StargateSettings stargateSettings);

    /// @dev Allows the contract owner to update the settings required for interaction with stargate.
    /// @param stargateSettings Stargate related parameters.
    function updateStargateSettings(StargateSettings calldata stargateSettings) external;

    event UpdateWormholeBridgeSettings(address indexed sender, WormholeBridgeSettings wormholeBridgeSettings);

    /// @dev Allows the contract owner to update the settings required for interaction with wormhole
    /// @param wormholeBridgeSettings Wormhole bridge related parameters.
    function updateWormholeBridgeSettings(WormholeBridgeSettings calldata wormholeBridgeSettings) external;

    event AddCelerChainIds(address indexed sender, uint16[] networkIds, uint64[] chainIds);

    /// @dev Allows the contract owner to add Celer chain ids to the corresponding magpie network ids.
    /// @param networkIds An array containing identifiers for Magpie networks.
    /// @param chainIds An array containing chain identifiers corresponding to the network ids.
    function addCelerChainIds(uint16[] calldata networkIds, uint64[] calldata chainIds) external;

    event UpdateCelerBridgeSettings(address indexed sender, CelerBridgeSettings celerBridgeSettings);

    /// @dev Allows the contract owner to updates the Celer bridge settings.
    /// @param celerBridgeSettings Celer bridge related parameters.
    function updateCelerBridgeSettings(CelerBridgeSettings calldata celerBridgeSettings) external;

    event AddMagpieStargateBridgeAddresses(
        address indexed sender,
        uint16[] networkIds,
        bytes32[] magpieStargateBridgeAddresses
    );

    /// @dev Allows the contract owner to add Magpie stargate bridge address to its corresponding network id.
    /// @param networkIds An array containing identifiers for Magpie networks.
    /// @param magpieStargateBridgeAddresses An array containing addresses of Magpie stargate bridge corresponding to the network ids.
    function addMagpieStargateBridgeAddresses(
        uint16[] calldata networkIds,
        bytes32[] calldata magpieStargateBridgeAddresses
    ) external;

    event AddMagpieStargateBridgeV2Addresses(
        address indexed sender,
        uint16[] networkIds,
        bytes32[] magpieStargateBridgeAddresses
    );

    /// @dev Allows the contract owner to add Magpie stargate bridge V2 address to its corresponding network id.
    /// @param networkIds An array containing identifiers for Magpie networks.
    /// @param magpieStargateBridgeAddresses An array containing addresses of Magpie stargate bridge V2 corresponding to the network ids.
    function addMagpieStargateBridgeV2Addresses(
        uint16[] calldata networkIds,
        bytes32[] calldata magpieStargateBridgeAddresses
    ) external;

    event AddMagpieCelerBridgeAddresses(
        address indexed sender,
        uint16[] networkIds,
        bytes32[] magpieCelerBridgeAddresses
    );

    /// @dev Allows the contract owner to add Magpie Celer bridge addresses.
    /// @param networkIds An array containing identifiers for Magpie networks.
    /// @param magpieCelerBridgeAddresses An array containing Magpie celer bridge addresses corresponding to the networks in networkIds.
    function addMagpieCelerBridgeAddresses(
        uint16[] calldata networkIds,
        bytes32[] calldata magpieCelerBridgeAddresses
    ) external;

    /// @dev Deposits assets to the specified bridge.
    /// @param bridgeInArgs Arguments that are required for bridgeIn.
    function bridgeIn(BridgeInArgs calldata bridgeInArgs) external payable;

    /// @dev Withdraws assets from the specified bridge.
    /// @param bridgeOutArgs Arguments that are required for bridgeOut.
    function bridgeOut(BridgeOutArgs calldata bridgeOutArgs) external payable returns (uint256 amount);

    /// @dev Retrieves the Wormhole token sequence
    /// @param tokenSequence The token sequence that is generated by Magpie protocol for the specific crosschain swap.
    /// @return Value of the Wormhole token sequence.
    function getWormholeTokenSequence(uint64 tokenSequence) external view returns (uint64);
}
```

<br>


# LibCommon

It contains an enum and structs that define the data structures for passing arguments and information related to bridge operations, including bridge types, payload data, recipient network IDs, amounts, asset addresses, and transfer keys. The purpose of these data structures is to provide a standardized format for handling bridge operations and their associated parameters in the contract or system that uses them.

### BridgeType

This is an enumeration that defines two values: `Wormhole` and `Stargate`. It is used to represent different bridge types.

```solidity
enum BridgeType {
    Wormhole,
    Stargate,
    Celer
}
```

### BridgeArgs

```solidity
struct BridgeArgs {
    BridgeType bridgeType;
    bytes payload;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>bridgeType
</code></pre></td><td><pre><code>BridgeType
</code></pre></td><td>An instance of the <code>BridgeType</code> enum that specifies the type of the bridge.</td></tr><tr><td><pre><code>payload
</code></pre></td><td><pre><code>bytes
</code></pre></td><td>A <code>bytes</code> field that contains additional payload data for the bridge operation.</td></tr></tbody></table>

### BridgeInArgs

```solidity
struct BridgeInArgs {
    uint16 recipientNetworkId;
    BridgeArgs bridgeArgs;
    uint256 amount;
    address toAssetAddress;
    TransferKey transferKey;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>recipientNetworkId
</code></pre></td><td><pre><code>uint16
</code></pre></td><td>An unsigned 16-bit integer that represents the ID of the recipient network.</td></tr><tr><td><pre><code>bridgeArgs
</code></pre></td><td><pre><code>BridgeArgs
</code></pre></td><td>An instance of the <code>BridgeArgs</code> struct that contains the bridge arguments.</td></tr><tr><td><pre><code>amount
</code></pre></td><td><pre><code>uint256
</code></pre></td><td>A <code>uint256</code> value that represents the amount being bridged.</td></tr><tr><td><pre><code>toAssetAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>An <code>address</code> that specifies the address of the asset on the recipient network.</td></tr><tr><td><pre><code>transferKey
</code></pre></td><td><pre><code>TransferKey
</code></pre></td><td>An instance of the <code>TransferKey</code> struct that represents a transfer key for the bridge operation.</td></tr></tbody></table>

### BridgeOutArgs

```solidity
struct BridgeOutArgs {
    BridgeArgs bridgeArgs;
    Transaction transaction;
    TransferKey transferKey;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>bridgeArgs
</code></pre></td><td><pre><code>BridgeArgs
</code></pre></td><td>An instance of the <code>BridgeArgs</code> struct that contains the bridge arguments.</td></tr><tr><td><pre><code>transaction
</code></pre></td><td><pre><code>Transaction
</code></pre></td><td>An instance of the <code>Transaction</code> struct that represents the transaction for the bridge-out operation.</td></tr><tr><td><pre><code>transferKey
</code></pre></td><td><pre><code>TransferKey
</code></pre></td><td>An instance of the <code>TransferKey</code> struct that represents a transfer key for the bridge operation.</td></tr></tbody></table>

### RefundArgs

```solidity
struct RefundArgs {
    uint16 recipientNetworkId;
    uint256 amount;
    address toAssetAddress;
    TransferKey transferKey;
    BridgeArgs bridgeArgs;
    bytes payload;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">recipientNetworkId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>An unsigned 16-bit integer that represents the ID of the recipient network.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>A <code>uint256</code> value that represents the amount being refunded.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">toAssetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>An <code>address</code> that specifies the address of the asset on the recipient network.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">TransferKey
</code></pre></td><td>An instance of the <code>TransferKey</code> struct that represents a transfer key for the bridge operation.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeArgs
</code></pre></td><td>An instance of the <code>BridgeArgs</code> struct that contains the bridge arguments.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">payload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The bytes that contain some message which are required while bridging.</td></tr></tbody></table>


# LibStargate

This library is implementing a bridge for cross-chain communication using the Stargate protocol.&#x20;

The code defines three structs:

### StargateBridgeInData

contains the chain ID of the recipient on the other chain, the IDs of the source and destination pools, and the amount of fees to be paid.

```solidity
struct StargateBridgeInData {
    uint16 layerZeroRecipientChainId;
    uint256 sourcePoolId;
    uint256 destPoolId;
    uint256 fee;
    uint256 gasLimit;
}
```

<table><thead><tr><th width="292">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">layerZeroRecipientChainId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>This field is an unsigned 16-bit integer that represents the chain ID of the recipient on Layer 0. Layer 0 typically refers to the root blockchain or the main chain.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">sourcePoolId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>This field is a <code>uint256</code> value that represents the ID or identifier of the source pool. The exact meaning and context of the pool ID may depend on the specific implementation or protocol using this struct.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">destPoolId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>This field is a <code>uint256</code> value that represents the ID or identifier of the destination pool. Similarly to the source pool ID, the meaning and context of the destination pool ID depend on the specific implementation or protocol.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">fee
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>This field is a <code>uint256</code> value that represents the fee associated with the bridge operation.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">gasLimit
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount of gas fees one needs to execute the transaction.</td></tr></tbody></table>

### StargateBridgeOutData

contains the address of the sender's bridge contract, a nonce, and the ID of the sender's chain.

```solidity
struct StargateBridgeOutData {
    bytes srcAddress;
    uint256 nonce;
    uint16 srcChainId;
}
```

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">srcAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>This field is of type <code>bytes</code> and represents the source address.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">nonce
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>This field is of type <code>uint256</code> and represents a nonce value. Nonce is commonly used as a security measure to prevent replay attacks or ensure transaction ordering.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">srcChainId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>This field is of type <code>uint16</code> and represents the source chain ID. It identifies the chain from which the bridge-out operation originates.</td></tr></tbody></table>

### ExecuteBridgeInArgs

this struct is used to encapsulate the necessary input arguments for executing a bridge operation in the context of a Stargate bridge system. The fields hold relevant information such as network ID, token details, router address, recipient address, and additional bridge-specific data

```solidity
struct ExecuteBridgeInArgs {
    address routerAddress;
    uint256 amount;
    bytes recipientAddress;
    TransferKey transferKey;
    StargateBridgeInData bridgeInData;
    IStargateRouter.lzTxObj lzTxObj;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>routerAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>This field is of type <code>address</code> and represents the address of the router</td></tr><tr><td><pre><code>amount
</code></pre></td><td><pre><code>uint256
</code></pre></td><td>This field is of type <code>uint256</code> and represents the amount being bridged in. It specifies the quantity of tokens or assets involved in the bridge-in operation.</td></tr><tr><td><pre><code>recipientAddress
</code></pre></td><td><pre><code>bytes
</code></pre></td><td>This field is of type <code>bytes</code> and represents the recipient address. The encoding and interpretation of the recipient address may depend on the specific requirements or format of the bridge system or protocol.</td></tr><tr><td><pre><code>transferKey
</code></pre></td><td><pre><code>TransferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct TransferKey {
    uint16 networkId;
    bytes32 senderAddress;
    uint64 swapSequence;
}
</code></pre></td></tr><tr><td><pre><code>bridgeInData
</code></pre></td><td><pre><code>StargateBridgeInData
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct StargateBridgeInData {
    uint16 layerZeroRecipientChainId;
    uint256 sourcePoolId;
    uint256 destPoolId;
    uint256 fee;
}
</code></pre></td></tr><tr><td><pre><code>lzTxObj
</code></pre></td><td><pre><code>IStargateRouter.lzTxObj
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct lzTxObj {
        uint256 dstGasForCall;
        uint256 dstNativeAmount;
        bytes dstNativeAddr;
    }
</code></pre></td></tr></tbody></table>

LibStargate has the below functions:

### updateSettings

updates the stargateSettings struct in the contract's AppStorage struct.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">stargateSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">StargateSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct StargateSettings {
    address routerAddress;
}
</code></pre></td></tr></tbody></table>

### decodeBridgeOutPayload

decodes the bridgeOutPayload and returns the StargateBridgeOutData.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeOutPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload consisting of data necessary for bridging out</td></tr></tbody></table>

**Output**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeOutData
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">StargateBridgeOutData
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct StargateBridgeOutData {
    bytes srcAddress;
    uint256 nonce;
    uint16 srcChainId;
}
</code></pre></td></tr></tbody></table>

### decodeBridgeInPayload

decodes the bridgeInPayload and returns the StargateBridgeInData.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeInPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload consisting of data necessary for bridging in.</td></tr></tbody></table>

**Output**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeInData
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity"><strong>StargateBridgeInData
</strong></code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct StargateBridgeInData {
    uint16 layerZeroRecipientChainId;
    uint256 sourcePoolId;
    uint256 destPoolId;
    uint256 fee;
}
</code></pre></td></tr></tbody></table>

### getMinAmountLD

returns the minimum amount of tokens that can be bridged.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount that needs to be swapped</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeInData
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">StargateBridgeInData
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct StargateBridgeInData {
    uint16 layerZeroRecipientChainId;
    uint256 sourcePoolId;
    uint256 destPoolId;
    uint256 fee;
}
</code></pre></td></tr></tbody></table>

**Output**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">swapObj.amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The minimum amount out</td></tr></tbody></table>

### encodeRecipientAddress

this function is responsible for converting a `bytes32` Ethereum address into a 20-byte `bytes` representation, suitable for further processing or storage within the contract.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">recipientAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes32
</code></pre></td><td>The recipient address in bytes32</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">encodedRecipientAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The receipient address in bytes</td></tr></tbody></table>

### getLzTxObj

this function is responsible for creating and returning a layerZero transaction object (`lzTxObj`) based on the provided sender address.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">sender
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The address that initiated the transaction.</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">lzTxObj
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">IStargateRouter.lzTxObj
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct lzTxObj {
        uint256 dstGasForCall;
        uint256 dstNativeAmount;
        bytes dstNativeAddr;
    }
</code></pre></td></tr></tbody></table>

### bridgeIn

this function facilitates the bridging of tokens from the caller's network to a recipient network. It sets the necessary parameters, including the recipient address, bridge input data, lazy transaction object, token sequence, amount, network ID, and router address, and then calls the `executeBridgeIn` function to execute the bridge operation.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">recipientNetworkId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>The network identifier of the destination chain</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct BridgeArgs {
    BridgeType bridgeType;
    bytes payload;
}

</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount </code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256 </code></pre></td><td>The amount that needs to be swapped</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">toAssetAddress </code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address </code></pre></td><td>The final token that needs to be received</td></tr></tbody></table>

**Output**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">tokenSequence
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64
</code></pre></td><td>The sequence received after a successful bridging in</td></tr></tbody></table>

### executeBridgeIn

this function is responsible for executing the bridge-in operation by calling the `swap` function of the StargateRouter contract with the necessary arguments. It handles the transaction fee, source and destination pool IDs, sender address, amount, minimum acceptable amount, lazy transaction object, recipient address, and payload.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">executeBridgeInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">ExecuteBridgeInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct ExecuteBridgeInArgs {
    address routerAddress;
    uint256 amount;
    bytes recipientAddress;
    TransferKey transferKey;
    StargateBridgeInData bridgeInData;
    IStargateRouter.lzTxObj lzTxObj;
}
</code></pre></td></tr></tbody></table>

### bridgeOut

this function is responsible for executing the bridge out operation. It decodes the payload, retrieves the sender address, and calls the `withdraw` function of the `IMagpieStargateBridge` contract to withdraw tokens based on the provided arguments. The deposited amount for the `fromAssetAddress` is reduced accordingly.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeOutPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload consisting of data necessary for briding out.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transaction
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">Transaction
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct Transaction {
    DataTransferType dataTransferType;
    BridgeType bridgeType;
    uint16 recipientNetworkId;
    bytes32 fromAssetAddress;
    bytes32 toAssetAddress;
    bytes32 toAddress;
    bytes32 recipientAggregatorAddress;
    uint256 amountOutMin;
    uint256 swapOutGasFee;
}
</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">TransferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct TransferKey {
    uint16 networkId;
    bytes32 senderAddress;
    uint64 swapSequence;
}
</code></pre></td></tr></tbody></table>

**Output**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount received after bridging out.</td></tr></tbody></table>

### addStargateBridgeAddresses():

It updates the Magpie Stargate bridge addresses for specific network IDs within the application storage.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of unsigned 16-bit integers (<code>uint16</code>) representing network identifiers.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieStargateBridgeAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes32[]
</code></pre></td><td><p></p><p>An array of <code>bytes32</code> values representing Magpie Stargate Bridge addresses.<br></p></td></tr></tbody></table>

### addstargateBridgeV2Addresses():

It updates the Magpie Stargate bridge addresses for specific network IDs within the application storage.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of unsigned 16-bit integers (<code>uint16</code>) representing network identifiers.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieStargateBridgeAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes32[]
</code></pre></td><td>An array of <code>bytes32</code> values representing Magpie Stargate Bridge addresses.</td></tr></tbody></table>

### Events:

```solidity
event UpdateStargateSettings(address indexed sender, StargateSettings stargateSettings);
```

```solidity
event AddMagpieStargateBridgeAddresses(
        address indexed sender,
        uint16[] networkIds,
        bytes32[] magpieStargateBridgeAddresses
    );
```

```solidity
event AddMagpieStargateBridgeV2Addresses(
        address indexed sender,
        uint16[] networkIds,
        bytes32[] magpieStargateBridgeAddresses
    );
```


# LibWormhole

It provides functions for interacting with the Wormhole bridge in a decentralized exchange system.

### WormhokeBridgeInData

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">recipientBridgeChainId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>the receipient chain id as per wormhole standard.</td></tr></tbody></table>

### updateSettings()

updates the `stargateSettings` struct in the contract's `AppStorage` struct.

**Input**

<table><thead><tr><th width="273">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre class="language-solidity"><code class="lang-solidity">wormholeBridgeSettings
</code></pre></td><td><pre class="language-solidity"><code class="lang-solidity">WormholeBridgeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct WormholeBridgeSettings {
    address bridgeAddress;
}
</code></pre></td></tr></tbody></table>

### &#x20;normalize()

normalizes an amount from one decimal precision to another.

**Input**

<table><thead><tr><th width="288.3333333333333">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">fromDecimals
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint8
</code></pre></td><td>decimals of the source asset</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">toDecimals
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint8
</code></pre></td><td>decimals of the target asset</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>amount that needs to be normalized</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>the normalized amount</td></tr></tbody></table>

### &#x20;denormalize()

denormalizes an amount from one decimal precision to another.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">fromDecimals
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint8
</code></pre></td><td>decimal of the source asset</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">toDecimals
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint8
</code></pre></td><td>decimal of the target asset</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>amount that needs to be denormalized</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>the denormalized amount</td></tr></tbody></table>

### getRecipientBridgeChainId

this function is responsible for extracting the recipient bridge chain ID from the provided bridge in payload.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeInPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload necessary for bridging in.</td></tr></tbody></table>

**Output**

<table><thead><tr><th width="265">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">recipientBridgeChainId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>The receipient chain id fetched from the payload</td></tr></tbody></table>

### bridgeIn

this function is responsible for executing the bridge-in operation using the Wormhole bridge. It performs dust management operations for token amounts, approves the spending of tokens, and calls the `transferTokens` function of the Wormhole bridge contract to initiate the token transfer. The recipient bridge chain ID, Magpie aggregator address, and timestamp-based nonce are provided as arguments to the `transferTokens` function.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">recipientNetworkId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>The network identifier of the destination chain</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeArgs
</code></pre></td><td><pre><code>struct BridgeArgs {
    BridgeType bridgeType;
    bytes payload;
}
</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount that needs to be swapped</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">toAssetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The final token that needs to be received</td></tr></tbody></table>

**Output**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">tokenSequence
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64
</code></pre></td><td>The sequence received after a successful bridging in</td></tr></tbody></table>

### bridgeOut

this function is responsible for executing the bridge-out operation using the Wormhole bridge. It verifies the token sequence, extracts the amount of tokens from the payload, performs denormalization if necessary, and completes the transfer by calling the `completeTransfer` function of the Wormhole bridge contract.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeOutPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload contains data that is necessary for bridging out</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transaction
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">Transaction
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct Transaction {
    DataTransferType dataTransferType;
    BridgeType bridgeType;
    uint16 recipientNetworkId;
    bytes32 fromAssetAddress;
    bytes32 toAssetAddress;
    bytes32 toAddress;
    bytes32 recipientAggregatorAddress;
    uint256 amountOutMin;
    uint256 swapOutGasFee;
}
</code></pre></td></tr></tbody></table>

**Output**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p>   </p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount received after bridging out</td></tr></tbody></table>

### Event:

```solidity
event UpdateWormholeBridgeSettings(address indexed sender, 
WormholeBridgeSettings wormholeBridgeSettings);
```


# LibTransaction

The `LibTransaction` library provides functions for encoding and decoding a `Transaction` struct into a byte array.&#x20;

```solidity
struct Transaction {
    DataTransferType dataTransferType;
    BridgeType bridgeType;
    uint16 recipientNetworkId;
    bytes32 fromAssetAddress;
    bytes32 toAssetAddress;
    bytes32 toAddress;
    bytes32 recipientAggregatorAddress;
    uint256 amountOutMin;
    uint256 swapOutGasFee;
    uint64 tokenSequence;
}
```

<table><thead><tr><th width="311.3333333333333">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>dataTransferType
</code></pre></td><td><pre><code>DataTransferType
</code></pre></td><td><p><code>DataTransferType</code> has two named values: <code>Wormhole</code> and <code>LayerZero</code>.</p><p>Each named value is assigned an implicit integer value, starting at 0 for the first value and incrementing by 1 for each subsequent value. In this case, <code>Wormhole</code> is assigned the value 0, and <code>LayerZero</code> is assigned the value 1.</p></td></tr><tr><td><pre><code>bridgeType
</code></pre></td><td><pre><code>BridgeType
</code></pre></td><td><p><code>BridgeType</code> has two named values: <code>Wormhole</code> and <code>Stargate</code>.</p><p>Each named value is assigned an implicit integer value, starting at 0 for the first value and incrementing by 1 for each subsequent value. In this case, <code>Wormhole</code> is assigned the value 0, and <code>Stargate</code> is assigned the value 1.</p></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">recipientNetworkId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>the network id of the recipient chain.</td></tr><tr><td><pre><code>fromAssetAddress
</code></pre></td><td><pre><code>bytes32
</code></pre></td><td>the address of the source asset address that will get swapped. Example: <code>0x0000000000000000000000007b155e039f60ad89b3b3761a513238dfeebd8ab1</code></td></tr><tr><td><pre><code>toAssetAddress
</code></pre></td><td><pre><code>bytes32
</code></pre></td><td>the address of the destination asset address that will be received after swapping.<br>Example: <br><code>0x0000000000000000000000003b981e413aedcd075d96a8f28d2aaff9b15f4f01</code></td></tr><tr><td><pre><code>toAddress
</code></pre></td><td><pre><code>bytes32
</code></pre></td><td>the address of the recipient. <br>Example: <code>0x000000000000000000000000EE2249f8E5c4E84882eBA16DC991F3Fd4404C955</code></td></tr><tr><td><pre><code>recipientAggregatorAddress
</code></pre></td><td><pre><code>bytes32
</code></pre></td><td>the address of the aggregator at the destionation address. </td></tr><tr><td><pre><code>amountOutMin
</code></pre></td><td><pre><code>uint256
</code></pre></td><td>the minimum swapped amount that is acceptable by the user. Example: <code>100000000000000000</code></td></tr><tr><td><pre><code>swapOutGasFee
</code></pre></td><td><pre><code>uint256
</code></pre></td><td>the gas fee that the user can pay for the swapping. <br>Example: <code>100000</code></td></tr><tr><td><pre><code>tokenSequence
</code></pre></td><td><pre><code>uint64
</code></pre></td><td>the sequence we receive while transferring the tokens over the bridge. </td></tr></tbody></table>

<pre class="language-solidity"><code class="lang-solidity"><strong>struct TransactionValidation {
</strong>    bytes32 fromAssetAddress;
    bytes32 toAssetAddress;
    bytes32 toAddress;
    uint256 amountOutMin;
    uint256 swapOutGasFee;
}
</code></pre>

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>fromAssetAddress
</code></pre></td><td><pre><code>bytes32
</code></pre></td><td>This field is of type <code>bytes32</code> and represents the address of the asset being transferred from. The address is typically encoded as a 32-byte value.</td></tr><tr><td><pre><code>toAssetAddress
</code></pre></td><td><pre><code>bytes32
</code></pre></td><td>This field is of type <code>bytes32</code> and represents the address of the asset being transferred to. Similar to <code>fromAssetAddress</code>, it is encoded as a 32-byte value.</td></tr><tr><td><pre><code>toAddress
</code></pre></td><td><pre><code>bytes32
</code></pre></td><td>This field is of type <code>bytes32</code> and represents the destination address of the transfer. It is also encoded as a 32-byte value.</td></tr><tr><td><pre><code>amountOutMin
</code></pre></td><td><pre><code>uint256
</code></pre></td><td>This field is of type <code>uint256</code> and represents the minimum amount of the transferred asset that should be received. It defines a threshold for the expected output amount.</td></tr><tr><td><pre><code>swapOutGasFee
</code></pre></td><td><pre><code>uint256
</code></pre></td><td>This field is of type <code>uint256</code> and represents the gas fee associated with the swap or transfer operation. It specifies the amount of gas required for completing the transaction.</td></tr></tbody></table>

### encode()&#x20;

The `encode` function takes a `Transaction` struct and converts it into a byte array.&#x20;

**Input**&#x20;

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre class="language-solidity"><code class="lang-solidity">transaction
</code></pre></td><td><pre class="language-solidity"><code class="lang-solidity">Transaction
</code></pre></td><td>the transaction struct to perform the encoding.</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field </th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre class="language-solidity"><code class="lang-solidity">transactionPayload
</code></pre></td><td><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>returns the encoded data in the form of bytes.</td></tr></tbody></table>

### decode()

The `decode` function takes a byte array and converts it back into a `Transaction` struct.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre class="language-solidity"><code class="lang-solidity">transactionPayload
</code></pre></td><td><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>the payload in bytes that needs to be decoded</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre class="language-solidity"><code class="lang-solidity">transaction
</code></pre></td><td><pre class="language-solidity"><code class="lang-solidity">Transaction
</code></pre></td><td>returns the Transaction struct after the decoding is completed.</td></tr></tbody></table>


# LibBridge

provides functions for bridging assets into and out of a decentralized exchange system using either the Wormhole bridge or the Stargate bridge.

### **bridgeIn()**

The purpose of this function is to provide a unified way to bridge assets into a decentralized exchange system using either the Wormhole or Stargate bridge, depending on the bridge type specified in the `BridgeArgs` struct. This allows the decentralized exchange system to support multiple bridge types and switch between them as needed.

The function first checks the type of bridge specified in the `BridgeArgs` struct. If it is `Wormhole`, it calls the `bridgeIn` function of the `LibWormhole` library, passing in the necessary parameters. If it is `Stargate`, it calls the `bridgeIn` function of the `LibStargate` library. If the specified bridge type is neither `Wormhole` nor `Stargate`, the function reverts and throws an `InvalidBridgeType` error.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">recipientNetworkId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>network identifier of the target chain</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct BridgeArgs {
    BridgeType bridgeType;
    bytes payload;
}
</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>the amount that needs to be swapped</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">toAssetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>the target asset</td></tr></tbody></table>

**Output**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">tokenSequence
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64
</code></pre></td><td>the sequence received after a successful bridgIn</td></tr></tbody></table>

### bridgeOut()

Similar to the `bridgeIn` function but handles withdrawals of assets instead. It takes in a `BridgeArgs` struct that specifies the bridge type and the payload data for the bridge transaction. It also takes in a Transaction struct that contains information about the transaction being processed, such as the recipient address and the amount being withdrawn. Finally, it takes in a `TransferKey` struct that contains information needed to validate the withdrawal transaction. The `bridgeOut` function then delegates to the appropriate bridge implementation based on the bridge type specified in the `BridgeArgs` struct. If the bridge type is `BridgeType.Wormhole`, it calls the `bridgeOut` function in `LibWormhole`. If the bridge type is `BridgeType.Stargate`, it calls the `bridgeOut` function in `LibStargate`.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct BridgeArgs {
    BridgeType bridgeType;
    bytes payload;
}
</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transaction
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">Transaction
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct Transaction {
    DataTransferType dataTransferType;
    BridgeType bridgeType;
    uint16 recipientNetworkId;
    bytes32 fromAssetAddress;
    bytes32 toAssetAddress;
    bytes32 toAddress;
    bytes32 recipientAggregatorAddress;
    uint256 amountOutMin;
    uint256 swapOutGasFee;
}
</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">TransferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct TransferKey {
    uint16 networkId;
    bytes32 senderAddress;
    uint64 swapSequence;
}
</code></pre></td></tr></tbody></table>

**Output**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount received after bridging out.</td></tr></tbody></table>


# Data Transfer

Data transfer protocols like Wormhole and LayerZero play a crucial role in enabling cross-chain communication and interoperability. Both Wormhole and LayerZero share the goal of enhancing interoperability in the Web3 space, allowing for more fluid and efficient communication and transfer of data and assets across different blockchain networks. This interoperability is key to the growth and scalability of decentralized applications and platforms in the Web3 ecosystem.


# DataTransferFacet

This is a Solidity contract implementing the IDataTransfer interface. It contains several functions related to updating settings and receiving data transfers.

### **updateLayerZeroSettings**

allows the contract owner to update the LayerZeroSettings struct, which contains settings for Layer 0 networks.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">layerZeroSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">LayerZeroSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct LayerZeroSettings {
    address routerAddress;
}
</code></pre></td></tr></tbody></table>

### **addLayerZeroChainIds**&#x20;

allow the contract owner to add LayerZero chain IDs.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of network identifier for each blockchain. These are defined by the magpie team.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">chainIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of blockchain identifiers</td></tr></tbody></table>

### addLayerZeroNetworkIds

allows the contract owner to add LayerZero network IDs.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">chainIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of blockchain identifiers</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of network identifier for each blockchain. These are defined by the layerzero team.</td></tr></tbody></table>

### **updateWormholeSettings**

allows the contract owner to update the WormholeSettings struct, which contains settings for the Wormhole bridge.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">wormholeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">WormholeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct WormholeSettings {
    address bridgeAddress;
    uint8 consistencyLevel;
}
</code></pre></td></tr></tbody></table>

### **addWormholeNetworkIds**

allows the contract owner to add mappings between Wormhole chain IDs and network IDs.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">chainIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of blockchain identifiers</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of network identifier for each blockchain. These are defined by the wormhole team.</td></tr></tbody></table>

### getWormholeCoreSequence

this function provides a way to obtain the core sequence from a transfer key's core sequence by calling the `getCoreSequence` function from the `LibWormhole` library. It allows external callers to retrieve the core sequence without modifying the contract's state.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKeyCoreSequence
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64
</code></pre></td><td>The sequence provide by magpie team for the data transfer</td></tr></tbody></table>

### **lzReceive**

called by LayerZero to initiate a data transfer. It enforces that the function is called by a LayerZero contract and then calls the lzReceive function in the LibLayerZero library, which handles the actual data transfer.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">senderChainId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>The chain id of the source chain</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">localAndRemoteAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The address which will receive the data</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">nonce
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64
</code></pre></td><td>random or pseudo-random number that is used only once.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">extendedPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload + extra information like which data transfer type has been used</td></tr></tbody></table>

### dataTransferIn():

It calls the `dataTransfer` function from the `LibDataTransfer` library, passing the `dataTransferInArgs` as an argument.

**Input**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">dataTransferInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DataTransferInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct DataTransferInArgs {
    DataTransferInProtocol protocol;
    TransferKey transferKey;
    bytes payload;
}
</code></pre></td></tr></tbody></table>

### dataTransferOut():

It calls the `getPayload` function from the `LibDataTransfer` library, passing the `dataTransferOutArgs` as an argument.

**Input**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">dataTransferOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DataTransferOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct DataTransferOutArgs {
    DataTransferType dataTransferType;
    bytes payload;
}
</code></pre></td></tr></tbody></table>


# Interface - IDataTransfer

````solidity


interface IDataTransfer {
    event UpdateLayerZeroSettings(address indexed sender, LayerZeroSettings layerZeroSettings);

    /// @dev Allows the contract owner to update the LayerZero settings
    /// @param layerZeroSettings LayerZero related parameters.
    function updateLayerZeroSettings(LayerZeroSettings calldata layerZeroSettings) external;

    event AddLayerZeroChainIds(address indexed sender, uint16[] networkIds, uint16[] chainIds);

    /// @dev Allows the contract owner to add LayerZero chain ids to the corresponding magpie network ids.
    /// @param networkIds An array containing identifiers for Magpie networks.
    /// @param chainIds An array containing chain identifiers corresponding to the network ids.
    function addLayerZeroChainIds(uint16[] calldata networkIds, uint16[] calldata chainIds) external;

    event AddLayerZeroNetworkIds(address indexed sender, uint16[] chainIds, uint16[] networkIds);

    /// @dev Allows the contract owner to add Magpie network ids to the corresponding LayerZero chain ids.
    /// @param chainIds An array containing chain identifiers corresponding to the network ids.
    /// @param networkIds An array containing identifiers for Magpie networks.
    function addLayerZeroNetworkIds(uint16[] calldata chainIds, uint16[] calldata networkIds) external;

    event UpdateWormholeSettings(address indexed sender, WormholeSettings wormholeSettings);

    /// @dev Allows the contract owner to update the settings required for interaction with Wormhole.
    /// @param wormholeSettings Wormhole related parameters.
    function updateWormholeSettings(WormholeSettings calldata wormholeSettings) external;

    event AddWormholeNetworkIds(address indexed sender, uint16[] chainIds, uint16[] networkIds);

    /// @dev Allows the contract owner to add Magpie network ids to the corresponding Wormhole chain ids.
    /// @param chainIds An array containing chain identifiers corresponding to the network ids.
    /// @param networkIds An array containing identifiers for Magpie networks.
    function addWormholeNetworkIds(uint16[] calldata chainIds, uint16[] calldata networkIds) external;

    /// @dev Retrieves the Wormhole core sequence.
    /// @param transferKeyCoreSequence Magpie transferKey sequence that is generated for each crosschain swap.
    function getWormholeCoreSequence(uint64 transferKeyCoreSequence) external view returns (uint64);

    event LzReceive(TransferKey transferKey, bytes payload);

    /// @dev Allows LayerZero to send message corresponding to a specific crosschain swap.
    /// @param senderChainId The LayerZero chain identifier for the source chain.
    /// @param senderAddress The address of the origin contract.
    /// @param nonce Unique identifier for the message.
    /// @param extendedPayload Payload of the specific crosschain swap.
    function lzReceive(
        uint16 senderChainId,
        bytes calldata senderAddress,
        uint64 nonce,
        bytes calldata extendedPayload
    ) external;

    /// @dev Sends swap data to a data transfer protocol
    function dataTransferIn(DataTransferInArgs calldata dataTransferInArgs) external payable;

    /// @dev Recives swap data from a data transfer protocol
    function dataTransferOut(
        DataTransferOutArgs calldata dataTransferOutArgs
    ) external payable returns (TransferKey memory, bytes memory);
}

```
````


# LibCommon

It contains an enum and structs that are used to encapsulate and pass relevant information and parameters for data transfer operations. They store details such as the data transfer protocol, transfer key, payload, and data transfer type. The specific usage and implementation of these structs would depend on the context and requirements of the data transfer system or protocol being used.

### DataTransferKey

```solidity
enum DataTransferType {
    Wormhole,
    LayerZero
}
```

### DataTransferInProtocol

```solidity
struct DataTransferInProtocol {
    uint16 networkId;
    DataTransferType dataTransferType;
    bytes payload;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>networkId
</code></pre></td><td><pre><code>uint16
</code></pre></td><td>This field is of type <code>uint16</code> and represents the network ID of the data transfer protocol.</td></tr><tr><td><pre><code>dataTransferType
</code></pre></td><td><pre><code>DataTransferType
</code></pre></td><td>This field is of type <code>DataTransferType</code> (an enum) and represents the type of data transfer, either Wormhole or LayerZero.</td></tr><tr><td><pre><code>payload
</code></pre></td><td><pre><code>bytes
</code></pre></td><td>This field is of type <code>bytes</code> and represents the payload of the data transfer.</td></tr></tbody></table>

### DataTransferInArgs

```solidity
struct DataTransferInArgs {
    DataTransferInProtocol protocol;
    TransferKey transferKey;
    bytes payload;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>protocol
</code></pre></td><td><pre><code>DataTransferInProtocol
</code></pre></td><td>This field is of type <code>DataTransferInProtocol</code> and represents the data transfer protocol details, including the network ID, data transfer type, and payload.</td></tr><tr><td><pre><code>transferKey
</code></pre></td><td><pre><code>TransferKey
</code></pre></td><td>This field is of type <code>TransferKey</code> and represents a transfer key associated with the data transfer.</td></tr><tr><td><pre><code>payload
</code></pre></td><td><pre><code>bytes
</code></pre></td><td>This field is of type <code>bytes</code> and represents the payload of the data transfer.</td></tr></tbody></table>

### DataTransferOutArgs

```solidity
struct DataTransferOutArgs {
    DataTransferType dataTransferType;
    bytes payload;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>dataTransferType
</code></pre></td><td><pre><code>DataTransferType
</code></pre></td><td>This field is of type <code>DataTransferType</code> (an enum) and represents the type of data transfer, either Wormhole or LayerZero.</td></tr><tr><td><pre><code>payload
</code></pre></td><td><pre><code>bytes
</code></pre></td><td>This field is of type <code>bytes</code> and represents the payload of the data transfer.</td></tr></tbody></table>


# LibDataTransfer

This is a Solidity smart contract library that provides functions related to data transfer between different blockchain networks or layers.&#x20;

### getOriginalPayload()

this function is responsible for extracting the original payload from the extended payload by slicing the `extendedPayload` from the 42nd byte to the end. It removes the extended part of the payload and returns the original payload.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">extendedPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload + extra information like which data transfer type has been used</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>payload</td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>the original payload</td></tr></tbody></table>

### dataTransfer()

this function is responsible for executing data transfer operations based on the specified protocols. It increments the core sequence, creates a transfer key, generates the extended payload, and processes each protocol in `dataTransferInArgs.protocols`. Depending on the protocol's `dataTransferType`, either the Wormhole or LayerZero data transfer function is called. If an unrecognised `dataTransferType` is encountered, the function reverts with an error.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">dataTransferInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DataTransferInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct DataTransferInArgs {
    DataTransferInProtocol protocol;
    TransferKey transferKey;
    bytes payload;
}

</code></pre></td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">TransferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct TransferKey {
    uint16 networkId;
    bytes32 senderAddress;
    uint64 swapSequence;
}
</code></pre></td></tr></tbody></table>

### getPayload()

this function is responsible for obtaining the transfer key and payload based on the specified data transfer type. Depending on the `dataTransferType` in `dataTransferOutArgs`, either the Wormhole or LayerZero library functions are called to obtain the payload.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">dataTransferOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DataTransferOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct DataTransferOutArgs {
    DataTransferType dataTransferType;
    bytes payload;
}
</code></pre></td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">TransferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct TransferKey {
    uint16 networkId;
    bytes32 senderAddress;
    uint64 swapSequence;
}
</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">payload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The data necessary for swapping.</td></tr></tbody></table>


# LibWormhole

Contains several functions for interacting with a Wormhole bridge, which is a cross-chain communication protocol that allows tokens and other data to be transferred between different blockchains.

### updateSettings()

updates the wormholeSettings variable in the AppStorage struct with the provided wormholeSettings input parameter. The new settings are emitted in an UpdateWormholeSettings event.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">wormholeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">WormholeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct WormholeSettings {
    address bridgeAddress;
    uint8 consistencyLevel;
}
</code></pre></td></tr></tbody></table>

### addWormholeNetworkIds()

adds multiple chainIds and networkIds to the wormholeNetworkIds mapping in AppStorage. The new mappings are emitted in an AddWormholeNetworkIds event.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">chainIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of wormhole chain identifiers</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of network identifiers provided by magpie team.</td></tr></tbody></table>

### dataTransfer()

transfers data across the Wormhole bridge by calling the publishMessage function on a Wormhole core contract with a given payload, timestamp, and consistency level.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">payload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload that contains the data which will be transferred over the blockchains</td></tr></tbody></table>

### getPayload()

verifies and returns the payload of a Wormhole message. It uses the parseAndVerifyVM function on a Wormhole core contract to check the validity of the message, and then extracts and returns the payload of the message..

**Input**

<table><thead><tr><th width="252.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">dataTransferOutPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>payload required for receiving the data</td></tr></tbody></table>

**Output**

<table><thead><tr><th width="255.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">extendedPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload + extra information like which data transfer type has been used</td></tr></tbody></table>

### getCoreSequence()

this function is responsible for retrieving the core sequence value from the `s.wormholeCoreSequences` mapping based on the provided `transferKeyCoreSequence`.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKeyCoreSequence
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64
</code></pre></td><td>The core sequence provided by magpie for data transfer</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">s.wormholeCoreSequences[transferKeyCoreSequence]
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64
</code></pre></td><td>The sequence received by the wormhole core bridge.</td></tr></tbody></table>

### Events:

```solidity
event UpdateWormholeSettings(address indexed sender, WormholeSettings wormholeSettings);
```

```solidity
event AddWormholeNetworkIds(address indexed sender, uint16[] chainIds, uint16[] networkIds);
```


# LibLayerZero

The `LibLayerZero` library provides functions for updating Layer Zero settings, handling Layer Zero data transfers (in and out), decoding and encoding data transfer payloads, registering and retrieving extended payloads, and enforcing authorization for Layer Zero operations. It consist of two structs:

### updateSettings()

updates the LayerZero settings of the Magpie aggregator contract by storing the given LayerZeroSettings struct in the storage of the aggregator contract.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">layerZeroSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">LayerZeroSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct LayerZeroSettings {
    address routerAddress;
}
</code></pre></td></tr></tbody></table>

### addLayerZeroChainIds()

used to add a mapping of network IDs to chain IDs in LayerZero. Takes two arrays as input, networkIds and chainIds, where the i-th element of the networkIds array corresponds to the i-th element of the chainIds array.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of network identifiers provided by magpie team.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">chainIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of layer zero blockchain identifiers</td></tr></tbody></table>

### addLayerZeroNetworkIds()

used to add a mapping of chain IDs to network IDs in LayerZero. Takes two arrays as input, chainIds and networkIds, where the i-th element of the chainIds array corresponds to the i-th element of the networkIds array.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">chainIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of layer zero blockchain identifiers</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>An array of network identifiers provided by magpie team.</td></tr></tbody></table>

### decodeDataTransferInPayload()

takes a byte array as input and returns a LayerZeroDataTransferInData struct. This struct contains the fee that is required to be paid for the data transfer.

**Input**

<table><thead><tr><th width="282">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">dataTransferInPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload required for transfering data from one chain to another</td></tr></tbody></table>

**Output**

<table><thead><tr><th width="289">Field</th><th width="290">Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">dataTransferInData
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">LayerZeroDataTransferInData
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct LayerZeroDataTransferInData {
    uint256 fee;
}
</code></pre></td></tr></tbody></table>

### encodeRemoteAndLocalAddresses()

this function is responsible for encoding the remote and local addresses into a `bytes` array.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">remoteAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes32
</code></pre></td><td>target address</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">localAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>source address</td></tr></tbody></table>

**Output**

<table><thead><tr><th width="338.3333333333333">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">encodedRemoteAndLocalAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>concatenated target and source address</td></tr></tbody></table>

### dataTransfer()

responsible for transferring data using LayerZero. It takes two parameters as input: payload, which is the data that is to be transferred, and protocol, which is a DataTransferInProtocol struct that contains the payload and network ID.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">payload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload necessary for data transfer</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">protocol
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DataTransferInProtocol
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct DataTransferInProtocol {
    uint16 networkId;
    DataTransferType dataTransferType;
    bytes payload;
}
</code></pre></td></tr></tbody></table>

### getPayload()

takes a byte as input, which is the data transfer out payload, and returns the extended payload for the message using the sender network ID, sender address, and core sequence of the message.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">dataTransferOutPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload necessary for data transfer</td></tr></tbody></table>

**Output**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">extendedPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload + extra information like which data transfer type has been used</td></tr></tbody></table>

### registerPayload()

takes a TransferKey struct and a byte array as input and registers the extended payload for the message in the storage of the aggregator contract.

**Input**

<table><thead><tr><th width="216.99999999999997">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">TransferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct TransferKey {
    uint16 networkId;
    bytes32 senderAddress;
    uint64 swapSequence;
}
</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">extendedPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload + extra information like which data transfer type has been used</td></tr></tbody></table>

### lzReceive()

is called when a message is received by the contract. It takes three parameters as input: senderChainId, which is the ID of the chain that sent the message, localAndRemoteAddresses, which is a byte array that contains the local and remote addresses of the sender, and extendedPayload, which is the extended payload for the message. This function validates the message and registers the extended payload for the message in the storage of the aggregator contract.

**Input**

<table><thead><tr><th width="286">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">senderChainId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>The layer zero chain identifier for the source chain</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">localAndRemoteAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The address that will receive the data from layerzero</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">extendedPayload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Payload + extra information like which data transfer type has been used</td></tr></tbody></table>

### Events:

```solidity
event UpdateLayerZeroSettings(address indexed sender, LayerZeroSettings layerZeroSettings);
```

```solidity
event AddLayerZeroChainIds(address indexed sender, uint16[] networkIds, uint16[] chainIds);
```

```solidity
event AddLayerZeroNetworkIds(address indexed sender, uint16[] chainIds, uint16[] networkIds);
```

```solidity
event LzReceive(TransferKey transferKey, bytes payload);
```


# Aggregator

The aggregator is used to perform on-chain and cross-chain swap. The aggregator also lets the user estimate gas for a particular kind of swap. And also to check if a transfer key has been used.&#x20;


# AggregatorFacet

The `AggregatorFacet` contract serves as the implementation of the `IAggregator` interface. It provides functions for updating settings, performing swaps, managing deposits, retrieving payloads, and checking transfer key usage. The functions enforce necessary checks and interact with the underlying `LibAggregator` library to execute the operations.

### updateWeth()

The purpose of this function is to allow the contract owner to update the address of the WETH token used in the aggregator contract.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">weth
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of wrapped native address (WETH for Ethereum, WMATIC for Polygon etc.)</td></tr></tbody></table>

### updateMagpieRouterAddress()

the `updateMagpieRouterAddress` function is a straightforward administrative function that allows the contract owner to update a critical component of the system, in this case, the address of the Magpie Router.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieRouterAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>This new address is  the updated address for the Magpie Router within the contract.</td></tr></tbody></table>

### updateNetworkId()

The purpose of this function is to allow the contract owner to update the network ID used in the aggregator contract.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>networkId of the current chain in Magpie protocol, it is different from the actual networkId<br>ethereum: 1<br>polygon: 2<br>bsc: 3<br>avalanche: 4<br>arbitrum: 5 <br>optimism: 6<br></td></tr></tbody></table>

### addMagpieAggregatorAddresses()

The purpose of this function is to allow the contract owner to add Magpie aggregator addresses for multiple network IDs in the aggregator contract.

**Input**

<table><thead><tr><th width="311.3333333333333">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>networkIds of the networks we want to add</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieAggregatorAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes32[]
</code></pre></td><td>Address of MagpieAggregator contracts on the specified chains/networks</td></tr></tbody></table>

### swapIn()

this function is responsible for executing a swap-in operation. It enforces various checks such as the deadline, pausing status, and custom guards.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">swapInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">SwapInArgs
</code></pre></td><td>SwapInArgs is a struct, its explained <a href="/pages/GofltEY63pRiP44jn7UJ#swapinargs">here</a></td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amountOut
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>amountOut that you will receive after swapping tokens</td></tr></tbody></table>

### swapOut()

this function is responsible for executing a swap-out operation. It enforces various checks such as the deadline, pausing status, and custom guards.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">swapOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">SwapOutArgs
</code></pre></td><td>SwapOutArgs is a struct, its explained <a href="/pages/GofltEY63pRiP44jn7UJ#swapoutargs">here</a></td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amountOut
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>amountOut that you will receive after swapping tokens</td></tr></tbody></table>

### getDeposit()

The purpose of this function is to allow external callers to retrieve the deposit amount for a specific asset in the aggregator contract.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">assetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the token for which you want to query deposit</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>It returns the amount of deposited assets </td></tr></tbody></table>

### withdraw()

The purpose of this function is to allow external callers to initiate the withdrawal of funds from the aggregator contract for a specific asset.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">assetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the token which will be withdrawn</td></tr></tbody></table>

### getDepositByUser()

The purpose of this function is to allow external callers to retrieve the deposit amount for a specific asset deposited by a specific user in the aggregator contract.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">assetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>the address of the asset whose deposited amount needs to be retrieved</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">senderAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>the address of the user who has deposited the asset</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>amount</td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>the deposited amount</td></tr></tbody></table>

### isTransferKeyUsed()

The purpose of this function is to allow external callers to check if a specific transfer key has been used in the aggregator contract.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>the source network identifier provided by the magpie team for each bloackchain</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">senderAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes32
</code></pre></td><td>the address of the user </td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">coreSequence
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64
</code></pre></td><td>the sequence stored in our data base</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bool
</code></pre></td><td>True if the key has been used false if not</td></tr></tbody></table>


# LibAggregator

The purpose of this library is to provide the core functionality for aggregating swap transactions and managing related operations within the Aggregator contract. The library has three structs.

### SwapInArgs

<table><thead><tr><th width="269.6666666666667">Field</th><th width="250">Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">swapArgs
</code></pre></td><td>bytes memory</td><td></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct BridgeArgs {
    BridgeType bridgeType;
    bytes payload;
}
</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">dataTransferInProtocol
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DataTransferInProtocol
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct DataTransferInProtocol {
    uint16 networkId;
    DataTransferType dataTransferType;
    bytes payload;
}
</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transactionValidation
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">TransactionValidation
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct TransactionValidation {
    bytes32 fromAssetAddress;
    bytes32 toAssetAddress;
    bytes32 toAddress;
    uint256 amountOutMin;
    uint256 swapOutGasFee;
}
</code></pre></td></tr></tbody></table>

### SwapOutArgs

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">swapArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes memory
</code></pre></td><td></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct BridgeArgs {
    BridgeType bridgeType;
    bytes payload;
}
</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">dataTransferOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DataTransferOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct DataTransferOutArgs {
    DataTransferType dataTransferType;
    bytes payload;
}
</code></pre></td></tr></tbody></table>

### SwapOutVariables

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">fromAssetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The address of the asset being swapped out.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">toAssetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The address of the asset to which the swap is being performed.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">toAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The address to which the swapped asset will be transferred.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transactionToAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The address to which any transaction fee associated with the swap will be sent.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeAmount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount of the asset being swapped out.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amountIn
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount of the asset being swapped out.</td></tr></tbody></table>

### updateWeth()

The purpose of this function is to allow the contract owner to update the address of the WETH token used in the aggregator contract.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">weth
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the Wrapped Ether (WETH) contract.</td></tr></tbody></table>

### updateMagpieRouterAddress()

This function is responsible for updating the `magpieRouterAddress` variable within the contract's storage, allowing changes to be made to the address associated with the Magpie Router. Only contract owner can call this function.

Input

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieRouterAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The address of the magpie router.</td></tr></tbody></table>

### updateNetworkId()

The purpose of this function is to allow the contract owner to update the network ID used in the aggregator contract. Only contract owner can call this function.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>The network ID associated with the application.</td></tr></tbody></table>

### addMagpieAggregatorAddresses()

The purpose of this function is to allow the contract owner to add Magpie aggregator addresses for multiple network IDs in the aggregator contract.

**Input**

<table><thead><tr><th width="311.3333333333333">Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16[]
</code></pre></td><td>The network ID associated with the application.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieAggregatorAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes32[]
</code></pre></td><td>The Magpie Diamond contract addresses for each of the networkIDs</td></tr></tbody></table>

### swapIn()

This function allows for swapping assets into the contract using a bridge-in transaction. It facilitates interoperability between different networks and allows users to transfer assets from one network to another through the contract.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">swapInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">SwapInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct SwapInArgs {
    SwapArgs swapArgs;
    BridgeArgs bridgeArgs;
    DataTransferInProtocol dataTransferInProtocol;
    TransactionValidation transactionValidation;
}
</code></pre></td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amountOut
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount received after swapping</td></tr></tbody></table>

### swapOut()

This function allows for swapping out assets from the contract using a bridge-out transaction. It facilitates interoperability between different networks and allows users to transfer assets from the contract to another network through the bridge-out mechanism.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">swapOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">SwapOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct SwapOutArgs {
    SwapArgs swapArgs;
    BridgeArgs bridgeArgs;
    DataTransferOutArgs dataTransferOutArgs;
}
</code></pre></td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amountOut
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount received after swapping</td></tr></tbody></table>

### getDeposit()

The purpose of this function is to allow external callers to retrieve the deposit amount for a specific asset in the aggregator contract.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">assetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the asset that will be deposited</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">s.deposits[assetAddress]
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The deposited amount</td></tr></tbody></table>

### withdraw()

This function provides a way for users to withdraw their deposited assets from the contract, ensuring that only the rightful owner can withdraw their funds.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">assetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The asset that will be withdrawn</td></tr></tbody></table>

### getDepositByUser()

The purpose of this function is to allow external callers to retrieve the deposit amount for a specific asset deposited by a specific user in the aggregator contract.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">assetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the asset that will be deposited</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">senderAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the user who has deposited the asset</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">s.depositsByUser[assetAddress][senderAddress]
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>Deposited amount</td></tr></tbody></table>

### isTransferKeyUsed()

The purpose of this function is to allow external callers to check if a specific transfer key has been used in the aggregator contract.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>networkId of the current chain in Magpie protocol, it is different from the actual networkId<br>ethereum: 1<br>polygon: 2<br>bsc: 3<br>avalanche: 4<br>arbitrum: 5 <br>optimism: 6</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">senderAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes32
</code></pre></td><td>The address who initiated the transfer.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">coreSequence
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64
</code></pre></td><td>The magpie sequence for the current swap.</td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">s.usedTransferKeys[networkId][senderAddress][swapSequence]
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bool
</code></pre></td><td>Flag used to identify if the transfer key has been used for swapping or not.</td></tr></tbody></table>

### bridgeIn():

This function is responsible for executing a delegatecall to a specific facet in the Diamond contract, passing the `bridgeInArgs` data as the input. The specific functionality and behavior of the called facet would depend on the implementation details defined in the facet contract associated with the given selector.

**Input**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeInArgs
</code></pre></td><td><pre><code>struct BridgeInArgs {
    uint16 recipientNetworkId;
    BridgeArgs bridgeArgs;
    uint256 amount;
    address toAssetAddress;
    TransferKey transferKey;
}
</code></pre></td></tr></tbody></table>

### bridgeOut():

his function is responsible for executing a delegatecall to a specific facet in the Diamond contract, passing the `bridgeOutArgs` data as the input. The specific functionality and behavior of the called facet would depend on the implementation details defined in the facet contract associated with the given selector. The function expects the delegatecall to return a single `uint256` value, which is then returned by the function itself.

**Input**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">bridgeOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">BridgeOutArgs
</code></pre></td><td><pre><code>struct BridgeOutArgs {
    BridgeArgs bridgeArgs;
    Transaction transaction;
    TransferKey transferKey;
}
</code></pre></td></tr></tbody></table>

### dataTransferIn():

This function is responsible for executing a delegatecall to a specific facet in the Diamond contract, passing the `dataTransferInArgs` data as the input. The specific functionality and behavior of the called facet would depend on the implementation details defined in the facet contract associated with the given selector.

**Input**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">dataTransferInArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DataTransferInArgs
</code></pre></td><td><pre><code>struct DataTransferInArgs {
    DataTransferInProtocol protocol;
    TransferKey transferKey;
    bytes payload;
}
</code></pre></td></tr></tbody></table>

### dataTransferOut():

**Input**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">dataTransferOutArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DataTransferOutArgs
</code></pre></td><td><pre><code>struct DataTransferOutArgs {
    DataTransferType dataTransferType;
    bytes payload;
}
</code></pre></td></tr></tbody></table>

**Output**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>transferKey</td><td><p></p><pre class="language-solidity"><code class="lang-solidity">TransferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct TransferKey {
    uint16 networkId;
    bytes32 senderAddress;
    uint64 swapSequence;
}
</code></pre></td></tr><tr><td>payload</td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>A string of bytes that contains transactional data.</td></tr></tbody></table>

### Events:

```solidity
event UpdateWeth(address indexed sender, address weth);
```

```solidity
event UpdateMagpieRouterAddress(address indexed sender, address weth);
```

```solidity
event UpdateNetworkId(address indexed sender, uint16 networkId);
```

```solidity
event AddMagpieAggregatorAddresses(
        address indexed sender,
        uint16[] networkIds,
        bytes32[] magpieAggregatorAddresses
    );
```

```solidity
event SwapIn(
        address indexed fromAddress,
        bytes32 indexed toAddress,
        address fromAssetAddress,
        address toAssetAddress,
        uint256 amountIn,
        uint256 amountOut,
        TransferKey transferKey,
        Transaction transaction
    );
```

```solidity
event SwapOut(
        address indexed fromAddress,
        address indexed toAddress,
        address fromAssetAddress,
        address toAssetAddress,
        uint256 amountIn,
        uint256 amountOut,
        TransferKey transferKey,
        Transaction transaction
    );
```

```solidity
 event Withdraw(address indexed sender, address indexed assetAddress, uint256 amount);
```


# Interface - IAggregator

```solidity
interface IAggregator {
    event UpdateWeth(address indexed sender, address weth);

    /// @dev Allows the contract owner to update the address of wrapped native token.
    /// @param weth Address of the wrapped native token.
    function updateWeth(address weth) external;

    event UpdateNetworkId(address indexed sender, uint16 networkId);

    /// @dev Allows the contract owner to update the network id in the storage.
    /// @param networkId Magpie network id associated with the chain.
    function updateNetworkId(uint16 networkId) external;

    event AddMagpieAggregatorAddresses(
        address indexed sender,
        uint16[] networkIds,
        bytes32[] magpieAggregatorAddresses
    );

    /// @dev Allows the contract owner to add Magpie Aggregator addresses for multiple network ids.
    /// @param networkIds Magpie network id associated with the chain.
    /// @param magpieAggregatorAddresses The Magpie Aggregator diamond contract addresses for the related network ids.
    function addMagpieAggregatorAddresses(
        uint16[] calldata networkIds,
        bytes32[] calldata magpieAggregatorAddresses
    ) external;

    event SwapIn(
        address indexed fromAddress,
        bytes32 indexed toAddress,
        address fromAssetAddress,
        address toAssetAddress,
        uint256 amountIn,
        uint256 amountOut,
        TransferKey transferKey,
        Transaction transaction
    );

    /// @dev This function allows for swapping assets into the contract using a bridge-in transaction.
    /// @param swapInArgs Arguments that are required for swapOut.
    /// @return amountOut The amount received after swapping.
    function swapIn(SwapInArgs calldata swapInArgs) external payable returns (uint256 amountOut);

    event SwapOut(
        address indexed fromAddress,
        address indexed toAddress,
        address fromAssetAddress,
        address toAssetAddress,
        uint256 amountIn,
        uint256 amountOut,
        TransferKey transferKey,
        Transaction transaction
    );

    /// @dev Withdraws the assets from the specified bridge and swaps them out to the specified address.
    /// @param swapOutArgs Arguments that are required for swapOut.
    /// @return amountOut The amount received after swapping.
    function swapOut(SwapOutArgs calldata swapOutArgs) external returns (uint256 amountOut);

    event Withdraw(address indexed sender, address indexed assetAddress, uint256 amount);

    /// @dev Withdraw assets that were collected to cover crosschain swap cost.
    /// @param assetAddress Address of the asset that will be withdrawn.
    function withdraw(address assetAddress) external;

    /// @dev Retrieve the deposit amount for a specific asset in the aggregator contract.
    /// @param assetAddress Address of the asset that will be deposited.
    function getDeposit(address assetAddress) external view returns (uint256);

    /// @dev Retrieve the deposit amount for a specific asset deposited by a specific user.
    /// @param assetAddress Address of the asset that was deposited
    /// @param senderAddress Address of the user who has deposited the asset
    function getDepositByUser(address assetAddress, address senderAddress) external view returns (uint256);

    /// @dev Check if a specific transfer key has been used for a crosschain swap.
    /// @param networkId Magpie network id associated with the chain.
    /// @param senderAddress The address  of the origin contract.
    /// @param swapSequence The magpie sequence for the current swap. Each swap gets a new a new sequence
    function isTransferKeyUsed(
        uint16 networkId,
        bytes32 senderAddress,
        uint64 swapSequence
    ) external view returns (bool);

    event UpdateMagpieRouterAddress(address indexed sender, address magpieRouterAddress);

    /// @dev Allows the contract owner to update the Magpie Router address.
    /// @param magpieRouterAddress The address of the Magpie Router.
    function updateMagpieRouterAddress(address magpieRouterAddress) external;
}
```


# Multicall

The `Multicall` is a facet of a Diamond smart contract that provides a functionality for batching multiple function calls into a single transaction. This enhances efficiency and user experience for complex swaps.

The primary use case of this contract is to improve efficiency and user experience. By allowing multiple calls in one transaction, it reduces the transaction count, saving on gas fees and simplifying interactions for the user.

This is particularly useful in complex dApps where a user might need to perform several actions in a sequence. Instead of executing each action in a separate transaction, they can be batched together using `multicall`.


# MulticallFacet

The purpose of this contract is to serve as a facet in a Diamond contract that allows for batch execution of multiple delegatecalls using the `multicall` function.

### multicall():

The `multicall` function enforces that the caller is the contract owner and then delegates the execution to the `LibMulticall.multicall` function, which handles the execution of multiple delegatecalls to different facets.

**Input**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">selectors
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes4[] 
</code></pre></td><td>an array of function selectors</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">data
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes[]
</code></pre></td><td>an array of data that needs to be fed into the selectors</td></tr></tbody></table>


# IMulticall

```solidity
// SPDX-License-Identifier: Unlicense
pragma solidity 0.8.17;

interface IMulticall {
    function multicall(bytes4[] calldata selectors, bytes[] calldata data) external;
}

```


# LibMulticall

The purpose of this library is to enable the execution of multiple delegatecalls to different facets of a Diamond contract in a single transaction.

### multicall():

The function begins by accessing the `LibDiamond.DiamondStorage` storage struct from the Diamond contract using the `LibDiamond.diamondStorage()` function. This allows the function to access the storage variables of the Diamond contract.

The function checks if the length of `selectors` is equal to the length of `data`. If the lengths are not equal, it reverts the transaction by calling `revert` with the error `SelectorsLengthInvalid()`. This ensures that each selector has a corresponding data item.

The function then iterates over each element in the `data` array using a `for` loop. It retrieves the facet address associated with the selector from the `selectorToFacetAndPosition` mapping stored in the Diamond contract's storage.

The `delegatecall` function is invoked on the `facet` address, passing the corresponding `data[i]` as the delegatecall data. Delegatecall allows the called contract (facet) to execute the function within the context of the calling contract (the current contract). The `delegatecall` returns a tuple `(bool success, bytes memory returnData)`.

If the `delegatecall` was not successful (i.e., `success` is `false`), the function reverts the transaction by calling `revert` with the error `InvalidMulticall()`.

**Input**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">selectors
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes4[]
</code></pre></td><td>an array of function selectors</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">data
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes[]
</code></pre></td><td>an array of data that needs to be fed into the selectors</td></tr></tbody></table>


# Pauser

The primary use case of this contract is to provide an emergency stop mechanism. In case of detected vulnerabilities, bugs, or during contract upgrades, the contract owner can pause the contract to prevent potential losses or other issues.

Once the issues are resolved or the upgrade is complete, the contract can be unpaused to resume normal operations.


# PauserFacet

The `PauserFacet` contract provides an implementation of the `IPauser` interface, allowing the contract owner to pause and unpause the contract by invoking the corresponding functions.

### pause():

The `pause` function is used to pause the contract's functionality. It enforces that only the contract owner can call this function, and upon successful verification, it updates the `paused` state variable and emits a corresponding event.

### unpause():

The `unpause` function allows the contract owner to resume the functionality of the paused contract. It enforces that only the contract owner can call this function, and upon successful verification, it updates the `paused` state variable and emits a corresponding event.


# IPauser

```solidity
// SPDX-License-Identifier: Unlicense
pragma solidity 0.8.17;

interface IPauser {
    event Paused(address sender);

    function pause() external;

    event Unpaused(address sender);

    function unpause() external;
}
```


# LibPauser

The purpose of this library is to provide pause and unpause functionality for a contract.

### pause():

It retrieves the storage state of the contract using `LibMagpieAggregator.getStorage()`.&#x20;

It sets the `paused` variable of the storage state to `true`. This variable is used to indicate whether the contract is currently paused or not.

It emits a `Paused` event, passing `msg.sender` as the parameter. The `Paused` event is emitted to notify listeners that the contract has been paused, and `msg.sender` represents the address of the sender who triggered the `pause` function.

### unpause():

It retrieves the storage state of the contract using `LibMagpieAggregator.getStorage()`.&#x20;

It sets the `paused` variable of the storage state to `false`. This variable is used to indicate whether the contract is currently paused or not.

It emits a `Paused` event, passing `msg.sender` as the parameter. The `Paused` event is emitted to notify listeners that the contract has been unpaused, and `msg.sender` represents the address of the sender who triggered the `unpause` function.

### enforceIsNotPaused():

The purpose of this function is to enforce that certain operations can only be performed when the contract is not paused. If the contract is indeed paused, the function reverts the transaction and provides an error message indicating that the contract is paused. This helps ensure that critical functions or actions are not performed during a paused state, maintaining the desired behavior and security of the contract.


# Libraries

Here are the articles in this section:

[LibAsset](https://2191989945-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCW8mjZq1CYAC6Fmqzv07%2Fuploads%2F1zhncmwo99EJ1mNmHfeu%2Flibasset?alt=media)[LibBytes](https://2191989945-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCW8mjZq1CYAC6Fmqzv07%2Fuploads%2Fxms1OA38PVuLviqQBs0l%2Flibbytes?alt=media)[LibGuard](https://2191989945-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCW8mjZq1CYAC6Fmqzv07%2Fuploads%2FIQpjR9Mw542SQ6anq6oq%2Flibguard?alt=media)[LibMagpieAggregator](https://2191989945-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCW8mjZq1CYAC6Fmqzv07%2Fuploads%2Fn5MNPTOpcUD8OliLILgm%2Flibmagpieaggregator?alt=media)[LibTransferKey](https://2191989945-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCW8mjZq1CYAC6Fmqzv07%2Fuploads%2FSByAgWYP0jbEqpmXvVpa%2Flibtransferkey?alt=media)[LibUint256Array](https://2191989945-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCW8mjZq1CYAC6Fmqzv07%2Fuploads%2FVRcm9H0S7qvJ26ynvNGq%2Flibuint256array?alt=media)


# LibAsset

The `LibAsset` library provides a convenient interface for interacting with different types of assets in Solidity, whether they are native assets or ERC20 tokens.

### isNative():

This function checks if the given address (`self`) represents a native asset (Ether). It returns `true` if the address is the native asset ID (0x0).

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The asset that will be checked for a native token.</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self == NATIVE_ASSETID
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bool
</code></pre></td><td>Flag to identify if the asset is native or not.</td></tr></tbody></table>

### getBalance():

This function retrieves the balance of the current contract for a given asset (`self`). If the asset is a native asset, it returns the Ether balance of the contract. Otherwise, it uses the ERC20 `balanceOf` function to fetch the token balance.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Asset whose balance needs to be found</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self.isNative() ? address(this).balance : IERC20(self).balanceOf(address(this))
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>Balance of the asset</td></tr></tbody></table>

### getBalanceOf():

Retrieves the balance of the target address for a given asset (self).

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Asset whose balance needs to be found.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">targetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The address where the balance is checked from.</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><p></p></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>Balance of the specific asset.</td></tr></tbody></table>

### transferFrom():

This function performs a `safeTransferFrom` operation for a given asset (`self`) from one address (`from`) to another address (`to`). It uses the `SafeERC20` library to ensure safe token transfers.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Asset that will be transferred</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">from
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>address that will send the  asset</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">to
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>address that will receive the transferred asset</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>amount of an asset that will be transferred</td></tr></tbody></table>

### transfer():

This function performs a transfer of a given amount of an asset (`self`) to a recipient address (`recipient`). If the asset is a native asset, it uses `Address.sendValue` to send Ether. Otherwise, it uses the ERC20 `safeTransfer` function.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Asset that will be transferred</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">recipient
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>address that will receive the transferred asset</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>amount of an asset that will be transferred</td></tr></tbody></table>

### approve():

This function approves a spender address (`spender`) to spend a specified amount of an asset (`self`). It uses the `SafeERC20` library's `forceApprove` function.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The asset that will be approved.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">spender
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of a contract that will use the owners asset.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>Asset amount that can be spent.</td></tr></tbody></table>

### deposit():

This function allows for the deposit of a specified amount of an asset (`self`). If the asset is a native asset, it checks if the received Ether amount is sufficient and then converts it to the wrapped Ether token (`weth`) using the `IWETH` interface's `deposit` function. Otherwise, it performs a `safeTransferFrom` operation to transfer the asset from the sender address to the current contract.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the asset that will be deposited</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">weth
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the Wrapped Ether (WETH) contract.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>Depositing amount</td></tr></tbody></table>

### getAllowance():

This function retrieves the allowance amount that a spender address (`spender`) is approved to spend from an owner address (`owner`) for a given asset (`self`). It uses the ERC20 `allowance` function.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The asset whose allowance will be granted to the spender.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">owner
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the owner who owns the asset.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">spender
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of a contract that will use the owners allowance.</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">IERC20(self).allowance(owner, spender)
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The allowed amount</td></tr></tbody></table>

### Withdraw():

This function allows for the withdrawal of a specified amount of an asset (`self`) to a designated address (`to`). If the asset is a native asset, it uses the `IWETH` interface's `withdraw` function to convert the wrapped Ether token back to Ether. Then, it performs a transfer of the native asset to the specified address. If the asset is an ERC20 token, it performs a transfer of the token to the specified address.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The asset that will be withdrawn</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">weth
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the Wrapped Ether (WETH) contract.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">to
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address that will receive withdrawn token.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>Amount that needs to be withdrawn</td></tr></tbody></table>

### getDecimals():

This function retrieves the decimal precision of an ERC20 token. If the asset is a native asset, it defaults to 18 decimal places. Otherwise, it uses the `decimals` function of the ERC20 token to fetch the decimal precision.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The asset address whose decimals we are finding.</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">tokenDecimals
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint8
</code></pre></td><td>The decimals of the asset address</td></tr></tbody></table>

### isSuccessful():

Determines if a call was successful.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">target
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the target contract.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">success
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bool
</code></pre></td><td>To check if the call to the contract was successful or not.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">data
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The data was sent while calling the target contract.</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">result
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bool
</code></pre></td><td>The success of the call.</td></tr></tbody></table>

### execute():

Executes a low level call.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The address of the contract to which the call is being made.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">params
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The parameters or data to be sent in the call.</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">result
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bool
</code></pre></td><td>The success of the call.</td></tr></tbody></table>


# LibBytes

These utility functions provide convenient operations for manipulating byte arrays in Solidity.

### toAddress():

This function is used to convert a portion of a byte array into an `address`. It takes in the byte array (`self`) and a starting index (`start`). It verifies that the byte array has enough bytes to read an address (20 bytes) starting from the specified index. Then, it uses assembly code to load the address from the specified location in memory and returns it.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The bytes that contains the address.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">start
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The starting position to retrieve the address from the bytes.</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">tempAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The retrieved address from the bytes.</td></tr></tbody></table>

### slice():

This function is used to extract a slice of bytes from a byte array. It takes in the byte array (`self`), a starting index (`start`), and a length (`length`). It checks that the specified slice is within the bounds of the byte array. Then, it creates a new byte array (`tempBytes`) with a length equal to the specified slice length. It uses assembly code to copy the slice from the original byte array to the new byte array. Finally, it updates the length of the new byte array and returns it.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The string of bytes that needs to be sliced</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">start
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The starting position to begin slicing</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">length
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The length of the byte</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">tempBytes
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The sliced byte</td></tr></tbody></table>

### concat():

This function is used to concatenate two byte arrays. It takes in two byte arrays (`self` and `postBytes`). It creates a new byte array (`tempBytes`) with a length equal to the combined lengths of the two input byte arrays. It uses assembly code to copy the contents of the two byte arrays into the new byte array. Finally, it updates the length of the new byte array and returns it.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The bytes that needs to be concatenated.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">postBytes
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The bytes that needs to be concatenated.</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">tempBytes
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The concatenated bytes</td></tr></tbody></table>


# LibGuard

These functions are intended to prevent reentrancy attacks by ensuring that reentrant calls are not executed when the `guarded` flag is set. The `guarded` flag is controlled by these functions to enable or disable the reentrancy guard as needed.

### enforcePreGuard():

This function is used to enforce a pre-reentrancy guard. It retrieves the `AppStorage` instance using `LibMagpieAggregator.getStorage()` and checks if the `guarded` flag is set. If the flag is already set, indicating an ongoing reentrant call, it reverts the transaction with a `ReentrantCall` error. Otherwise, it sets the `guarded` flag to `true`.

### enforcePostGuard():

This function is used to enforce a post-reentrancy guard. It retrieves the `AppStorage` instance using `LibMagpieAggregator.getStorage()` and sets the `guarded` flag to `false`.

### enforceDelegatedCallPreGuard():

Accesses the contract storage to determine if a specific type of delegated call is already in progress. If a call of that type is already in progress, it reverts the transaction to prevent reentrancy. If no such call is in progress, it sets the delegated call state to `true` for that call type.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">delegatedCallType
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DelegatedCallType
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">enum DelegatedCallType {
    BridgeIn,
    BridgeOut,
    DataTransferIn,
    DataTransferOut
}
</code></pre></td></tr></tbody></table>

### enforceDelegatedCall():

Accesses the contract storage to confirm whether a particular type of delegated call is currently in progress. If the expected call is not in progress, it reverts the transaction, indicating an invalid delegated call.

### enforceDelegatedCallPostGaurd():

Accesses the contract storage and sets the delegated call state back to `false` for the specified type of delegated call.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th></th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">delegatedCallType
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DelegatedCallType
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">enum DelegatedCallType {
    BridgeIn,
    BridgeOut,
    DataTransferIn,
    DataTransferOut
}
</code></pre></td></tr></tbody></table>

### enforceDelegatedCallGuard():

Accesses the contract storage to confirm whether a particular type of delegated call is currently in progress. If the expected call is not in progress, it reverts the transaction, indicating an invalid delegated call.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">delegatedCallType
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DelegatedCallType
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">enum DelegatedCallType {
    BridgeIn,
    BridgeOut,
    DataTransferIn,
    DataTransferOut
}
</code></pre></td></tr></tbody></table>


# LibMagpieAggregator

It defines a storage structure and utility functions for managing various settings and data in the Magpie Aggregator application.

```solidity
struct CurveSettings {
    address mainRegistry;
    address cryptoRegistry;
    address cryptoFactory;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>mainRegistry
</code></pre></td><td><pre><code>address
</code></pre></td><td>Address of the main registry of the curve protocol.</td></tr><tr><td><pre><code>cryptoRegistry
</code></pre></td><td><pre><code>address
</code></pre></td><td>Address of the crypto registry of the curve protocol</td></tr><tr><td><pre><code>cryptoFactory
</code></pre></td><td><pre><code>address
</code></pre></td><td>Address of the crypto factory of the crypto factory</td></tr></tbody></table>

```solidity
struct Amm {
    uint8 protocolId;
    bytes4 selector;
    address addr;
}
```

<table><thead><tr><th>Field </th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>protocolId
</code></pre></td><td><pre><code>uint8
</code></pre></td><td>The protocol identifier provided by magpie team.</td></tr><tr><td><pre><code>selector
</code></pre></td><td><pre><code>bytes4
</code></pre></td><td>The function selector of the AMM.</td></tr><tr><td><pre><code>addr
</code></pre></td><td><pre><code>address
</code></pre></td><td>The address of the facet of the AMM.</td></tr></tbody></table>

```solidity
struct WormholeBridgeSettings {
    address bridgeAddress;
}
```

<table><thead><tr><th>Field </th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>bridgeAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>The wormhole token bridge address</td></tr></tbody></table>

```solidity
struct StargateSettings {
    address routerAddress;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>routerAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>The stargate router address.</td></tr></tbody></table>

```solidity
struct WormholeSettings {
    address bridgeAddress;
    uint8 consistencyLevel;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>bridgeAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>The wormhole core bridge address.</td></tr><tr><td><pre><code>consistencyLevel
</code></pre></td><td><pre><code>uint8
</code></pre></td><td>The level of finality the guardians will reach before signing the message</td></tr></tbody></table>

```solidity
struct LayerZeroSettings {
    address routerAddress;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>routerAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>The router address of layer zero protocol</td></tr></tbody></table>

```solidity
struct CelerBridgeSettings {
    address messageBusAddress; 
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>messageBusAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>The message bus address of celer bridge</td></tr></tbody></table>

```solidity
struct AppStorage {
    address weth;
    uint16 networkId;
    mapping(uint16 => bytes32) magpieAggregatorAddresses;
    mapping(address => uint256) deposits;
    mapping(address => mapping(address => uint256)) depositsByUser;
    mapping(uint16 => mapping(bytes32 => mapping(uint64 => bool))) usedTransferKeys;
    uint64 swapSequence;
    // Pausable
    bool paused;
    // Reentrancy Guard
    bool guarded;
    // Amm
    mapping(uint16 => Amm) amms;
    // Curve Amm
    CurveSettings curveSettings;
    // Data Transfer
    mapping(uint16 => mapping(uint16 => mapping(bytes32 => mapping(uint64 => bytes)))) payloads;
    // Stargate Bridge
    StargateSettings stargateSettings;
    mapping(uint16 => bytes32) magpieStargateBridgeAddresses;
    // Wormhole Bridge
    WormholeBridgeSettings wormholeBridgeSettings;
    mapping(uint64 => uint64) wormholeTokenSequences;
    // Wormhole Data Transfer
    WormholeSettings wormholeSettings;
    mapping(uint16 => uint16) wormholeNetworkIds;
    mapping(uint64 => uint64) wormholeCoreSequences;
    // LayerZero Data Transfer
    LayerZeroSettings layerZeroSettings;
    mapping(uint16 => uint16) layerZeroChainIds;
    mapping(uint16 => uint16) layerZeroNetworkIds;
    address magpieRouterAddress;
    mapping(uint16 => mapping(bytes32 => mapping(uint64 => mapping(address => uint256)))) stargateDeposits;
    mapping(uint8 => bool) delegatedCalls;
    // Celer Bridge
    CelerBridgeSettings celerBridgeSettings;
    mapping(uint16 => uint64) celerChainIds;
    mapping(uint16 => mapping(bytes32 => mapping(uint64 => mapping(address => uint256)))) celerDeposits;
    mapping(uint16 => mapping(bytes32 => mapping(uint64 => address))) celerRefundAddresses;
    mapping(uint16 => bytes32) magpieCelerBridgeAddresses;
    mapping(uint16 => mapping(uint16 => mapping(bytes32 => mapping(uint64 => bytes32)))) payloadHashes;
    mapping(uint16 => bytes32) magpieStargateBridgeV2Addresses;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>weth
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the Wrapped Ether (WETH) contract.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">networkId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>The network ID associated with the application.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieAggregatorAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity"> mapping(uint16 => bytes32)
</code></pre></td><td>A mapping of network IDs to Magpie aggregator addresses.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">deposits
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(address => uint256)
</code></pre></td><td>Tracks the total deposits made by each user.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">depositsByUser
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(address => mapping(address => uint256))
</code></pre></td><td>Tracks the deposits made by each user for specific token addresses.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">usedTransferKeys
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => mapping(bytes32 => mapping(uint64 => bool)))
</code></pre></td><td>Tracks the usage status of transfer keys for specific network IDs, sender addresses, and swap sequences.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">swapSequence
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64
</code></pre></td><td>A counter used for generating swap sequences.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">paused
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bool
</code></pre></td><td>A flag indicating whether the contract is paused or not.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">guarded
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bool
</code></pre></td><td>A flag indicating whether reentrancy guard is enabled or not.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amms
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => Amm)
</code></pre></td><td>A mapping of network IDs to AMMs.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">curveSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">CurveSettings
</code></pre></td><td>Contains settings related to Curve AMMs.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">payloads
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => mapping(uint16 => mapping(bytes32 => mapping(uint64 => bytes))))
</code></pre></td><td>A mapping used for storing data transfer payloads.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">stargateSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">StargateSettings
</code></pre></td><td>Contains settings related to the Stargate bridge.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieStargateBridgeAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => bytes32)
</code></pre></td><td>A mapping of network IDs to Magpie Stargate bridge addresses.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">wormholeBridgeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">WormholeBridgeSettings
</code></pre></td><td>Contains settings related to the Wormhole Token bridge.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">wormholeTokenSequences
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint64 => uint64)
</code></pre></td><td>Tracks the token sequences for the Wormhole bridge.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">wormholeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">WormholeSettings
</code></pre></td><td>Contains settings related to Wormhole data transfers.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">wormholeNetworkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => uint16)
</code></pre></td><td>A mapping of network IDs for the Wormhole bridge.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">wormholeCoreSequences
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint64 => uint64)
</code></pre></td><td>Tracks the core sequences for the Wormhole bridge.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">layerZeroSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">LayerZeroSettings
</code></pre></td><td>Contains settings related to LayerZero data transfers.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">layerZeroChainIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => uint16)
</code></pre></td><td>A mapping of chain IDs for LayerZero data transfers.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">layerZeroNetworkIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity"> mapping(uint16 => uint16)
</code></pre></td><td>A mapping of network IDs for LayerZero data transfers.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieRouterAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the Magpie Router</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">stargateDeposits
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => mapping(bytes32 => mapping(uint64 => mapping(address => uint256))))
</code></pre></td><td>A mapping to show how much amount has been deposited why which address along with the message passed by the address and the networkId</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">delegatedCalls
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity"> mapping(uint8 => bool)
</code></pre></td><td>used to associate a boolean value (<code>bool</code>) with a single byte integer (<code>uint8</code>).</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">celerBridgeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">CelerBridgeSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct CelerBridgeSettings {
    address messageBusAddress; // The message bus address of celer bridge
}
</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">celerChainIds
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => uint64)
</code></pre></td><td>A mapping of chain IDs for celer bridge transfers.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">celerDeposits
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => mapping(bytes32 => mapping(uint64 => mapping(address => uint256))))
</code></pre></td><td>A mapping of network Ids, data, chain Id, and address to the amount being deposited.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">celerRefundAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => mapping(bytes32 => mapping(uint64 => address)))
</code></pre></td><td>A mapping of network Ids, data, and chain id to the refund address.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieCelerBridgeAddresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => bytes32)
</code></pre></td><td>A mapping of network ID to the magpie celer bridge  address in the form of bytes.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">payloadHashes
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => mapping(uint16 => mapping(bytes32 => mapping(uint64 => bytes32))))
</code></pre></td><td></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieStargateBridgeV2Addresses
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => bytes32)
</code></pre></td><td>A mapping of network ID to the magpie stargate bridge  V2 address in the form of bytes.</td></tr></tbody></table>

### getStorage():

returns a reference to the `AppStorage` struct.

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">s
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">AppStorage
</code></pre></td><td><code>AppStorage</code> struct.</td></tr></tbody></table>


# LibMagpieRouter

This library declared struct and a library used by MagpieAggregator. This structure and library design help organize data and provide access to the app's storage, allowing other parts of the system to fetch essential data or settings as needed.

### CurveSettings:

```solidity
struct CurveSettings {
    address mainRegistry;
    address cryptoRegistry;
    address cryptoFactory;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">mainRegistry
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address for the main Curve registry.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">cryptoRegistry
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address for the crypto Curve registry.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">cryptoFactory
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address for the crypto Curve factory.</td></tr></tbody></table>

### Amm

```solidity
struct Amm {
    uint8 protocolId;
    bytes4 selector;
    address addr;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">protocolId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint8
</code></pre></td><td>An identifier for the AMM protocol.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">selector
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes4
</code></pre></td><td>A function selector.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">addr
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The address where this AMM resides.</td></tr></tbody></table>

### AppStorage

```solidity
struct AppStorage {
    address weth;
    address magpieAggregatorAddress;
    mapping(uint16 => Amm) amms;
    CurveSettings curveSettings;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">weth
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>The address of the Wrapped Ether contract.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">magpieAggregatorAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>Address of the Magpie Aggregator contract.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amms
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">mapping(uint16 => Amm)
</code></pre></td><td>A mapping of different AMMs, indexed by a <code>uint16</code> value.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">curveSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">CurveSettings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct CurveSettings {
    address mainRegistry;
    address cryptoRegistry;
    address cryptoFactory;
}
</code></pre></td></tr></tbody></table>


# LibMagpieRouterV2

This library declared struct and a library used by MagpieRouterV2. This structure and library design help organize data and provide access to the app's storage, allowing other parts of the system to fetch essential data or settings as needed.

### CurveSettings:

```solidity
struct AppStorage {
    mapping(uint16 => bytes4) selectors;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>selectors
</code></pre></td><td><pre><code>mapping(uint16 => bytes4)
</code></pre></td><td>Mapping of command to its corresponding function selector.</td></tr></tbody></table>


# LibTransferKey

The `LibTransferKey` library provides functionality for encoding, decoding, and validating `TransferKey` structs, which are used to represent transfer keys in the application.

```solidity
struct TransferKey {
    uint16 networkId;
    bytes32 senderAddress;
    uint64 swapSequence;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>networkId
</code></pre></td><td><pre><code>uint16
</code></pre></td><td>networkId of the current chain in Magpie protocol, it is different from the actual networkId<br>ethereum: 1<br>polygon: 2<br>bsc: 3<br>avalanche: 4<br>arbitrum: 5 <br>optimism: 6</td></tr><tr><td><pre><code>senderAddress
</code></pre></td><td><pre><code>bytes32
</code></pre></td><td>The address who initiated the transfer.</td></tr><tr><td><pre><code>swapSequence
</code></pre></td><td><pre><code>uint64
</code></pre></td><td>The magpie sequence for the current swap.</td></tr></tbody></table>

### encode():

In the `encode` function, a new bytes array (`payload`) of size 42 is created to store the encoded transfer key.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">TransferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct TransferKey {
    uint16 networkId;
    bytes32 senderAddress;
    uint64 swapSequence;
}
</code></pre></td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">payload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The transferKey concatenated and converted to bytes</td></tr></tbody></table>

### decode():

In the `decode` function, the assembly block is used to extract the values of each field from the `payload` array and store them in the `transferKey` struct.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">payload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>The data which contains the transferKey.</td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">TransferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct TransferKey {
    uint16 networkId;
    bytes32 senderAddress;
    uint64 swapSequence;
}
</code></pre></td></tr></tbody></table>

### validate():

The `validate` function checks if the `networkId`, `senderAddress`, and `swapSequence` fields of both `TransferKey` structs are equal. If any of the fields differ, indicating an invalid transfer key, the function reverts with an `InvalidTransferKey` error.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">TransferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct TransferKey {
    uint16 networkId;
    bytes32 senderAddress;
    uint64 swapSequence;
}
</code></pre></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">TransferKey
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct TransferKey {
    uint16 networkId;
    bytes32 senderAddress;
    uint64 swapSequence;
}
</code></pre></td></tr></tbody></table>


# LibUint256Array

### sum():

the `sum` function in the `LibUint256Array` library allows you to calculate the sum of all elements in a `uint256` array using efficient assembly operations.

**Input**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">self
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256[]
</code></pre></td><td>An array of amounts whose sum needs to be found out.</td></tr></tbody></table>

**Output**:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amountOut
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The final sum of all the amounts</td></tr></tbody></table>


# LibSwap

```solidity
struct SwapData {
    uint16 amountsOffset;
    uint16 dataOffset;
    uint16 commandsOffset;
    uint16 commandsOffsetEnd;
    uint16 outputsLength;
    uint256 amountIn;
    address toAddress;
    address fromAssetAddress;
    address toAssetAddress;
    uint256 deadline;
    uint256 amountOutMin;
}
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>amountsOffset
</code></pre></td><td><pre><code>uint16
</code></pre></td><td>This is a 16-bit unsigned integer representing the offset for the amounts section in the transaction calldata. Offsets are used to locate specific data within a block of calldata.</td></tr><tr><td><pre><code>dataOffset
</code></pre></td><td><pre><code>uint16
</code></pre></td><td>Similar to amountsOffset, this is a 16-bit unsigned integer representing the offset for another data section in the calldata. The specific nature of this data depends on the context in which SwapData is used.</td></tr><tr><td><pre><code>commandsOffset
</code></pre></td><td><pre><code>uint16
</code></pre></td><td>This is a 16-bit unsigned integer indicating the starting point of the commands section in the calldata. Commands in the context of a swap refers to specific actions.</td></tr><tr><td><pre><code>commandsOffsetEnd
</code></pre></td><td><pre><code>uint16
</code></pre></td><td>This is a 16-bit unsigned integer marking the end of the commands section in the calldata. Knowing the start and end of the commands section helps in parsing and executing them correctly.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">outputsLength
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>Represents the length of all of the commands.</td></tr><tr><td><pre><code>amountIn
</code></pre></td><td><pre><code>uint256
</code></pre></td><td>A 256-bit unsigned integer representing the amount of the asset being provided in the swap.</td></tr><tr><td><pre><code>toAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>This is the Ethereum address to which the output of the swap (the swapped asset) will be sent.</td></tr><tr><td><pre><code>fromAssetAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>The Ethereum address of the asset being swapped from. This could be the contract address of an ERC-20 token or another type of asset.</td></tr><tr><td><pre><code>toAssetAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>The Ethereum address of the asset being swapped to. Like fromAssetAddress, this is typically the contract address of the target ERC-20 token or other asset types.</td></tr><tr><td><pre><code>deadline
</code></pre></td><td><pre><code>uint256
</code></pre></td><td>A timestamp (usually in seconds since the Unix epoch) indicating the deadline by which the swap must be completed.</td></tr><tr><td><pre><code>amountOutMin
</code></pre></td><td><pre><code>uint256
</code></pre></td><td>The minimum amount of the output asset that must be received for the swap to be considered successful.</td></tr></tbody></table>

### getAmountIn():

getAmountIn is a function that iterates over a portion of the transaction calldata, extracting and summing up amounts of an asset.

**Input:**

| Field          | Type   | Description                          |
| -------------- | ------ | ------------------------------------ |
| startOffset    | uint16 | The location starting position       |
| endOffset      | uint16 | The location ending position         |
| positionOffset | uint16 | The location of the current position |

**Ouput:**

| Field    | Type    | Description                      |
| -------- | ------- | -------------------------------- |
| amountIn | uint256 | The Amount for the current swap. |

### getFirstAmountIn():

the getFirstAmountIn function is a utility function used to extract the first amount of an asset involved in a swap operation directly from the calldata of a transaction.

**Input:**

| Field          | Type   | Description                                     |
| -------------- | ------ | ----------------------------------------------- |
| swapArgsOffset | uint16 | The location where the swapping data is stored. |

**Output:**

| Field    | Type    | Description          |
| -------- | ------- | -------------------- |
| amountIn | uint256 | The first amount in. |

### getData():

getData is a function that parses and organizes data from a transaction's calldata for a token swap operation.

**Input:**

| Field          | Type   | Description                                     |
| -------------- | ------ | ----------------------------------------------- |
| swapArgsOffset | uint16 | The location where the swapping data is stored. |

**Output:**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>swapData</td><td>SwapData memory</td><td><pre class="language-solidity"><code class="lang-solidity">struct SwapData {
    uint16 amountsOffset;
    uint16 dataOffset;
    uint16 commandsOffset;
    uint16 commandsOffsetEnd;
    uint256 amountIn;
    address toAddress;
    address fromAssetAddress;
    address toAssetAddress;
    uint256 deadline;
    uint256 amountOutMin;
}
</code></pre></td></tr></tbody></table>


# MagpieCelerBridge

`MagpieCelerBridge`, which serves as an intermediary to handle deposits, withdrawals, and refunds of assets between Magpie Aggregator and Celer Network.

**It has two modifiers:**

### onlyMagpieAggregator:

Restricts functions to only be called by the Magpie Aggregator.

### onlyCeler:

Restricts functions to only be called by the Celer Network.

**It contains the following functions:**

### **updateSettings():**

Allows the owner to update the contract settings.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">_settings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">Settings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct Settings {
        address aggregatorAddress;
        address messageBusAddress;
    }
</code></pre></td></tr></tbody></table>

### **deposit():**

Handles the deposit process by receiving funds, approving tokens, sending them to the liquidity bridge, and notifying the message bus.

**Input**

<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">depositArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">DepositArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct DepositArgs {
        uint32 slippage;
        uint64 chainId;
        uint256 amount;
        address sender;
        address receiver;
        address assetAddress;
        TransferKey transferKey;
    }
</code></pre></td></tr></tbody></table>

### **withdraw():**

Handles withdrawal requests from deposited amounts.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">withdrawArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">WithdrawArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct WithdrawArgs {
        address assetAddress;
        TransferKey transferKey;
    }
</code></pre></td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The withdrawal amount</td></tr></tbody></table>

### **executeMessageWithTransfer():**

Receives transfers and updates the deposited amounts accordingly.

Input

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">assetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td></td></tr><tr><td></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint64
</code></pre></td><td></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">payload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td></td></tr><tr><td></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td></td></tr></tbody></table>

Output

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">IMessageBus.TxStatus
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">enum TxStatus {
        Null,
        Success,
        Fail,
        Fallback,
        Pending 
    }
</code></pre></td></tr></tbody></table>

### **executeMessageWithTransferRefund():**

Manages refunds to the designated recipient.

**Input**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">assetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td></td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">payload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td></td></tr><tr><td></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td></td></tr></tbody></table>

**Output**

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">IMessageBus.TxStatus
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">enum TxStatus {
        Null,
        Success,
        Fail,
        Fallback,
        Pending 
    }
</code></pre></td></tr></tbody></table>


# MagpieStargateBridge

The contract serves as a bridge between Magpie and the Stargate network, allowing deposits and withdrawals of assets between the two networks. It has a modifier `onlyMagpieAggregator` that restricts access to functions only to the Magpie aggregator address specified in the `settings` struct. It has a modifier `onlyStargate` that restricts access to functions only to the Stargate router address specified in the `settings` struct.

```solidity
struct Settings {
        address aggregatorAddress;
        address routerAddress;
    }
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>aggregatorAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>Magpie Aggregator Address</td></tr><tr><td><pre><code>routerAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>Stargate Router Address</td></tr></tbody></table>

```solidity
struct WithdrawArgs {
        uint16 srcChainId;
        uint256 nonce;
        address assetAddress;
        bytes srcAddress;
        TransferKey transferKey;
    }
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>srcChainId
</code></pre></td><td><pre><code>uint16
</code></pre></td><td>A <code>uint16</code> value representing the source chain ID from which the withdrawal is initiated.</td></tr><tr><td><pre><code>nonce
</code></pre></td><td><pre><code>uint256
</code></pre></td><td>A <code>uint256</code> value representing a unique identifier for the withdrawal transaction.</td></tr><tr><td><pre><code>assetAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>An <code>address</code> representing the asset address that is being withdrawn.</td></tr><tr><td><pre><code>srcAddress
</code></pre></td><td><pre><code>bytes
</code></pre></td><td>A <code>bytes</code> array representing the source address on the source chain.</td></tr><tr><td><pre><code>transferKey
</code></pre></td><td><pre><code>TransferKey
</code></pre></td><td>An instance of the <code>TransferKey</code> struct from the <code>LibTransferKey</code> library, which contains the network ID, sender address, and swap sequence associated with the withdrawal.</td></tr></tbody></table>

### updateSettings():

to update the bridge settings. Only the contract owner can call this function.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">_settings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">Settings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct Settings {
        address aggregatorAddress;
        address routerAddress;
    }
</code></pre></td></tr></tbody></table>

### withdraw():

to withdraw deposited funds. It checks the deposited amount based on the transfer key and asset address, clears the cached swap if the amount is zero, and transfers the amount to the aggregator address. Only the Magpie aggregator can call this function.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">withdrawArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">WithdrawArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct WithdrawArgs {
        uint16 srcChainId;
        uint256 nonce;
        address assetAddress;
        bytes srcAddress;
        TransferKey transferKey;
    }
</code></pre></td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amountOut
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount that is withdrawn.</td></tr></tbody></table>

### sgReceive():

`sgReceive`  is called by the Stargate router when assets are received from another chain. It increments the deposited amount based on the transfer key, asset address, and amount.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey.networkId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>Network Id extracted from the TransferKey struct</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey.senderAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Sender Address extracted from the TransferKey struct</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey.swapSequence
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>Swap Sequence extracted from the TransferKey struct</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">assetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>An <code>address</code> parameter representing the address of the received asset.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>A <code>uint256</code> parameter representing the amount of the received asset.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">payload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>A <code>bytes calldata</code> parameter containing encoded information about the transfer, including the <code>TransferKey</code>.</td></tr></tbody></table>


# MagpieStargateBridgeV2

Similar to MagpieStargateBridge but the router address of the bridge has changed.

```solidity
struct Settings {
        address aggregatorAddress;
        address routerAddress;
    }
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>aggregatorAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>Magpie Aggregator Address</td></tr><tr><td><pre><code>routerAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>Stargate Router Address</td></tr></tbody></table>

```solidity
struct WithdrawArgs {
        uint16 srcChainId;
        uint256 nonce;
        address assetAddress;
        bytes srcAddress;
        TransferKey transferKey;
    }
```

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>srcChainId
</code></pre></td><td><pre><code>uint16
</code></pre></td><td>A <code>uint16</code> value representing the source chain ID from which the withdrawal is initiated.</td></tr><tr><td><pre><code>nonce
</code></pre></td><td><pre><code>uint256
</code></pre></td><td>A <code>uint256</code> value representing a unique identifier for the withdrawal transaction.</td></tr><tr><td><pre><code>assetAddress
</code></pre></td><td><pre><code>address
</code></pre></td><td>An <code>address</code> representing the asset address that is being withdrawn.</td></tr><tr><td><pre><code>srcAddress
</code></pre></td><td><pre><code>bytes
</code></pre></td><td>A <code>bytes</code> array representing the source address on the source chain.</td></tr><tr><td><pre><code>transferKey
</code></pre></td><td><pre><code>TransferKey
</code></pre></td><td>An instance of the <code>TransferKey</code> struct from the <code>LibTransferKey</code> library, which contains the network ID, sender address, and swap sequence associated with the withdrawal.</td></tr></tbody></table>

### updateSettings():

to update the bridge settings. Only the contract owner can call this function.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">_settings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">Settings
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct Settings {
        address aggregatorAddress;
        address routerAddress;
    }
</code></pre></td></tr></tbody></table>

### withdraw():

to withdraw deposited funds. It checks the deposited amount based on the transfer key and asset address, clears the cached swap if the amount is zero, and transfers the amount to the aggregator address. Only the Magpie aggregator can call this function.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">withdrawArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">WithdrawArgs
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">struct WithdrawArgs {
        uint16 srcChainId;
        uint256 nonce;
        address assetAddress;
        bytes srcAddress;
        TransferKey transferKey;
    }
</code></pre></td></tr></tbody></table>

Output:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amountOut
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>The amount that is withdrawn.</td></tr></tbody></table>

### sgReceive():

`sgReceive`  is called by the Stargate router when assets are received from another chain. It increments the deposited amount based on the transfer key, asset address, and amount.

Input:

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey.networkId
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint16
</code></pre></td><td>Network Id extracted from the TransferKey struct</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey.senderAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>Sender Address extracted from the TransferKey struct</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">transferKey.swapSequence
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>Swap Sequence extracted from the TransferKey struct</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">assetAddress
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">address
</code></pre></td><td>An <code>address</code> parameter representing the address of the received asset.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">amount
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">uint256
</code></pre></td><td>A <code>uint256</code> parameter representing the amount of the received asset.</td></tr><tr><td><p></p><pre class="language-solidity"><code class="lang-solidity">payload
</code></pre></td><td><p></p><pre class="language-solidity"><code class="lang-solidity">bytes
</code></pre></td><td>A <code>bytes calldata</code> parameter containing encoded information about the transfer, including the <code>TransferKey</code>.</td></tr></tbody></table>


# Deployments \[Deprecated]

The contracts are deployed on Ethereum, Polygon, BSC, Avalanche, Optimism, Polygon zkEVM and Base.

### MagpieAggregator Diamond Proxy

| Network       | Louper Address                                                                                                                                                                                 | Explorer                                                                                                                |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Ethereum      | [ ](https://louper.dev/diamond/0xba7bAC71a8Ee550d89B827FE6d67bc3dCA07b104?network=mainnet)[Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=mainnet) | [Explorer Link](https://etherscan.io/address/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104)                                |
| Polygon       | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=polygon)                                                                                           | [Explorer Link](https://polygonscan.com/address/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104)                             |
| BSC           | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=bsc)                                                                                               | [Explorer Link](https://bscscan.com/address/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104)                                 |
| Avalanche     | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=avalanche)                                                                                         | [Explorer Link](https://snowtrace.io/address/0xba7bAC71a8Ee550d89B827FE6d67bc3dCA07b104/contract/43114/code)            |
| Arbitrum-One  | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=arbitrum)                                                                                          | [Explorer Link](https://arbiscan.io/address/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104#code)                            |
| Optimism      | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=optimism)                                                                                          | [Explorer Link](https://optimistic.etherscan.io/address/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104#code)                |
| Base          | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=base)                                                                                              | [Explorer Link](https://basescan.org/address/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104#code)                           |
| Polygon zkEVM | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=polygonZkEvm)                                                                                      | [Explorer Link](https://zkevm.polygonscan.com/address/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104#code)                  |
| Blast         | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=blast)                                                                                             | [Explorer Link](https://blastscan.io/address/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104)                                |
| zkSync        | [Louper Link](https://louper.dev/diamond/0x22bfb19ed098ec206fe2e5d0f719672a7dc7103e?network=zkSync)                                                                                            | [Explorer Link](https://explorer.zksync.io/address/0x22bfb19ed098ec206fe2e5d0f719672a7dc7103e#transactions)             |
| Manta         | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=manta)                                                                                             | [Explorer Link](https://pacific-explorer.manta.network/address/0xba7bAC71a8Ee550d89B827FE6d67bc3dCA07b104?tab=contract) |
| Scroll        | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=scroll)                                                                                            | [Explorer Link](https://scrollscan.com/address/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104)                              |
| Metis         | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=metis)                                                                                             | [Explorer Link](https://explorer.metis.io/address/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104)                           |
| Fantom        | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=fantom)                                                                                            | [Explorer Link](https://ftmscan.com/address/0xba7bAC71a8Ee550d89B827FE6d67bc3dCA07b104)                                 |
| Taiko         | [Louper Link](https://louper.dev/diamond/0xba7bac71a8ee550d89b827fe6d67bc3dca07b104?network=taiko)                                                                                             | [Explorer Link](https://taikoscan.io/address/0xba7bAC71a8Ee550d89B827FE6d67bc3dCA07b104)                                |

### MagpieRouterV2&#x20;

<table><thead><tr><th width="250">Network</th><th>Explorer</th></tr></thead><tbody><tr><td>Ethereum</td><td><a href="https://etherscan.io/address/0xbd96bca0d3a4fcc18dc44d333a7851c513772289">Explorer Link</a></td></tr><tr><td>Polygon</td><td><a href="https://polygonscan.com/address/0xbd96bca0d3a4fcc18dc44d333a7851c513772289">Explorer Link</a></td></tr><tr><td>BSC</td><td><a href="http://bscscan.com/address/0xbd96bca0d3a4fcc18dc44d333a7851c513772289">Explorer Link</a></td></tr><tr><td>Avalanche</td><td><a href="https://snowtrace.io/address/0x1f030e4f3302670794f355afc0d30f4ae30641a0">Explorer Link</a></td></tr><tr><td>Arbitrum-One</td><td><a href="https://arbiscan.io/address/0xbd96bca0d3a4fcc18dc44d333a7851c513772289">Explorer Link</a></td></tr><tr><td>Optimism</td><td><a href="https://optimistic.etherscan.io/address/0xbd96bca0d3a4fcc18dc44d333a7851c513772289">Explorer Link</a></td></tr><tr><td>Base</td><td><a href="https://basescan.org/address/0x9ee06954418687c6fb3a9966f7c46e0a245f0183">Explorer Link</a></td></tr><tr><td>Polygon zkEVM</td><td><a href="https://zkevm.polygonscan.com/address/0x5cced4f430526228980f307de46f378e6ffb84de">Explorer Link</a></td></tr><tr><td>Blast</td><td><a href="https://blastscan.io/address/0x596384bdffc9f563b53791aeec50a42ff51c3e42">Explorer Link</a></td></tr><tr><td>zkSync</td><td><a href="https://era.zksync.network/address/0xface2ddf4fd8ba5e180c1fd9767f96e14f085509">Explorer Link</a></td></tr><tr><td>Manta</td><td><a href="https://manta.socialscan.io/address/0x596384bdffc9f563b53791aeec50a42ff51c3e42">Explorer Link</a></td></tr><tr><td>Scroll</td><td><a href="https://scrollscan.com/address/0x956df8424b556f0076e8abf5481605f5a791cc7f">Explorer Link</a></td></tr><tr><td>Metis</td><td><a href="https://explorer.metis.io/address/0x956df8424b556f0076e8abf5481605f5a791cc7f">Explorer Link</a></td></tr><tr><td>Fantom</td><td><a href="https://ftmscan.com/address/0x956df8424b556f0076e8abf5481605f5a791cc7f">Explorer Link</a></td></tr><tr><td>Taiko</td><td><a href="https://taikoscan.io/address/0x956df8424b556f0076e8abf5481605f5a791cc7f">Explorer Link</a></td></tr></tbody></table>

### **MagpieStargateBridgeV2**

| Network       | Explorer                                                                                                |
| ------------- | ------------------------------------------------------------------------------------------------------- |
| Ethereum      | [Explorer Link](https://etherscan.io/address/0xa15172b2588901483d8E49bAf7A73f184775CC31)                |
| Polygon       | [Explorer Link](https://polygonscan.com/address/0xc325856e5585823aaC0D1Fd46c35c608D95E65A9)             |
| BSC           | [Explorer Link](https://bscscan.com/address/0xc325856e5585823aaC0D1Fd46c35c608D95E65A9)                 |
| Avalanche     | [Explorer Link](https://snowtrace.io/address/0xbDB12D3aD22a7ac40ded89041dE4D32F28b16856)                |
| Arbitrum-One  | [Explorer Link](https://arbiscan.io/address/0xc325856e5585823aaC0D1Fd46c35c608D95E65A9)                 |
| Optimism      | [Explorer Link](https://optimistic.etherscan.io/address/0xc325856e5585823aaC0D1Fd46c35c608D95E65A9)     |
| Base          | [Explorer Link](https://basescan.org/address/0x8699DE5F3102AD1c97b7EfD9C541446A20C06Ada)                |
| Polygon zkEVM | [Explorer Link](https://zkevm.polygonscan.com/address/0x596384BDffC9F563b53791AEEc50a42Ff51C3e42)       |
| Blast         | -                                                                                                       |
| zkSync        | [Explorer Link](https://explorer.zksync.io/address/0xbd948872b8c800e9c46df6d4334262211ea54c96#contract) |
| Manta         | -                                                                                                       |
| Scroll        | [Explorer Link](https://scrollscan.com/address/0x1a44076050125825900e736c501f859c50fe728c)              |
| Metis         | -                                                                                                       |
| Fantom        | -                                                                                                       |
| Taiko         | -                                                                                                       |

### **MagieCelerBridge**

| Network Name  | Explorer                                                                                            |
| ------------- | --------------------------------------------------------------------------------------------------- |
| Ethereum      | [Explorer Link](https://etherscan.io/address/0x43d2c6cFbDD5eD179B2213160d37f0383547fBB3)            |
| Polygon       | [Explorer Link](https://polygonscan.com/address/0xa15172b2588901483d8E49bAf7A73f184775CC31)         |
| BSC           | [Explorer Link](https://bscscan.com/address/0xa15172b2588901483d8E49bAf7A73f184775CC31)             |
| Avalanche     | [Explorer Link](https://snowtrace.io/address/0xc325856e5585823aaC0D1Fd46c35c608D95E65A9)            |
| Arbitrum-one  | [Explorer Link](https://arbiscan.io/address/0xa15172b2588901483d8E49bAf7A73f184775CC31)             |
| Optimism      | [Explorer Link](https://optimistic.etherscan.io/address/0xa15172b2588901483d8E49bAf7A73f184775CC31) |
| Base          | [Explorer Link](https://basescan.org/address/0x2b14763c27B9661182c2503f6C9C4d47BA747Dd2)            |
| Polygon zkEVM | [Explorer Link](https://zkevm.polygonscan.com/address/0x52BeBb970697476313AE2B3383F40d4aFD4aD9D3)   |
| Blast         | -                                                                                                   |
| zkSync        | [Explorer Link](https://explorer.zksync.io/address/0xde46efdd4f8073a475ab3c89cb106d4f1a9a8c2e)      |
| Manta         | [Explorer Link](https://manta.socialscan.io/address/0x9b36f165bab9ebe611d491180418d8de4b8f3a1f)     |
| Scroll        | [Explorer Link](https://scrollscan.com/address/0x9B36f165baB9ebe611d491180418d8De4b8f3a1f)          |
| Metis         | -                                                                                                   |
| Fantom        | -                                                                                                   |
| Taiko         | -                                                                                                   |

### MagpieRouterV2 (Deprecated)

| Network       | Explorer                                                                                                     |
| ------------- | ------------------------------------------------------------------------------------------------------------ |
| Ethereum      | [Explorer Link](https://etherscan.io/address/0xcf32c5bb41f7a302298a2d2072155800871baad3#code)                |
| Polygon       | [Explorer Link](https://polygonscan.com/address/0xcf32c5bb41f7a302298a2d2072155800871baad3)                  |
| BSC           | [Explorer Link](https://bscscan.com/address/0xcf32c5bb41f7a302298a2d2072155800871baad3#code)                 |
| Avalanche     | [Explorer Link](https://snowtrace.io/address/0x746b0cA3762e229D4dCbd22b4A10906aa788D396/contract/43114/code) |
| Arbitrum-one  | [Explorer Link](https://arbiscan.io/address/0xcf32c5bb41f7a302298a2d2072155800871baad3#code)                 |
| Optimism      | [Explorer Link](https://optimistic.etherscan.io/address/0xcf32c5bb41f7a302298a2d2072155800871baad3#code)     |
| Base          | [Explorer Link](https://basescan.org/address/0x6a1431bb23e08e3209dae3130b441863855fc14b#code)                |
| Polygon zkEVM | [Explorer Link](https://zkevm.polygonscan.com/address/0x59b37ed62599f3d2f9a593be0153ef08702cb370)            |
| Blast         | [Explorer Link](https://blastscan.io/address/0x956df8424b556f0076e8abf5481605f5a791cc7f)                     |
| zkSync        | [Explorer Link](https://explorer.zksync.io/address/0x5fe556bcf5fc7db6e075ca6f4cd4f8bbee2a3e54)               |
| Manta         | [Explorer Link](https://pacific-explorer.manta.network/address/0x956Df8424B556F0076E8abf5481605f5A791cc7f)   |
| Scroll        | -                                                                                                            |
| Metis         | -                                                                                                            |
| Fantom        | -                                                                                                            |
| Taiko         | -                                                                                                            |

### **MagpieStargateBridge (Deprecated)**

| Network Name  | Explorer                                                                                            |
| ------------- | --------------------------------------------------------------------------------------------------- |
| Ethereum      | [Explorer Link](https://etherscan.io/address/0x956df8424b556f0076e8abf5481605f5a791cc7f)            |
| Polygon       | [Explorer Link](https://polygonscan.com/address/0x956Df8424B556F0076E8abf5481605f5A791cc7f)         |
| BSC           | [Explorer Link](https://bscscan.com/address/0x956Df8424B556F0076E8abf5481605f5A791cc7f)             |
| Avalanche     | [Explorer Link](https://snowtrace.io/address/0x956Df8424B556F0076E8abf5481605f5A791cc7f)            |
| Arbitrum-one  | [Explorer Link](https://arbiscan.io/address/0x956Df8424B556F0076E8abf5481605f5A791cc7f)             |
| Optimism      | [Explorer Link](https://optimistic.etherscan.io/address/0x956Df8424B556F0076E8abf5481605f5A791cc7f) |
| Base          | -                                                                                                   |
| Polygon zkEVM | [Explorer Link](https://zkevm.polygonscan.com/address/0x956Df8424B556F0076E8abf5481605f5A791cc7f)   |
| Blast         | -                                                                                                   |
| zkSync        | -                                                                                                   |
| Manta         | -                                                                                                   |
| Scroll        | -                                                                                                   |
| Metis         | -                                                                                                   |
| Fantom        | -                                                                                                   |
| Taiko         | -                                                                                                   |


# For Agents

AI Agent integration

## Fly Trade EVM Swap API — Agent Reference

### Overview

Base URL: `https://api.fly.trade`

Execute a token swap on EVM networks in 3 steps:

1. GET `/aggregator/quote` → receive `quoteId` + pricing
2. GET `/aggregator/transaction` → receive transaction payload
3. Sign and submit transaction to the network

**Shortcut:** Use GET `/aggregator/quote/transaction` to get both quote and transaction in one call (no gas estimation).

### Decision Tree for Agent Use

```
Want to swap tokens?
│
├─ Standard swap (user pays gas in native token)
│   ├─ Need gas estimate?  → Step 1 (quote) + Step 2 (transaction, estimateGas=true) + Step 3
│   └─ No gas estimate needed? → Combined /quote/transaction + Step 3
│
└─ Calling from a smart contract?
    └─ GET /quote/transaction (estimateGas=false, fromAddress=CONTRACT) → forward data as calldata
```

***

### Supported Networks

Use the `network` string (not chain ID) in all requests.

| `network` value | Chain             |
| --------------- | ----------------- |
| `ethereum`      | Ethereum Mainnet  |
| `polygon`       | Polygon           |
| `bsc`           | BNB Smart Chain   |
| `arbitrum`      | Arbitrum One      |
| `optimism`      | Optimism          |
| `base`          | Base              |
| `avalanche`     | Avalanche C-Chain |
| `blast`         | Blast             |
| `manta`         | Manta Pacific     |
| `scroll`        | Scroll            |
| `fantom`        | Fantom            |
| `polygonzk`     | Polygon zkEVM     |
| `zksync`        | zkSync Era        |
| `linea`         | Linea             |
| `sonic`         | Sonic             |
| `megaeth`       | MegaETH           |
| `fogo`          | Fogo              |
| `stable`        | Stable            |
| `plasma`        | Plasma            |
| `monad`         | Monad             |
| `hyperevm`      | HyperEVM          |
| `eclipse`       | Eclipse           |
| `unichain`      | Unichain          |
| `berachain`     | Berachain         |
| `abstract`      | Abstract          |
| `ink`           | Ink               |
| `taiko`         | Taiko             |
| `metis`         | Metis             |
| `solana`        | Solana            |
| `morph`         | Morph             |
| `zerogravity`   | 0g                |
| `katana`        | Katana            |
| `tempo`         | Tempo             |
| `telos`         | Telos             |
| `pharos`        | Pharos            |

Full list: GET `/token-manager/networks` or check Swagger at `https://api.fly.trade/swagger`.

***

### These 5 endpoints cover most agent use cases:

#### Step 1 — Get Quote

**GET** `/aggregator/quote`&#x20;

Fetches a quote estimating the output amount you'll receive for swapping a given input asset. Use this to preview the exchange rate, fees, and expected output before committing to a transaction.

#### Required Parameters

| Parameter          | Type    | Description                                                                                                                                                   |
| ------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `network`          | string  | Network name (e.g. `ethereum`)                                                                                                                                |
| `fromTokenAddress` | string  | The token address of the token to sell. Use `0x0000000000000000000000000000000000000000` for native token (ETH/MATIC/BNB)                                     |
| `toTokenAddress`   | string  | Token to buy. Use `0x0000000000000000000000000000000000000000` for native token (ETH/MATIC/BNB)                                                               |
| `sellAmount`       | string  | The amount of the token to sell.                                                                                                                              |
| `slippage`         | number  | Max slippage. `0.005` = 0.5%, `0.01` = 1%                                                                                                                     |
| `fromAddress`      | string  | Wallet address sending the swap                                                                                                                               |
| `toAddress`        | string  | Wallet address receiving tokens                                                                                                                               |
| `gasless`          | boolean | Always set `gasless: false`. This ensures the user pays gas in the native token. Gasless transactions are deprecated and will be removed in a future release. |

#### Optional Parameters

| Parameter          | Type   | Description                                            |
| ------------------ | ------ | ------------------------------------------------------ |
| `affiliateAddress` | string | Address to receive affiliate fee                       |
| `affiliateFee`     | number | Fee percentage. `0.01` = 1%. Deducted from `fromToken` |

#### Example Request

````bash
GET https://api.fly.trade/aggregator/quote?network=ethereum&fromTokenAddress=0x0000000000000000000000000000000000000000&toTokenAddress=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48&fromAddress=0xff270dc360ef80314c7d6b2564fe76eaf3979b1a&toAddress=0xff270dc360ef80314c7d6b2564fe76eaf3979b1a&sellAmount=1000000000000000000&slippage=0.005&gasless=false```
````

#### Response Schema (Standard Swap)

```json
{
  "id": "8de05661-09d6-4b82-ab63-1e32ee1fa297",   // ← save as quoteId
  "amountOut": "1956398549",                        // expected output in smallest unit
  "targetAddress": "0xa6e941eab67569ca4522f70d343714ff51d571c4",  // router address (use for ERC-20 approval)
  "fees": [
    { "type": "gas", "value": "0.0150" }
  ],
  "resourceEstimate": {
    "gasLimit": "191157"
  }
}
```

#### Critical Constraints

* **Quote expires in 5 minutes.** After expiry, the `quoteId` is invalid. Fetch a new quote.
* **Single-use.** Each `quoteId` can only be used once with `/aggregator/transaction`. If consumed or expired, fetch a new quote.
* **ERC-20 approval required** before executing. The spender is `targetAddress` from the quote response.

***

### Step 2 — Get Transaction Payload

**GET** `/aggregator/transaction`

#### Required Parameters

| Parameter | Type   | Description                         |
| --------- | ------ | ----------------------------------- |
| `quoteId` | string | The `id` value returned from Step 1 |

#### Optional Parameters

| Parameter     | Type    | Default | Description                                                                                                                                                        |
| ------------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `estimateGas` | boolean | `true`  | When `true`, validates token approval and balance before returning. Fails with `"Couldn't estimate gas"` if checks fail. Set to `false` for contract integrations. |

#### Example Request

```bash
GET https://api.fly.trade/aggregator/transaction?quoteId=8de05661-09d6-4b82-ab63-1e32ee1fa297
```

#### Response Schema

```json
{
  "from": "0xff270dc360ef80314c7d6b2564fe76eaf3979b1a",
  "to": "0xa6e941eab67569ca4522f70d343714ff51d571c4",   // router contract
  "data": "0x73fc4457...",                               // encoded calldata
  "chainId": 1,
  "type": 2,                                             // EIP-1559 (type 2) or legacy (type 0)
  "gasLimit": "314086",
  "maxFeePerGas": "228922087",                           // present for EIP-1559 chains
  "maxPriorityFeePerGas": "190605439",                   // present for EIP-1559 chains
  "value": "10000000000000000"                           // ETH value in wei (0 for ERC-20 swaps)
}
```

> **Note:** Some chains return legacy format with `gasPrice` instead of `maxFeePerGas`/`maxPriorityFeePerGas`. Ensure your signer/library handles both.

***

### Alternative: Combined Quote + Transaction (Single Request)

**GET** `/aggregator/quote/transaction`

Accepts all parameters from `/aggregator/quote`. `fromAddress` and `toAddress` are **required**. Gas is not estimated.

#### Example Request

````bash
GET https://api.fly.trade/aggregator/quote/transaction?network=base&fromTokenAddress=1&toTokenAddress=2&sellAmount=3&slippage=1&gasless=false&toAddress=111&fromAddress=111```
````

#### Response Schema

```json
{
  "quote": {
    "id": "...",
    "amountOut": "...",
    "targetAddress": "...",
    "fees": [...],
    "resourceEstimate": { "gasLimit": "..." }
  },
  "transaction": {
    "from": "...",
    "to": "...",
    "data": "...",
    "chainId": 1,
    "type": 2,
    "gasLimit": "...",
    "maxFeePerGas": "...",
    "maxPriorityFeePerGas": "...",
    "value": "..."
  }
}
```

***

### Step 3 — Execute the Transaction

Submit the transaction object from Step 2 directly to the network using any EVM-compatible library.

**TypeScript (ethers.js):**

```typescript
const tx = await signer.sendTransaction({
  to: transaction.to,
  data: transaction.data,
  value: transaction.value,
  gasLimit: transaction.gasLimit,
  // For EIP-1559:
  maxFeePerGas: transaction.maxFeePerGas,
  maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,
  // For legacy chains, use gasPrice instead
});
const receipt = await tx.wait();
```

***

### ERC-20 Token Approval

Before swapping an ERC-20 token, the `fromAddress` must approve the router contract (`targetAddress` from the quote) to spend the token.

```typescript
const token = new ethers.Contract(fromTokenAddress, [
  'function allowance(address owner, address spender) view returns (uint256)',
  'function approve(address spender, uint256 amount) returns (bool)'
], signer);

const allowance = await token.allowance(userAddress, routerAddress);
if (allowance.lt(sellAmount)) {
  const approveTx = await token.approve(routerAddress, ethers.constants.MaxUint256);
  await approveTx.wait();
}
```

***

### Smart Contract Integration

When calling from a contract, always set `estimateGas=false` or use the combined `/aggregator/quote/transaction` endpoint with `fromAddress` set to your **contract address**.

```typescript
// Get transaction data targeting your contract as sender
const url = new URL('https://api.fly.trade/aggregator/quote/transaction');
url.searchParams.set('fromAddress', CONTRACT_ADDRESS);
url.searchParams.set('estimateGas', 'false');
// ... other params

const { transaction } = await fetch(url.toString()).then(r => r.json());

// Pass transaction.data as calldata to your contract
await mySwapContract.executeSwap(fromToken, amountIn, transaction.data, { value: 0 });
```

**Contract requirements:**

* Approve the Fly router for ERC-20 tokens before calling
* Forward `transaction.data` as calldata to the router (`targetAddress`)
* Forward the correct `msg.value` for native token swaps


# Fly

随着区块链技术的不断发展，多链生态日益繁荣。我们坚信，链与链之间的互通互联，是 DeFi 长期增长的关键。\
在这个背景下，Fly.trade 不只是一个交易平台，它是 DeFi 的“基建飞轮”——为 DEX、LST 和公链提供底层执行能力，打通链间流动，真正做到“多链无界”。

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

### Fly 是连接器 (Fly Connects)

Fly 是一条航线，串联起交易者与多个区块链生态，把用户引向更多协议、资产与机会。

在 Fly 的路径中，你不仅可以探索不同公链的玩法，还能跨越壁垒，接触到更深层次的 DeFi 应用。

### Fly 是整合器 (Fly leverages)

Fly 会聚合所有链上和跨链的流动性，无论是主流 DEX，还是桥接协议的资金池，统统打通。

这意味着:

* 更深的市场深度
* 更低的滑点
* 更划算的交易价格
* 实时精准的最优路径

你只需要下单，其余交给 Fly。

### Fly 是聚合器 (Fly integrates)

我们整合多个协议的能力，不止是提升效率，更是让用户体验更轻松、DeFi 更强大。

在跨链交易方面，Fly 通过桥的消息传递层，让你在不同链之间一键交易，无需反复兑换稳定币或来回切换钱包。

在链内交易方面，Fly 的智能聚合算法实时捕捉最优交易路径，确保你用最优价格成交。

### Fly 是统一器 (Fly unifies)

我们正在推动一个真正多链协作、流动无界的 DeFi 新时代。

连接更多链、整合更多流动性、融合更多协议——Fly 不只是一个交易工具，它是一条通往未来的航线。

### 未来已来，Fly 正在起飞

在这个链越来越多、协议越来越多的时代，只有真正理解用户、整合流动、降低门槛的平台，才能赢得下一个周期。

Fly.trade 会是你在多链 DeFi 世界中的最佳起点。


# Fly 解决了哪些问题？

Explore the challenges in DeFi that fly trade addresses, including liquidity fragmentation, slippage, and user experience enhancements.

### 多链碎片化严重，使用门槛高 (Complexity and Fragmentation)  <a href="#docs-internal-guid-9c3f6581-7fff-27d9-7fe9-22a39fd76f6e" id="docs-internal-guid-9c3f6581-7fff-27d9-7fe9-22a39fd76f6e"></a>

当前的 DeFi 世界已经不再局限于以太坊。大量流动性分布在超过 50 条链和上百个 DEX 上。每个网络都有自己的界面、资产、流动性池、交互逻辑，甚至不同的钱包支持。这使得用户在寻找目标资产或最佳流动性时面临极高的复杂度，特别是对新用户而言，学习曲线陡峭，使用体验复杂且不友好。

Fly.trade 的目标是打破这一碎片化现状，通过统一的聚合和执行基础设施，连接多链流动性，为用户提供一致、顺畅的多链交易体验。

### 滑点高，成交效率低 (Slippage and Inefficient Liquidity)

由于流动性分散，用户在交易过程中经常遇到滑点过大、成交价格不理想或执行效率低下等问题。寻找最优路径通常需要手动比较多个 DEX 或桥接协议，耗时且容易出错。

Fly 通过智能聚合和实时路由算法，从多个链和协议中动态选择最优路径，帮助用户以最低成本完成交易，并大幅提升交易的价格效率和深度保障。

### 用户体验不佳，交易路径繁琐 (Poor User Experience)&#x20;

目前许多 DeFi 平台存在交互复杂、界面不直观、操作流程冗长等问题，用户常常需要跳转多个协议，进行多次授权与交互，才能完成一次交易。这不仅耗时耗力，也容易导致交易失败或用户流失。

Fly 将多个协议的核心功能整合为一个统一接口，大幅简化交易流程，提升整体用户体验。

### Gas 成本高，交易不够高效 (Gas Fee Optimization)&#x20;

在进行跨链或多步骤链上操作时，Gas 费用成为用户关注的主要成本因素，尤其当路径选择不佳时，可能无形中增加了大量额外开销。这也成为了 DeFi 用户活跃度与留存率的主要阻碍。

Fly 的路由系统会在确保价格优化的同时，也考虑链间和链内的 Gas 成本，帮助用户降低整体交易支出，提升操作效率。


# DeFi 的核心组成部分

### 跨链桥（Bridges） <a href="#docs-internal-guid-7863f6cc-7fff-bd08-b222-9cbb78d7f9a7" id="docs-internal-guid-7863f6cc-7fff-bd08-b222-9cbb78d7f9a7"></a>

跨链桥的作用是帮助用户将某条区块链上的资产转移到另一条链上，无需依赖中心化第三方。

通常，桥会通过智能合约将用户的代币锁定或销毁，并在目标链上铸造等值代币。这个过程确保资产总量保持一致，同时允许用户在不同链之间自由转移资产。

一旦代币跨链成功，用户就可以像使用本链资产一样进行兑换、提供流动性、参与挖矿等操作。

### 去中心化交易所（DEXs）

DEX 是建立在区块链上的交易平台，允许用户直接与其他用户交易加密资产，无需中心化撮合商或平台托管资产。

DEX 通常通过自动做市商（AMM）或订单簿系统实现撮合，所有交易都在链上完成，资产始终掌握在用户自己的钱包中。这不仅保障了资产的安全，也提高了隐私性。

### 流动性聚合（Liquidity Aggregation）

流动性聚合的作用是帮助用户同时从多个 DEX 搜索和比价，自动找到最优交易路径并完成交易，从而节省时间并获得更好的价格。

同时，聚合器通常也会发行治理代币，并激励流动性提供者，为整个 DeFi 社区带来更强的参与和增长动力。

没有流动性聚合，用户往往需要手动筛选数百个协议，寻找合适的交易池和资产路径，这大大提高了使用门槛。


# Fly 的核心功能亮点 (Fly key features)

Fly 不只是提升用户换币体验的聚合器，更在 DEX 基础设施层引入了多项创新，重塑 DeFi 用户体验和协议集成方式。

### 先进的流动性聚合算法 (Advanced Liquidity Aggregation)

Fly 的聚合与订单路由算法为链内与跨链环境提供高可扩展性，且无需依赖第三方聚合器。这意味着用户能获得更优的价格、更低的 Gas 费用，以及更流畅的交易体验。

### 为 DEX、LST、公链与协议提供基础设施支持 (Infra for DEX, LST, chains and protocols)

Fly 不仅服务于终端用户，也服务于其他协议和开发者。用户可以用任意代币、甚至跨链，一键存入 LST、LRT 或 LP 池，大幅简化质押与流动性操作流程。

同时，Fly 提供开放的 API，使其他协议也能向自己的社区用户提供最佳价格与快速兑换能力。

### Gas 成本优化 (Gas Fee Optimization)

通过优化交易路径与选择最节省资源的执行方式，Fly 帮助用户有效减少 Gas 费用，降低交易门槛，让 DeFi 更加亲民易用。

### 链抽象体验 (Chain Abstraction)

多链操作一直是用户最头疼的问题。Fly 通过隐藏链管理的底层复杂性，简化用户界面，做到\*\*“选择你在哪条链、你想去哪个链、想换什么资产”，其余操作全部交由 Fly 自动完成\*\*。

此外，Fly 也在持续构建对智能钱包的原生支持与“全局聚合”功能，为用户提供更高级的链抽象体验。

### 以用户为中心的产品设计 (User-Centric Design)

Fly 坚持简洁直观的交互理念：

一个页面，一个操作界面，一次选择，即可完成整个交易路径。\
所有路径选择、费率比较、跨链桥接、流动性识别，Fly 都为你处理好。

### AI x Crypto 执行层基础设施 (AI x Crypto Execution Layer)

面向 DeFAI（去中心化金融与人工智能结合的下一代生态），Fly 是完美的执行层。借助其算法与 API，DeFAI 协议能够执行：

* 链内/跨链换币
* 管理 LP 持仓
* 参与收益农场
* 购买 LST 或 RWA
* 铸造可收益稳定币等

Fly 拥有高扩展性、低延迟、非托管且低成本的执行能力，是释放 DeFAI 潜力的关键基础设施。


# Fly 的典型应用场景 (Use Cases)

### 跨链兑换（Cross-chain Swaps） <a href="#docs-internal-guid-a8587241-7fff-51ea-a0ad-19929e272305" id="docs-internal-guid-a8587241-7fff-51ea-a0ad-19929e272305"></a>

没有 Fly：\
用户需要手动在两个不同的链上找到合适的 DEX 来进行买卖，此外还需提前准备目标链的 Gas 代币。这通常意味着多次 Swap + 多次桥接操作，才能完成一次跨链交易。例如：

1. 把资产换成目标链的原生 Gas 代币
2. 桥接 Gas 到目标链
3. 桥接目标代币到目标链
4. 再次进行资产兑换

过程复杂、耗时耗费 Gas，体验极差。

使用 Fly：\
用户只需一次授权，一次点击，即可在统一界面内完成几乎任何链上代币的兑换操作。无需跳转多个网站、无需手动桥接、无需额外准备 Gas 代币，而且还能享受 Fly 的最优订单路由算法带来的更好价格。

### 链内兑换（On-Chain Swaps)

没有 Fly：\
用户需在区块链上手动对比多个 DEX，查找哪个池子流动性好、价格更优，甚至可能需要拆单。

使用 Fly：\
直接在 Fly 界面上输入你想换的任意代币，Fly 会自动聚合全链上所有主流 DEX 的价格与深度，为你寻找最佳成交路径。如果多池组合价格更优，Fly 还会自动拆分交易，确保你获得最划算的报价。

### 跨链收益挖矿 / 借贷 / NFT 购买 Cross-chain Yield farming/Lending & Borrowing/ NFT)

没有 Fly：\
用户需重复进行跨链兑换、桥接、寻找项目机会，还可能要在多个协议之间授权与切换。过程繁琐，Gas 成本高，操作门槛大。

使用 Fly（规划中 / 部分功能即将上线）：

* 收益挖矿（Yield Farming）\
  用户将能通过 Fly 接入链内或跨链的收益机会，仅需几次点击即可完成参与，无需反复桥接或兑换，大幅节省时间与 Gas 成本。
* 借贷（Lending & Borrowing）\
  未来将支持接入 AAVE、Compound 等借贷协议，用户可直接在 Fly 界面借出或借入资产，无需切换平台或链。
* NFT 市场跨链购买\
  用户未来可直接在 Fly 浏览各大 NFT 市场，并使用任意代币购买任意链上的 NFT，打通流动性与链间壁垒。

### 钱包 App 与 DEX 平台  (Wallet Apps & DEXs)

Fly 提供链抽象与聚合路由能力，使钱包或 DEX 无需自建复杂的跨链系统，即可实现跨链兑换、质押与借贷等功能。

### 专业交易者与机构用户 (Institutions & Professional Traders)

Fly 构建了低延迟、高资本效率的基础设施，适合做市商、量化团队或其他机构部署自动化交易策略。

### NFT 市场平台 (NFT Marketplaces)

NFT 项目方可通过 Fly 提供的 API 实现跨链支付能力，让用户使用任意链上资产直接购买 NFT，提升成交率与用户体验。

### Web3 项目方与协议开发者 (Web3 Projects)

不论是单链还是多链项目，接入 Fly 后，项目方即可一键赋能用户参与借贷、质押、挖矿等核心金融操作，提升资产流动性与用户留存。


# FAQ

Frequently Asked Questions

### Visit to our Help Center for more FAQ and knowledge hub. <https://support.magpiefi.xyz/hc/en-us>


# 支持的区块链网络 (Supported Networks)

This document describes the networks supported by the Magpie protocol 🚀

<div><figure><img src="/files/jenq0a8xQ2l9oYZEOVwk" alt=""><figcaption><p><strong>Sonic</strong></p></figcaption></figure> <figure><img src="/files/5656uD89H0U3hDTlKec0" alt=""><figcaption><p><strong>Ethereum</strong></p></figcaption></figure> <figure><img src="/files/Jm3FUqJJcs5jsoXtZn8B" alt=""><figcaption><p><strong>Ink</strong></p></figcaption></figure> <figure><img src="/files/V8iEwCYdEtEKuBYDMUTS" alt=""><figcaption><p><strong>Berachain</strong></p></figcaption></figure> <figure><img src="/files/MrFrgGsOplifmc7TJ2Am" alt=""><figcaption><p><strong>BNB Smart Chain</strong></p></figcaption></figure></div>

<div><figure><img src="/files/9VmjvUbLfJrZ9tTnCQ42" alt=""><figcaption><p><strong>Base</strong></p></figcaption></figure> <figure><img src="/files/Lm1EQqrpgjCpummDqTPN" alt=""><figcaption><p><strong>Polygon</strong></p></figcaption></figure> <figure><img src="/files/0uoY7piPJtA1vgEWHk67" alt=""><figcaption><p><strong>Optimism</strong></p></figcaption></figure> <figure><img src="/files/ygUqagbdcu7voTGmyPDA" alt=""><figcaption><p><strong>Arbitrum</strong></p></figcaption></figure> <figure><img src="/files/8qq7n5tQqKGGyn68YV35" alt=""><figcaption><p><strong>Avalanche</strong></p></figcaption></figure></div>

<div><figure><img src="/files/q3vfHEhUPJQ5mpcNRB5X" alt=""><figcaption><p><strong>Manta</strong></p></figcaption></figure> <figure><img src="/files/aHDhYHKNnv1O4tyHY6w2" alt=""><figcaption><p><strong>Polygon zkEVM</strong></p></figcaption></figure> <figure><img src="/files/zLuD251RtaMCoEhmFzzX" alt=""><figcaption><p><strong>zkSync</strong></p></figcaption></figure> <figure><img src="/files/O4sCu4xKcEWH8PEFTWu5" alt=""><figcaption><p><strong>Blast</strong></p></figcaption></figure> <figure><img src="/files/XTDmg5hoJam5PGzZ9RU2" alt=""><figcaption><p><strong>Scroll</strong></p></figcaption></figure></div>

<div><figure><img src="/files/XI2bFxmF0ysDbAZ1ZjUH" alt=""><figcaption><p><strong>Linea</strong></p></figcaption></figure> <figure><img src="/files/LJqwS9JNMFyBYoV7kyb2" alt=""><figcaption><p><strong>Metis</strong></p></figcaption></figure> <figure><img src="/files/8vJMSeGpK9IRg2CRGB9b" alt=""><figcaption><p><strong>Fantom</strong></p></figcaption></figure></div>


# Guides

Learn a bit about Magpie and how to use our app here!

{% content-ref url="/pages/SY4NYyowVQO9CujgBLjA" %}
[Glossary of DeFi Terms](/flycn/guides/glossary-of-defi-terms)
{% endcontent-ref %}

{% content-ref url="/pages/n5Uq65VHfbvQPf2aCLHc" %}
[Connect Wallet](/flycn/guides/connect-wallet)
{% endcontent-ref %}

{% content-ref url="/pages/dgpmdLatZiC75DispemQ" %}
[On-Chain Swap](/flycn/guides/on-chain-swap)
{% endcontent-ref %}

{% content-ref url="/pages/DKknfVMyi0LFcB0jq11M" %}
[Cross-Chain Swap](/flycn/guides/cross-chain-swap)
{% endcontent-ref %}

{% content-ref url="/pages/VpAcKZsPxasrtjyPqWyt" %}
[Swap configuration](/flycn/guides/swap-configuration)
{% endcontent-ref %}

{% content-ref url="/pages/7yQwOfm9K0FZg3sBtyQC" %}
[fly boosts](/flycn/guides/fly-boosts)
{% endcontent-ref %}

{% content-ref url="/pages/jnHCQ9ZzotNT9ytyyL7c" %}
[Transaction History](/flycn/guides/transaction-history)
{% endcontent-ref %}

{% content-ref url="/pages/lMhNw91VWkHe742MpcRi" %}
[Portfolio](/flycn/guides/portfolio)
{% endcontent-ref %}


# Glossary of DeFi Terms

Understand key DeFi terminology with Fly Trade's glossary, covering assets, AMMs, liquidity, slippage, and more to enhance your crypto knowledge.

### Asset

Digital token/cryptocurrency that can be owned, transferred, traded, or staked on the blockchain. fly.trade allows for the trading, staking, and moving of assets.

### Automated Market Makers

AMMs, such as Uniswap, allow users to deposit their tokens into smart contract-based liquidity pools to contribute to liquidity so that they may earn fees on the trades while users get access to asset swaps at market rates.

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

### ERC20

Token standard for Fungible tokens on Ethereum and EVM (Ethereum virtual machine) blockchains.

### Gas Fee

The fee required to initiate a transaction or execute a smart contract on a blockchain. In short, it's the cost of using the network's computational resources, compensating network validators or miners who process and confirm the transaction. Gas is typically paid in the native token of the blockchain (ETH on Ethereum and many EVM chains, S on Sonic, SOL on Solana)

### Liquidity <a href="#docs-internal-guid-0e99ae6a-7fff-9d79-0a7b-b09595090f43" id="docs-internal-guid-0e99ae6a-7fff-9d79-0a7b-b09595090f43"></a>

Assets in pools. Token/asset pairs that are available for trading.

### Liquidity Provider or "LP" <a href="#docs-internal-guid-715d28c3-7fff-fb87-07ec-35e13f66624d" id="docs-internal-guid-715d28c3-7fff-fb87-07ec-35e13f66624d"></a>

Users who pair and pool tokens. Liquidity providers assume impermanent loss and are compensated with swap fees, emissions (on some DEXs), as well as incentives.

### Pair <a href="#docs-internal-guid-ce8cf26d-7fff-0277-ba0f-246aa8cd0b12" id="docs-internal-guid-ce8cf26d-7fff-0277-ba0f-246aa8cd0b12"></a>

A smart contract that enables trading directly between two assets.

### Price Impact <a href="#docs-internal-guid-df51fe51-7fff-6d29-3bf3-4356350ef60d" id="docs-internal-guid-df51fe51-7fff-6d29-3bf3-4356350ef60d"></a>

The effect a trade has on an asset's price due to the size of the order relative to pool liquidity. Larger trades typically result in higher price impact.

### Pools

A smart contract that enables trading between two ERC20 tokens. Blockchains and DEXs can have multiple pools with the same assets, or tokens, with differing amounts of liquidity and slight price variation.

### Slippage <a href="#docs-internal-guid-b84de979-7fff-b166-3d70-406f4aefafa8" id="docs-internal-guid-b84de979-7fff-b166-3d70-406f4aefafa8"></a>

The price change between submitting a transaction and its execution.

### Swap Fees

A small fee which goes to the liquidity providers of the token.


# Connect Wallet

Step-by-step guide to connecting your wallet to fly trade, enabling secure and efficient access to DeFi trading features.

On the fly.trade website, one can connect a wallet by clicking on the "Connect the wallet" button located in the top right corner or in the swap menu.

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

Once the wallet is connected, the user can find their wallet address getting displayed on the top right of the screen.

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

If the current network of the wallet and the chosen network on the swap page do not match, then the button at the end of the swap activity box displays "Change Network To \<selected-network-name>"

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


# On-Chain Swap

Here we will provide you with a step-by-step set of instructions to swap tokens on the same chain using the fly.trade app.

Click under the 'From' field where the cursor shows in the below image in order to select the chain and token. In this example, we are going to swap USDC.E on Sonic to the STS token.

<figure><img src="/files/8z5s2OcWR0sJj3C51qD8" alt="" width="417"><figcaption></figcaption></figure>

Once you've clicked the 'From' field, you'll see the following, where you can select a network and token you would like to swap. If the stS token isn't near the top of the list for you, you can use the search field to find the token. We'll be selecting the Sonic Chain and USDC.e token for this example.

<figure><img src="/files/gFVlQdxNHOnHQwhpV9Rj" alt="" width="415"><figcaption></figcaption></figure>

In the app, you'll now click on the field below the 'To' in order to select the destination chain and token.

<figure><img src="/files/rfAj8r0ukESOPOaTt67n" alt="" width="418"><figcaption><p>As this is an on-chain swap, select the Sonic network and the STS token.</p></figcaption></figure>

Once you have selected the pair and amount, click "Swap USDC.e to stS." Note: the gas tank icon can be clicked to select the option to use the blockchains native gas token for the transactions, and the leaf icon can be selected to use fly.trade's gasless feature, which will use they token you are swapping to pay for the gas, just in case you do not have the native gas token.

<figure><img src="/files/Xxt2ZR6KDOZ64eJk4EgM" alt="" width="419"><figcaption></figcaption></figure>

After clicking 'Swap,' your wallet will prompt you to confirm the transaction with an estimated gas fee. Here is where you can adjust the amount of gas you want to spend if that is something you're comfortable with, but most people leave it at the suggested amount.

<figure><img src="/files/MMy7yF3MpWL9IlUT7kKA" alt="" width="423"><figcaption></figcaption></figure>

After 'Confirming' the transaction, just wait a bit and you can either click on the bar that appears once the swap is completed in the upper right of the screen, or you can click on the Wallet icon in the upper right of the web page to bring up the sidebar and select your history to view all previous transactions.

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

<figure><img src="/files/fjTOwXbjoyDiylrwtGoB" alt="" width="390"><figcaption></figcaption></figure>

You've just completed your first swap through fly.trade!&#x20;


# Cross-Chain Swap

Here we will provide you with a step-by-step set of instructions to swap tokens across chains using the fly.trade app. The process is very similar to on-chain swaps.

For a Cross-Chain swap select a different chain in the receiving network drop-down menu. For this example we will be swapping the 'LINK' token from 'Arbitrum' network for the 'AAVE' token on the 'Optimism' network.

<figure><img src="/files/OZ3Fs7xjhuMgCo95YiAh" alt="" width="375"><figcaption></figcaption></figure>

Just the same as the On-Chain swap instructions, select the box below the 'From' text to select the chain/network we are starting on, in this case, Arbitrum.&#x20;

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

Now select the 'LINK' token. If it's not near the top of your list, you can use the search bar to find it.

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

Next, select the box below the 'To' text and select the 'Optimism' chain/network, then search for and select 'AAVE' as the token to receive.

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

Next, we need to click on the 'Approve LINK' button so that the fly.trade dApp gains permission to swap the tokens.

<figure><img src="/files/9FQTBU1xyYnNOf50j291" alt=""><figcaption></figcaption></figure>

Your wallet app will prompt you to give the fly.trade dApp permission to use the selected token. Click 'Confirm.'

<figure><img src="/files/TnAxz5IwljYcQysZNsDz" alt="" width="361"><figcaption></figcaption></figure>

Once confirmed, the 'Approve' button now says "Swap LINK to AAVE". Click the button to start the swap process.

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

Your wallet will once again prompt you to confirm the transaction, this time with estimated fees for any Gas, Bridge, or Relayer fees that are required for the swap, all-in-one. Click the "Confirm" button to initiate the swap.

<figure><img src="/files/OyWdlOjyuiKD2l7nN8ul" alt="" width="360"><figcaption></figcaption></figure>

Next, you can either click on the bar in the upper right that shows the swap is completed to check the transaction or you can open the sidebar to see your transaction history and view the information there.

It'll look something like this, showing the two steps involved:&#x20;

* Receiving bridge funds
* Executing swap out

<figure><img src="/files/n5z4SeojH64vpNAhsGmw" alt="" width="375"><figcaption></figcaption></figure>

**There are three possible outcomes now:** \
1\. Successful transaction  \
2\. Refunded transaction \
3\. Intended token transaction&#x20;

1. **Successful Transaction:** You have received the chosen token.<br>

<figure><img src="/files/LcfPbrza6MxVubM8sKBF" alt="" width="375"><figcaption></figcaption></figure>

2. Refunded transaction : Something went wrong during the swap, and we have returned your token.

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

3. Intended token transaction  : If, during a cross-chain swap, there is not enough liquidity or high token volatility to receive the selected token, we provide you with a token that you can later swap using an On-chain swap by clicking "Swap to..." :

<figure><img src="/files/S8qmv68itEgVBcuSSXw9" alt="" width="563"><figcaption></figcaption></figure>

\
\
Hopefully that was easy, no bridges, no extra websites, just as simple as a normal on-chain swap.

Depending on the network you are going to or from, there can be a differing amount of time it takes for the transactions, but you can check the status in the 'Transactions' tab in the upper right corner of the screen.




---

[Next Page](/llms-full.txt/1)

