# Introducing Carbon DeFi

Carbon DeFi is an onchain trading protocol allowing users to perform automated trading strategies using custom limit orders and range orders. Users can submit individual limit/range orders or combine their orders together to create “recurring strategies” that buy a token low and sell it high in distinct price ranges. Unlike existing AMMs, Carbon DeFi allows users to customize the spread between their buy and sell orders.

By design, Carbon DeFi orders are irreversible on execution, easily adjustable directly on-chain, and resistant to MEV sandwich attacks. These capabilities give users an unprecedented level of control and automation to execute novel trading strategies on-chain.

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


# What Makes Carbon DeFi Unique?

Compared to existing on-chain liquidity protocols and AMMs, Carbon DeFi gives users the ability to execute automated on-chain trading strategies with greater control and efficiency via:

* an adjustable bid/ask spread
* rotating liquidity
* unidirectional, irreversible orders
* protection from MEV sandwich attacks

### Adjustable Spread

Users who create strategies in Carbon DeFi ("makers") are similar to liquidity providers in existing AMMs in that their activities supply liquidity for trading, and they collect fees from other users ("takers") who perform spot trades using their liquidity.&#x20;

However, Carbon DeFi is unique in that each individual maker can customize the fee they collect from trades by selecting their buy and sell ranges. While legacy AMMs force their liquidity providers to adopt the fee of the AMM they're providing liquidity to, Carbon DeFi lets LPs set their own personalized fee (or spread) by selecting the specific price(s) where they'd like to buy and where they'd like to sell their tokens.

### Rotating Liquidity

When a user provides liquidity in existing on-chain liquidity protocols/AMMs, their position buys and sells tokens using a single pricing curve ("bonding curve").

In Carbon DeFi, each user position consists of two bonding curves (or "orders") - one for buying and one for selling. When a user deposits a token pair, each token in the pair has one custom curve based on the settings decided by the user. Once your position buys or sells at your desired price, your liquidity is automatically rotated to its paired curve, where it sits inactive (in the case of a single limit or range order).

In the case of a recurring strategy, buy and sell orders trade in perpetuity, until the user chooses to stop the strategy. Such a strategy offers to buy in one price range and sell in a higher range, with liquidity automatically rotating between the selected ranges as each order is executed (akin to a "Grid Trading" or "Scalping" strategy).

{% hint style="info" %}
When using a Carbon DeFi strategy to replicate a concentrated liquidity position, the effective spread (also known as the fee tier) may narrow over time due to the auto-compounding nature of order balances. To maintain your intended spread, it’s recommended to periodically update the strategy and reconfigure the desired fee tier.
{% endhint %}

### Unidirectional, Irreversible Orders

In existing on-chain liquidity protocols, executed orders may be reversed when markets retrace. This is due the bidirectional nature of AMM liquidity: Once a buy order for one asset is traded against, a sell order for the other asset is placed at the same price. To avoid order reversal, users must manually monitor and withdraw their liquidity upon execution (or rely on external tooling to do so).

In contrast, limit/range orders in Carbon DeFi flow in a single direction and are therefore irreversible on execution. This removes the need for users to constantly monitor their orders and manually withdraw in time, or rely on a third-party to do so. [Read more about Carbon DeFi limit orders](/contracts-and-functions/carboncontroller-functions/data-and-events/strategydeleted)[.](https://medium.com/carbondefi/true-dex-limit-orders-carbon-vs-existing-solutions-58cd955098fd)

### MEV Protection

Due to the irreversibility of Carbon DeFi orders, spot trades that execute against Carbon DeFi strategies are protected from MEV sandwich attacks. [Read more about Carbon DeFi and MEV](https://medium.com/carbondefi/carbon-the-mev-sandwich-is-toast-2ec7800dde68).


# Fees & Payments

All fees collected by Carbon DeFi are protocol-owned, and their allocation is decided solely through DAO governance.

### Trader fees&#x20;

These fees are paid by the users that trade with existing strategies and orders on Carbon DeFi. The trading fee is defined as a percentage from the trade amount. The current trading fee percentage can be verified via smart contract, as described on the [tradingFeePPM](/contracts-and-functions/carboncontroller-functions/read-functions/tradingfeeppm) page.

### Dex aggregator swap fees

On the app interface, for some chains, we introduce a dex aggregator solution (inhouse or managed by 3rd party) which will include a specific 0.25% trading fee as part of the transaction.


# Resources

* [Carbon DeFi Website](https://www.carbondefi.xyz/)
* [Dune Analytics](https://dune.com/bancor/carbon-by-bancor)
* [Carbon DeFi FAQs](https://faq.carbondefi.xyz/)
* [Github](https://github.com/bancorprotocol/carbon-contracts)
* [Whitepaper](http://carbondefi.xyz/whitepaper)
* [Litepaper](http://carbondefi.xyz/litepaper)
* [Carbon DeFi Simulator](https://github.com/bancorprotocol/carbon-simulator)
* [Carbon DeFi SDK](https://github.com/bancorprotocol/carbon-sdk)
* [YouTube](https://www.youtube.com/@BancorProtocol)


# Security & Audits

Carbon Defi has been professionally audited by several world-class auditors.&#x20;

### PeckShield

[July 31, 2024 audit report done by PeckShield team](https://github.com/bancorprotocol/carbon-contracts/blob/dev/docs/audits/PeckShield-Audit-Report-Bancor-CarbonVortex-v1.0.1.pdf)

### PeckShield

[May 29, 2024 audit report done by PeckShield team](https://github.com/bancorprotocol/carbon-contracts/blob/dev/docs/audits/PeckShield-Audit-Report-Bancor-Carbon-v1.0.pdf)

### ChainSecurity&#x20;

[April 10, 2023 audit report done by ChainSecurity team](https://github.com/bancorprotocol/carbon-contracts/blob/dev/docs/audits/ChainSecurity_Carbon_Audit_Report.pdf)

### PeckShield

[April 4, 2023 audit report done by PeckShield team](https://github.com/bancorprotocol/carbon-contracts/blob/dev/docs/audits/PeckShield-Audit-Report-Carbon-v1.0.pdf)<br>

In addition, Carbon DeFi has a live public bug bounty with rewards of up to $1 million.

[**Details of the Carbon DeFi Public Bug Bounty can be found here**](https://github.com/bancorprotocol/carbon-contracts/blob/dev/docs/bug-bounty.md).


# Contracts

Carbon DeFi on-chain architecture is aiming to simplify the access points and contracts one needs to interact with. Therefore, it is composed of only two contracts which are using proxy addresses, meaning their address is unlikely to change.&#x20;

## Carbon DeFi Github

This repository includes Carbon DeFi and CarbonVortex core contracts&#x20;

{% embed url="<https://github.com/bancorprotocol/carbon-contracts>" %}

## CarbonVortexBridge Github

This repository includes CarbonVortexBridge core contracts

{% embed url="<https://github.com/bancorprotocol/carbon-vortex-bridge>" %}


# CarbonController

The `CarbonController`  purpose is to manage liquidity strategies and execute trades while ensuring compliance with the protocol's rules.&#x20;

Its functions include:

1. **Liquidity Management**:\
   The `CarbonController` facilitates the creation and management of liquidity strategies by users. These strategies define how liquidity is allocated across various market conditions to optimize trading outcomes.
2. **Strategy Execution**:\
   It controls the execution of user-defined strategies. By automating the trade processes, the controller ensures that trades align with the parameters defined in the liquidity strategies.
3. **Trade Handling**:\
   The contract processes trades by interacting with connected liquidity pools. It calculates optimal trade routes and ensures that trades occur within the bounds of user-defined parameters like slippage limits.


# CarbonVortex

The `CarbonVortex` contract is a mechanism in Carbon Defi designed to improve the efficiency and sustainability of the ecosystem by managing fees and circulating tokens. The execute() function in the contract include caller incentive for initiating token auction.

its functions include:

1. **Fee Collection**:

   It aggregates fees from various sources within the protocol, ensuring a steady accumulation of value derived from ecosystem usage.
2. **Token Consolidation**:

   The Carbon Defi ecosystem collects fees in multiple token formats. CarbonVortex facilitates permissionless consolidation of these tokens into a single unified token, typically the chain's native gas token (e.g., ETH on Ethereum).
3. **Blockchain Consolidation:**\
   \[To be added] The CarbonVortex enables the bridging of all collected fees onto the Ethereum blockchain.


# CarbonVortexBridge

The `CarbonVortexBridge` contract facilitates the ability to bridge any collected tokens from the `CarbonVortex`contract on any chain, onto Ethereum.

This distributed mechanism allows any caller to consolidate collected fees into a single blockchain (Ethereum) and allow the `CarbonVortex` to complete its task of auctioning these tokens.


# Deployments

Carbon DeFi contract addresses on different supported blockchains

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td>Mainnet Contract Addresses</td><td><a href="/pages/itx0VIdwfLUCgmaY7GDy">/pages/itx0VIdwfLUCgmaY7GDy</a></td><td><a href="/files/3P1jwREzX0RZGSN6mbVX">/files/3P1jwREzX0RZGSN6mbVX</a></td></tr><tr><td>Testnet Contract Addresses</td><td><a href="/pages/pdyGPjnETLFDde2G2ykY">/pages/pdyGPjnETLFDde2G2ykY</a></td><td><a href="/files/AEU2TGdD2a5ZkgGI6Pmn">/files/AEU2TGdD2a5ZkgGI6Pmn</a></td></tr></tbody></table>


# Mainnet Contracts

### Ethereum contracts

<table><thead><tr><th width="206.33333333333331">Name</th><th width="296">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonController</td><td>0xC537e898CD774e2dCBa3B14Ea6f34C93d5eA45e1<br><a href="https://etherscan.io/address/0xC537e898CD774e2dCBa3B14Ea6f34C93d5eA45e1">view on etherscan</a></td><td>This contract serves as the entry point for all interactions with Carbon DeFi.</td></tr><tr><td>Voucher</td><td>0x3660F04B79751e31128f6378eAC70807e38f554E<br><a href="https://etherscan.io/address/0x3660F04B79751e31128f6378eAC70807e38f554E">view on etherscan</a></td><td>This is the Carbon DeFi strategy NFT. </td></tr><tr><td>CarbonVortex</td><td>0xD053Dcd7037AF7204cecE544Ea9F227824d79801<br><a href="https://etherscan.io/address/0xd053dcd7037af7204cece544ea9f227824d79801#code">view on etherscan</a></td><td>Dutch auction contract that receives ArbFastLane transfers, Carbon DeFi fees and Bancor V3 pools' surplus, and allows public interactions.</td></tr></tbody></table>

### SEI-v2 EVM contracts

<table><thead><tr><th width="204.33333333333331">Name</th><th width="296">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonController</td><td>0xe4816658ad10bF215053C533cceAe3f59e1f1087<br><a href="https://seiscan.io/address/0xe4816658ad10bF215053C533cceAe3f59e1f1087#code">view on seiscan</a></td><td>This contract serves as the entry point for all interactions with Carbon DeFi.</td></tr><tr><td>Voucher</td><td>0xA4682A2A5Fe02feFF8Bd200240A41AD0E6EaF8d5<br><a href="https://seiscan.io/address/0xA4682A2A5Fe02feFF8Bd200240A41AD0E6EaF8d5#code">view on seiscan</a></td><td>This is the Carbon DeFi strategy NFT. </td></tr><tr><td>CarbonVortex</td><td>0x5715203B16F15d7349Cb1E3537365E9664EAf933<br><a href="https://seiscan.io/address/0x5715203B16F15d7349Cb1E3537365E9664EAf933#code">view on seiscan</a></td><td>Dutch auction contract that receives Carbon DeFi fees and allows public interactions.</td></tr><tr><td>CarbonVortexBridge</td><td>0x57Cf0C29C2B7Bc7Cf5396568e25E34a1b687ea05<br><a href="https://seiscan.io/address/0x57Cf0C29C2B7Bc7Cf5396568e25E34a1b687ea05#code">view on seiscan</a></td><td>Public contract that allows callers to bridge funds over to Ethereum</td></tr></tbody></table>

### Celo EVM contracts

<table><thead><tr><th width="194.33333333333331">Name</th><th width="296">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonController</td><td>0x6619871118D144c1c28eC3b23036FC1f0829ed3a<br><a href="https://celoscan.io/address/0x6619871118D144c1c28eC3b23036FC1f0829ed3a#code">view on celoscan</a></td><td>This contract serves as the entry point for all interactions with Carbon DeFi.</td></tr><tr><td>Voucher</td><td>0x5E994Ac7d65d81f51a76e0bB5a236C6fDA8dBF9A<br><a href="https://celoscan.io/address/0x5E994Ac7d65d81f51a76e0bB5a236C6fDA8dBF9A#code">view on celoscan</a></td><td>This is the Carbon DeFi strategy NFT. </td></tr><tr><td>CarbonVortex</td><td>0xD9D89e8A0dfE549e5B424D5b511cB3b84A764857<br><a href="https://celoscan.io/address/0xD9D89e8A0dfE549e5B424D5b511cB3b84A764857">view on celoscan</a></td><td>Dutch auction contract that receives Carbon DeFi fees and allows public interactions.</td></tr><tr><td>CarbonVortexBridge</td><td>0x753425e27aE996f0DB75C759C6E5EBa5c74D6aAF<br><a href="https://celoscan.io/address/0x753425e27aE996f0DB75C759C6E5EBa5c74D6aAF">view on celoscan</a></td><td>Public contract that allows callers to bridge funds over to Ethereum</td></tr></tbody></table>

### Coti EVM contracts

<table><thead><tr><th width="194.33333333333331">Name</th><th width="296">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonController</td><td>0x59f21012B2E9BA67ce6a7605E74F945D0D4C84EA<br><a href="https://mainnet.cotiscan.io/address/0x59f21012B2E9BA67ce6a7605E74F945D0D4C84EA">view on cotiscan</a></td><td>This contract serves as the entry point for all interactions with Carbon DeFi.</td></tr><tr><td>Voucher</td><td>0xA4682A2A5Fe02feFF8Bd200240A41AD0E6EaF8d5<br><a href="https://mainnet.cotiscan.io/address/0xA4682A2A5Fe02feFF8Bd200240A41AD0E6EaF8d5">view on cotiscan</a></td><td>This is the Carbon DeFi strategy NFT. </td></tr><tr><td>CarbonVortex</td><td>0x653E98561925B55977c0100636CcD314C4F232c5<br><a href="https://mainnet.cotiscan.io/address/0x653E98561925B55977c0100636CcD314C4F232c5?tab=index">view on cotiscan</a></td><td>Dutch auction contract that receives Carbon DeFi fees and allows public interactions.</td></tr><tr><td>CarbonVortexBridge</td><td>0xDEFeCd8c437df9C492B667776A6f98AaDbf5852C<br><a href="https://mainnet.cotiscan.io/address/0xDEFeCd8c437df9C492B667776A6f98AaDbf5852C">view on cotiscan</a></td><td>Public contract that allows callers to bridge funds over to Ethereum</td></tr></tbody></table>

### TAC EVM contracts

<table><thead><tr><th width="194.33333333333331">Name</th><th width="296">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonController</td><td>0xA4682A2A5Fe02feFF8Bd200240A41AD0E6EaF8d5<br><a href="https://explorer.tac.build/address/0xA4682A2A5Fe02feFF8Bd200240A41AD0E6EaF8d5">view on tac explorer</a></td><td>This contract serves as the entry point for all interactions with Carbon DeFi.</td></tr><tr><td>Voucher</td><td>0xb0d39990E1C38B50D0b7f6911525535Fbacb4C26<br><a href="https://explorer.tac.build/address/0xb0d39990E1C38B50D0b7f6911525535Fbacb4C26">view on tac explorer</a></td><td>This is the Carbon DeFi strategy NFT. </td></tr><tr><td>CarbonVortex</td><td>0xf7c7d7507041977aB0328CAf449f1e80085709a9<br><a href="https://explorer.tac.build/address/0xf7c7d7507041977aB0328CAf449f1e80085709a9">view on tac explorer</a></td><td>Dutch auction contract that receives Carbon DeFi fees and allows public interactions.</td></tr><tr><td>CarbonVortexBridge</td><td>0xa15E3295465439A361dBcac79C1DBCE6Cd01E562<br><a href="https://explorer.tac.build/address/0xa15E3295465439A361dBcac79C1DBCE6Cd01E562?tab=index">view on tac explorer</a></td><td>Public contract that allows callers to bridge funds over to Ethereum</td></tr></tbody></table>

### Base contracts

<table><thead><tr><th width="201">Name</th><th width="298">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonVortex</td><td>0xA4682A2A5Fe02feFF8Bd200240A41AD0E6EaF8d5<br><a href="https://basescan.org/address/0xA4682A2A5Fe02feFF8Bd200240A41AD0E6EaF8d5">view on basescan</a></td><td>Dutch auction contract that receives Carbon DeFi fees and allows public interactions.</td></tr><tr><td>CarbonVortexBridge</td><td>0x773B75CfB146bd5d1095fa9d6d45637f02B05119<br><a href="https://basescan.org/address/0x773B75CfB146bd5d1095fa9d6d45637f02B05119">view on basescan</a></td><td>Public contract that allows callers to bridge funds over to Ethereum</td></tr></tbody></table>

### Fantom contracts

<table><thead><tr><th width="199">Name</th><th width="298">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonVortex</td><td>0x4A0c4eF72e0BA9d6A2d34dAD6E794378d9Ad4130<br><a href="https://www.oklink.com/fantom/address/0x4A0c4eF72e0BA9d6A2d34dAD6E794378d9Ad4130">view on oklink</a></td><td>Dutch auction contract that receives Carbon DeFi fees and allows public interactions.</td></tr><tr><td>CarbonVortexBridge</td><td>0xA60a60d509a40F7A1D8c960f6ff708ae2659409e<br><a href="https://www.oklink.com/fantom/address/0xA60a60d509a40F7A1D8c960f6ff708ae2659409e">view on oklink</a></td><td>Public contract that allows callers to bridge funds over to Ethereum</td></tr></tbody></table>

### Mantle contracts

<table><thead><tr><th width="203">Name</th><th width="298">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonVortex</td><td>0x59f21012B2E9BA67ce6a7605E74F945D0D4C84EA<br><a href="https://mantlescan.xyz/address/0x59f21012B2E9BA67ce6a7605E74F945D0D4C84EA">view on mantlescan</a></td><td>Dutch auction contract that receives Carbon DeFi fees and allows public interactions.</td></tr><tr><td>CarbonVortexBridge</td><td>0xC56Eb3d03C5D7720DAf33a3718affb9BcAb03FBc<br><a href="https://mantlescan.xyz/address/0xC56Eb3d03C5D7720DAf33a3718affb9BcAb03FBc">view on mantlescan</a></td><td>Public contract that allows callers to bridge funds over to Ethereum</td></tr></tbody></table>

### Linea contracts

<table><thead><tr><th width="200">Name</th><th width="298">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonVortex</td><td>0x5bCA3389786385a35bca14C2D0582adC6cb2482e<br><a href="https://lineascan.build/address/0x5bCA3389786385a35bca14C2D0582adC6cb2482e">view on lineascan</a></td><td>Dutch auction contract that receives Carbon DeFi fees and allows public interactions.</td></tr><tr><td>CarbonVortexBridge</td><td>0x3F086F628678cF136C4fA7d2901ff5EBE2623435<br><a href="https://lineascan.build/address/0x3F086F628678cF136C4fA7d2901ff5EBE2623435">view on lineascan</a></td><td>Public contract that allows callers to bridge funds over to Ethereum</td></tr></tbody></table>

### Blast contracts

<table><thead><tr><th width="202">Name</th><th width="298">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonVortex</td><td>0x0f54099D787e26c90c487625B4dE819eC5A9BDAA<br><a href="https://blastscan.io/address/0x0f54099D787e26c90c487625B4dE819eC5A9BDAA">view on blastscan</a></td><td>Dutch auction contract that receives Carbon DeFi fees and allows public interactions.</td></tr><tr><td>CarbonVortexBridge</td><td>0x63e353AE90f95C72bf1E78e45456fb78B0c97525<br><a href="https://blastscan.io/address/0x63e353AE90f95C72bf1E78e45456fb78B0c97525#code">view on blastscan</a></td><td>Public contract that allows callers to bridge funds over to Ethereum</td></tr></tbody></table>

### Telos contracts

<table><thead><tr><th width="193">Name</th><th width="298">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonVortex</td><td>0x5E994Ac7d65d81f51a76e0bB5a236C6fDA8dBF9A<br><a href="https://www.teloscan.io/address/0x5E994Ac7d65d81f51a76e0bB5a236C6fDA8dBF9A">view on telosscan</a></td><td>Dutch auction contract that receives Carbon DeFi fees and allows public interactions.</td></tr><tr><td>CarbonVortexBridge</td><td>0x4E017822E77e34842b71b8A24b09e6E490FACA13<br><a href="https://www.teloscan.io/address/0x4E017822E77e34842b71b8A24b09e6E490FACA13">view on telosscan</a></td><td>Public contract that allows callers to bridge funds over to Ethereum</td></tr></tbody></table>

### IOTA contracts

<table><thead><tr><th width="200">Name</th><th width="297">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonVortex</td><td>0xe4816658ad10bF215053C533cceAe3f59e1f1087<br><a href="https://explorer.evm.iota.org/address/0xe4816658ad10bF215053C533cceAe3f59e1f1087">view on iota explorer</a></td><td>Dutch auction contract that receives Carbon DeFi fees and allows public interactions.</td></tr><tr><td>CarbonVortexBridge</td><td>0x7fC12ab5823b8977803F009A36ea21C9b4e17F06<br><a href="https://explorer.evm.iota.org/address/0x7fC12ab5823b8977803F009A36ea21C9b4e17F06?tab=txs">view on iota explorer</a></td><td>Public contract that allows callers to bridge funds over to Ethereum</td></tr></tbody></table>


# Testnet Contracts

### Sepolia contracts

<table><thead><tr><th width="193">Name</th><th width="298">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonController</td><td>0x5bCA3389786385a35bca14C2D0582adC6cb2482e<br><a href="https://sepolia.etherscan.io/address/0x5bCA3389786385a35bca14C2D0582adC6cb2482e">view on sepoliascan</a></td><td>This contract serves as the entry point for all interactions with Carbon DeFi.</td></tr><tr><td>Voucher</td><td>0x59f21012B2E9BA67ce6a7605E74F945D0D4C84EA<br><a href="https://sepolia.etherscan.io/address/0x59f21012B2E9BA67ce6a7605E74F945D0D4C84EA">view on sepoliascan</a></td><td>This is the Carbon DeFi strategy NFT. </td></tr><tr><td>CarbonVortex</td><td>0x3e67D217325a7298C3F80385E9f9EFf2DC0F5DE1<br><a href="https://sepolia.etherscan.io/address/0x3e67D217325a7298C3F80385E9f9EFf2DC0F5DE1">view on sepoliascan</a></td><td>Dutch auction contract that receives Carbon Defi fees and allows public interactions.</td></tr></tbody></table>

### TAC (SPB) contracts

<table><thead><tr><th width="193">Name</th><th width="298">Address</th><th>Description</th></tr></thead><tbody><tr><td>CarbonController</td><td>0xe4816658ad10bF215053C533cceAe3f59e1f1087<br></td><td>This contract serves as the entry point for all interactions with Carbon DeFi.</td></tr><tr><td>Voucher</td><td>0xA4682A2A5Fe02feFF8Bd200240A41AD0E6EaF8d5<br></td><td>This is the Carbon DeFi strategy NFT. </td></tr></tbody></table>


# CarbonController Functions

This section will explain how to interact with the Carbon DeFi contract.&#x20;

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td></td><td>Write Functions</td><td></td><td><a href="/pages/yOleTwif38lWHDkYBHu1">/pages/yOleTwif38lWHDkYBHu1</a></td></tr><tr><td></td><td>Read Functions</td><td></td><td><a href="/pages/5ehgoXPslbiIOZhTXCGP">/pages/5ehgoXPslbiIOZhTXCGP</a></td></tr><tr><td></td><td>Data &#x26; Events</td><td></td><td><a href="/pages/ZMreMapbQMns73fIe7lm">/pages/ZMreMapbQMns73fIe7lm</a></td></tr></tbody></table>


# Write Functions

{% hint style="success" %}
The [Carbon DeFi SDK](/developer-guides/carbon-defi-sdk) simplifies the process, and is highly recommended.&#x20;
{% endhint %}

This section will group and organize all `write` functions that can trigger transactions against the Carbon DeFi contract.&#x20;

Important to note that all information that is needed for all `write` functions is visible and available on-chain, however, it is **highly recommended** to use the [SDK](/developer-guides/carbon-defi-sdk) to simplify the interaction and data collection processes.&#x20;


# Transaction Prerequisites

Before interacting with any blockchain smart contract, approval must be granted by the user for use of their tokens.&#x20;

The options to grant approval include:

* [approve()](/contracts-and-functions/carboncontroller-functions/write-functions/transaction-prerequisites/approve-allowance)
* [allowance()](/contracts-and-functions/carboncontroller-functions/write-functions/transaction-prerequisites/approve-allowance)


# approve() / allowance()

### approve() / allowance()

Allowance functions give permission to a contract to withdraw tokens directly from your wallet.&#x20;

Approval or allowance must be executed prior to any other transaction on Carbon DeFi.&#x20;

[Read more about the approve and allowance functionality ](https://eips.ethereum.org/EIPS/eip-2612)


# Trade

Carbon DeFi allows trading between any token pair with active orders.&#x20;

Trading on Carbon DeFi is similar to other decentralized exchanges (DEXes). Users specify the tokens they want to trade, and see the expected results before executing a transaction. Carbon DeFi supports native ETH, wrapped ETH (wETH), USDC, USDT, wBTC, BNT and all other standard ERC20 tokens.

Carbon DeFi includes two functions for trading that enable user flexibility:  &#x20;

1. [tradeBySourceAmount](/contracts-and-functions/carboncontroller-functions/write-functions/trade/tradebysourceamount): where the user nominates an amount of tokens to send to the smart contracts, and the smart contracts calculate an amount of tokens to send back.
2. [tradeByTargetAmount](/contracts-and-functions/carboncontroller-functions/write-functions/trade/tradebytargetamount): where the user nominates an amount of tokens to receive from the smart contracts, and the smart contracts calculate an amount of tokens for the user to send.  &#x20;

{% hint style="danger" %}
Only standard ERC20 tokens are supported \
(rebase, fee-on-transfer etc are not supported)
{% endhint %}

{% hint style="success" %}
While all required data is available on-chain, it is recommended to use the [Carbon DeFi SDK](/developer-guides/carbon-defi-sdk).
{% endhint %}


# tradeBySourceAmount()

{% hint style="info" %}
The function parameters must include the list of orders (tradeActions) to interact with.&#x20;

**Using the SDK is highly recommended.** See [Performing Trades](/developer-guides/carbon-defi-sdk/interacting-with-the-sdk/performing-trades) for details.&#x20;
{% endhint %}

### Function **tradeBySourceAmount()**

This function will trade the exact amount of indicated **source** tokens for as many **target** tokens as possible.&#x20;

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function tradeBySourceAmount(
        Token sourceToken,
        Token targetToken,
        TradeAction[] calldata tradeActions,
        uint256 deadline,
        uint128 minReturn
    ) external payable nonReentrant whenNotPaused returns (uint128) 
```

{% endcode %}

### **Function Arguments**

<table><thead><tr><th width="196">Name</th><th width="168.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>sourceToken</td><td>Token address</td><td>The source token address</td></tr><tr><td>targetToken</td><td>Token address</td><td>The target token address</td></tr><tr><td>tradeActions</td><td>list</td><td>This is a list of TradeAction objects, each of which  contain the <strong>strategyId</strong> and <strong>amount</strong> of source tokens to trade into the strategy</td></tr><tr><td>deadline</td><td>uint256</td><td>Unix timestamp after which the transaction will revert</td></tr><tr><td>minReturn</td><td>uint128</td><td>The minimum amount of target tokens that must be received for the transaction to not revert</td></tr></tbody></table>

{% hint style="warning" %}
tradeAction`amount`needs to follow the relevant token decimal. \
tradeBySourceAmount, follows the sourceToken decimals
{% endhint %}

### Example

{% code overflow="wrap" %}

```solidity
tradeBySourceAmount(
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, //source token
0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C, //target token
[{59, 1600000000000000000}, {72, 3140000000000000000}], //array of tradeActions [{strategyId, amount},{strategyId, amount}...]
1675680190, //deadline
5320000000000000000 //minReturn
)
```

{% endcode %}

{% hint style="success" %}
While all required data is available on-chain, it is recommended to use the [Carbon DeFi SDK](/developer-guides/carbon-defi-sdk).
{% endhint %}

{% hint style="info" %}
To trade directly with the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# tradeByTargetAmount()

{% hint style="info" %}
The function parameters must include the list of orders (tradeActions) to interact with.&#x20;

**Using the SDK is highly recommended.** See [Performing Trades](/developer-guides/carbon-defi-sdk/interacting-with-the-sdk/performing-trades) for details.&#x20;
{% endhint %}

### Function **tradeByTargetAmount()**

This function will trade to receive the exact amount of indicated **target** tokens for as few **source** tokens as possible.&#x20;

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function tradeByTargetAmount(
        Token sourceToken,
        Token targetToken,
        TradeAction[] calldata tradeActions,
        uint256 deadline,
        uint128 maxInput
    ) external payable nonReentrant whenNotPaused onlyProxyDelegate returns (uint128)
```

{% endcode %}

### **Function Arguments**

<table><thead><tr><th width="196">Name</th><th width="147.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>sourceToken</td><td>Token</td><td>The source token address</td></tr><tr><td>targetToken</td><td>Token</td><td>The target token address</td></tr><tr><td>tradeActions</td><td>list</td><td>This is a list of TradeAction objects, each of which  contain the <strong>strategyId</strong> and <strong>amount</strong> of target tokens to <strong>receive</strong> from the strategy. </td></tr><tr><td>deadline</td><td>uint256</td><td>Unix timestamp after which the transaction will revert</td></tr><tr><td>maxInput</td><td>uint128</td><td>The maximum amount of source tokens you are willing to spend (use) for the transaction to result in the requested targetToken amount and not revert</td></tr></tbody></table>

{% hint style="warning" %}
tradeAction `amount` need to follow the relevant token decimal. \
tradeByTargetAmount, follows the targetToken decimals
{% endhint %}

### Example

{% code overflow="wrap" %}

```solidity
tradeByTargetAmount(
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, //source token
0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C, //target token
[{59, 1600000000000000000}, {72, 3140000000000000000}], //array of tradeActions [{strategyId, amount},{strategyId, amount}...]
1675680190, //deadline
5320000000000000000 //maxInput
)
```

{% endcode %}

{% hint style="success" %}
While all required data is available on chain, it is recommended to use the [Carbon DeFi SDK](/developer-guides/carbon-defi-sdk).
{% endhint %}

{% hint style="info" %}
To trade directly with the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# Strategy Management

Every strategy on Carbon DeFi comprises two reciprocal connected Orders. Each Order is a standing offer to trade one token for another, at a set price or price range.  For example in a Strategy with one Order to sell WBTC to buy ETH, the other order would be to sell ETH to buy WBTC. Note that it is also possible to create disposable strategies that function as a one-way limit order.&#x20;

Each Order describes the prices and budget for selling/buying the tokens.&#x20;

The following Strategy functions are available:

* [**createStrategy:**](/contracts-and-functions/carboncontroller-functions/write-functions/strategy-management/createstrategy) Use this to create a new strategy.
* [**updateStrategy:**](/contracts-and-functions/carboncontroller-functions/write-functions/strategy-management/updatestrategy) Use this to change an existing strategy.
* [**deleteStrategy:**](/contracts-and-functions/carboncontroller-functions/write-functions/strategy-management/deletestrategy) Use this to remove a strategy and receive the tokens inside it.&#x20;

{% hint style="success" %}
While all required data is available on chain, it is recommended to use the [Carbon DeFi SDK](/developer-guides/carbon-defi-sdk).
{% endhint %}

{% hint style="info" %}
Each token must be approved for use prior to creating a strategy. See [approve() / allowance()](/contracts-and-functions/carboncontroller-functions/write-functions/transaction-prerequisites/approve-allowance) for details.&#x20;
{% endhint %}


# createStrategy()

{% hint style="danger" %}
Only standard ERC20 tokens are supported \
(rebase, fee-on-transfer etc are not supported)
{% endhint %}

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function createStrategy(
        Token token0,
        Token token1,
        Order[2] calldata orders
    ) external payable nonReentrant whenNotPaused onlyProxyDelegate returns (uint256)
```

{% endcode %}

This function is used to create a strategy on Carbon DeFi. Each strategy must include two linked orders.&#x20;

### **Function Arguments**

<table><thead><tr><th width="171">Name</th><th width="159.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>token0</td><td>Token</td><td>The first token in the strategy. Order0 will be referring to selling this token for token1. <br>(The Carbon DeFi UI will use this as "<a href="https://www.investopedia.com/terms/b/basecurrency.asp">Base</a>" token)</td></tr><tr><td>token1</td><td>Token</td><td>The second token in the strategy. <br>Order1 will be referring to selling this token for token0. <br>(The Carbon DeFi UI will use this as "<a href="https://www.investopedia.com/terms/q/quotecurrency.asp">Quote</a>" token)</td></tr><tr><td>orders</td><td>array</td><td>This is an array of two Order objects. Each order contains the following:<br><strong>y: uint128</strong> The amount of tokens deposited into the order.<br><strong>z: uint128</strong>  The y intercept of the order, which is used to calculate the marginal price.<br><strong>A: uint64</strong> Price range (width) parameter, encoded. <br><strong>B: uint64</strong> Price range (edge) parameter, encoded.  </td></tr></tbody></table>

### Example

{% code overflow="wrap" %}

```solidity
createStrategy(
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, //token0 ETH
0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, //token1 USDC
[{y, z, A, B}, // order0, selling token0 (ETH) for token1 (USDC)
{y, z, A, B}], // order1, selling token1 (USDC) for token0 (ETH)
)

// In the Carbon DeFi UI, this will appear with rates in units of ETH per USDC. 
```

{% endcode %}

### Returns

This function returns the assigned id of the strategy.

### Important notes

{% hint style="success" %}

* While all required data is available on chain, it is recommended to use the [Carbon DeFi SDK](/developer-guides/carbon-defi-sdk).
* *Due to input value normalization and memory restrictions, the order parameters stored on chain might be slightly different than those \`input\` via the UI and/or the SDK.*&#x20;
  {% endhint %}

### Example

```
//user inputs

{
    'liquidity'    : 759250124,
    'lowestRate'   : 309485009821345068724781056.000000000000000000000,
    'highestRate'  : 309485009821345068724781056.000000000014551915228,
    'marginalRate' : 309485009821345068724781056.000000000000000000019
}

//encoded order

{
    'y': 759250124, 
    'z': 759250124, 
    'A': 0, 
    'B': 12807111440334848
}

//decoded order

{
    'liquidity'    : 759250124,
    'lowestRate'   : 309485009821345068724781056,
    'highestRate'  : 309485009821345068724781056,
    'marginalRate' : 309485009821345068724781056
}

```

{% hint style="info" %}
To create a strategy with the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# updateStrategy

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function updateStrategy(
        uint256 strategyId,
        Order[2] calldata currentOrders,
        Order[2] calldata newOrders
    ) external payable nonReentrant whenNotPaused greaterThanZero(strategyId) onlyProxyDelegate 
```

{% endcode %}

This function is used to make changes to a strategy on Carbon DeFi, such as adding or removing liquidity, pausing/unpausing, changing trade rates, etc.&#x20;

### **Function Arguments**

<table><thead><tr><th width="162">Name</th><th width="114.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>strategyId</td><td>uint256</td><td>The ID of the strategy to update.</td></tr><tr><td>currentOrders</td><td>array</td><td>This is the current values of the order being edited. This is included to verify the state of the order before changing it, ensuring it's being updated from the expected state. This safeguard prevents editing an order right after it was changed due to trades. </td></tr><tr><td>newOrders</td><td>array</td><td>This is an array of the new Order objects, with their updated parameters, exactly the same as the object in <strong>createStrategy</strong>. <br><br>Each order contains the following:<br><strong>y: uint128</strong> The amount of tokens deposited into the order.<br><strong>z: uint128</strong>  The y intercept of the order.<br><strong>A: uint64</strong> Price range (width) parameter. <br><strong>B: uint64</strong> Price range (edge) parameter.  </td></tr></tbody></table>

### Example

{% code overflow="wrap" %}

```solidity
updateStrategy(
712, //strategyId
[{y, z, A, B},{y, z, A, B}], //current orders
[{y, z, A, B},{y, z, A, B}] // updated orders
)
```

{% endcode %}

{% hint style="success" %}
While all required data is available on chain, it is recommended to use the [Carbon DeFi SDK](/developer-guides/carbon-defi-sdk).
{% endhint %}

{% hint style="info" %}
To create a strategy with the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# deleteStrategy()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function deleteStrategy(uint256 strategyId) 
        external 
        nonReentrant 
        whenNotPaused 
        onlyProxyDelegate
```

{% endcode %}

This function is used to delete a strategy on Carbon DeFi. Once removed, all liquidity associated to the strategy is sent to the strategy owner's wallet.&#x20;

### **Function Arguments**

<table><thead><tr><th width="149">Name</th><th width="191.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>strategyId</td><td>uint256</td><td>The ID of the strategy to delete.</td></tr></tbody></table>

### Example

```solidity
deleteStrategy(
2381976568446569244243622252022377480199 //strategyId
) // Only the strategy owner can delete the strategy
```

{% hint style="success" %}
While all required data is available on chain, it is recommended to use the [Carbon DeFi SDK](/developer-guides/carbon-defi-sdk).
{% endhint %}


# Read Functions

This section will group and organize all `read` functions that can be used to collect data and information from the Carbon DeFi contract.&#x20;

{% hint style="info" %}
Important to note that the SDK has access to all relevant required information for creating and building `write` transactions.&#x20;
{% endhint %}


# controllerType()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function controllerType() external view returns (uint16);
```

{% endcode %}

This function returns a number indicating the controller type.


# tradingFeePPM()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function tradingFeePPM() external view returns (uint32);
```

{% endcode %}

This function returns the network default trading fee, represented in PPM (parts per million). However, every pair might have a custom fee setting for it, so it is advised to follow the process outlined in [pairTradingFeePPM()](/contracts-and-functions/carboncontroller-functions/read-functions/pairtradingfeeppm) function.

For example a PPM of 2,000 represents a 0.2% trading fee:&#x20;

2,000 / 1,000,000 = 0.002 = 0.2%

{% hint style="danger" %}
To operate with accurate fee values, please use the [pairTradingFeePPM()](/contracts-and-functions/carboncontroller-functions/read-functions/pairtradingfeeppm) function.
{% endhint %}


# pairTradingFeePPM()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function pairTradingFeePPM(Token token0, Token token1) external view returns (uint32);
```

{% endcode %}

This function returns the fee settings for a specific pair, represented in PPM (parts per million). It is recommended to identify the trading fee for the required pair to ensure the fee considerations are correctly represented to the user.

**Function Arguments**

<table><thead><tr><th width="175">Name</th><th width="142.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>token0</td><td>Token</td><td>The first token address. </td></tr><tr><td>token1</td><td>Token</td><td>The second token address.</td></tr></tbody></table>

{% hint style="info" %}
Querying the network fee for the token0/token1 pair will return the same result as querying the token1/token0 pair.
{% endhint %}

### Returns

Fee percentage in PPM

For example a PPM of 1000 represents a 0.1% trading fee:&#x20;

1000 / 1,000,000 = 0.001 = 0.1%

{% hint style="info" %}
If the pair has a customFee, the response would represent this value. Otherwise, the return would represent the default fee on the system.
{% endhint %}

### Example

<pre><code>pairTradingFeePPM(
 0x514910771AF9Ca656af840dff83E8264EcF986CA, //token0
 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE //token1
)

// Returns:
//   FeePPM; //1000 which represents 0.1%
<strong>// }
</strong></code></pre>


# pair()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function pair(Token token0, Token token1) external view returns (Pair memory);
```

{% endcode %}

This function is used to get the metadata for the pair of the indicated tokens. This includes the ID of the pair, token0, and token1.&#x20;

### **Function Arguments**

<table><thead><tr><th width="175">Name</th><th width="142.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>token0</td><td>Token</td><td>The first token address. </td></tr><tr><td>token1</td><td>Token</td><td>The second token address.</td></tr></tbody></table>

### Returns

This function returns a Pair object, containing the pair ID and the addresses of token0 and token1.

<table><thead><tr><th width="187">Name</th><th width="118.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>uint256</td><td>The ID of the pair </td></tr><tr><td>token0</td><td>Token</td><td>The first token address </td></tr><tr><td>token1</td><td>Token</td><td>The second token address</td></tr></tbody></table>

### Example

<pre><code>pair(
 0x514910771AF9Ca656af840dff83E8264EcF986CA, //token0
 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE //token1
)

// Returns:
// struct Pair {
//    uint128 id;
//    Token[2] tokens;
<strong>// }
</strong></code></pre>

{% hint style="info" %}
For the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# pairs()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function pairs() external view returns (Token[2][] memory)
```

{% endcode %}

This function returns a list of all initialized token pairs.

### Example

{% code overflow="wrap" %}

```solidity
// Returns:
[
[0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, 0x514910771AF9Ca656af840dff83E8264EcF986CA],  
[0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, 0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C]
]
```

{% endcode %}

{% hint style="info" %}
For the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# strategy()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function strategy(uint256 id) external view returns (Strategy memory);
   
```

{% endcode %}

This function is used to get details about a strategy, specified by its ID.&#x20;

### **Function Arguments**

<table><thead><tr><th width="127">Name</th><th width="209.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>uint256</td><td>The ID of the strategy</td></tr></tbody></table>

### **Returns**

This function returns details about the specified strategy.

<table><thead><tr><th width="128">Name</th><th width="136.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>uint256</td><td>The ID of the strategy</td></tr><tr><td>owner</td><td>address</td><td>The address of the owner of the strategy</td></tr><tr><td>tokens</td><td>array</td><td>An array containing the addresses of token0 and token1</td></tr><tr><td>orders</td><td>array</td><td>An array containing the order objects that specify the parameters of each order contained by the strategy</td></tr></tbody></table>

### Example

```
strategy(
 888 //strategy id
)

// returns 
// struct Strategy {
//    uint256 id;
//    address owner;
//    Token[2] tokens;
//    Order[2] orders;
// }

// [{y, z, A, B},{y, z, A, B}], // orders
```


# strategiesByPair()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
   function strategiesByPair(
        Token token0,
        Token token1,
        uint256 startIndex,
        uint256 endIndex
    ) external view returns (Strategy[] memory)
```

{% endcode %}

This function is used to obtain a list of strategies for the specified token pair.&#x20;

### **Function Arguments**

<table><thead><tr><th>Name</th><th width="138.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>token0</td><td>Token</td><td>The address of the first token in the pair</td></tr><tr><td>token1</td><td>Token</td><td>The address of the second token in the pair</td></tr><tr><td>startIndex</td><td>uint256</td><td>Index of first strategy to view</td></tr><tr><td>endIndex</td><td>uint256</td><td>Index of last strategy to view</td></tr></tbody></table>

### Returns

This function returns a list of strategy objects containing details for strategies from the specified token pair.&#x20;

### Example

```
strategiesByPairl(
 0x514910771AF9Ca656af840dff83E8264EcF986CA, //token0
 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, //token1
 0, //startIndex
 25, //endIndex
)

// returns
// [(Strategy), (Strategy), (Strategy)]

// struct Strategy {
//    uint256 id;
//    address owner;
//    Token[2] tokens;
//    Order[2] orders;
// }

// Order objects:
//        [
//            Order({
//                y: uint128,
//                z: uint128,
//                A: uint64,
//                B: uint64
//            }),
//            Order({
//                y: uint128),
//                z: uint128,
//                A: uint64,
//                B: uint64
//            })
//        ]
```


# strategiesByPairCount()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function strategiesByPairCount(Token token0, Token token1) external view returns (uint256)
```

{% endcode %}

This function is used to get the number of strategies for the specified token pair.

### **Function Arguments**

<table><thead><tr><th>Name</th><th width="147.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>token0</td><td>Token</td><td>The token address of the first token in the pair </td></tr><tr><td>token1</td><td>Token</td><td>The token address of the second token in the pair</td></tr></tbody></table>

### Returns

This function returns the number of strategies that exist for the specified token pair.

### Example

```
strategiesByPairCount(
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, //token0
0x514910771AF9Ca656af840dff83E8264EcF986CA, //token1
)

// returns
// 612
```

{% hint style="info" %}
For the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# calculateTradeSourceAmount()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function calculateTradeSourceAmount(
        Token sourceToken,
        Token targetToken,
        TradeAction[] calldata tradeActions
    ) external view returns (uint128);
   
```

{% endcode %}

This function is used to get the number of target tokens that would be received by trading the indicated number of source tokens.

### **Function Arguments**

<table><thead><tr><th width="175">Name</th><th width="116.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>sourceToken</td><td>Token</td><td>The address of the token being swapped into the trade</td></tr><tr><td>targetToken</td><td>Token</td><td>The address of the token received from the trade</td></tr><tr><td>tradeActions</td><td>array</td><td>The list of TradeAction objects that specify the route of the trade. <br><br>The TradeAction object contains the strategy ID of the strategy that is being swapped into, and the number of tokens being swapped in<br><br>For example:<br>{712,<br>1500000000000000000}</td></tr></tbody></table>

### Returns

This returns the number of target tokens expected to be returned by the specified trade.&#x20;

### Example

```
tradeSourceAmount(
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, //token0
0x514910771AF9Ca656af840dff83E8264EcF986CA, //token1
[(712,1500000000000000000), (615, 2300000000000000000)] // TradeAction (id, amount)
)

// Return
// 7300000000000000000
```

{% hint style="info" %}
For the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# calculateTradeTargetAmount()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    function calculateTradeTargetAmount(
        Token sourceToken,
        Token targetToken,
        TradeAction[] calldata tradeActions
    ) external view returns (uint128);
```

{% endcode %}

This function is used to get the number of source tokens that would be required to trade to receive the indicated number of target tokens.

### **Function Arguments**

<table><thead><tr><th>Name</th><th width="116.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>sourceToken</td><td>Token</td><td>The address of the token being swapped into the trade</td></tr><tr><td>targetToken</td><td>Token</td><td>The address of the token received from the trade</td></tr><tr><td>tradeActions</td><td>array</td><td>The list of TradeAction objects that specify the route of the trade <br><br>The TradeAction object contains the strategy ID of the strategy that is being swapped into, and the number of tokens being swapped in.<br><br>For example:<br>{712,<br>1500000000000000000}</td></tr></tbody></table>

### Returns

This returns the number of **source** tokens expected to be returned by the specified trade.&#x20;

### Example

```
tradeTargetAmount(
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, //token0
0x514910771AF9Ca656af840dff83E8264EcF986CA, //token1
[{712,1500000000000000000}, {615, 2300000000000000000}] // TradeAction {id, amount}
)

// Return
// 7300000000000000000 source tokens
```

{% hint style="info" %}
For the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# Data & Events

Carbon DeFi emits events for each of its primary user-functions to support ongoing event listening for data aggregation. <br>


# TradingFeePPMUpdated()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    event TradingFeePPMUpdated(uint32 prevFeePPM, uint32 newFeePPM);
```

{% endcode %}

This event indicates when the trading fee, in parts-per-million, is updated.&#x20;

### Event Parameters

| Name       | Type   | Description              |
| ---------- | ------ | ------------------------ |
| prevFeePPM | uint32 | The previous trading fee |
| newFeePPM  | uint32 | The new trading fee      |


# PairCreated()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    emit PairCreated(id, sortedTokens[0], sortedTokens[1]);
        return Pair({ id: id, tokens: sortedTokens });
    }
```

{% endcode %}

This event indicates when a new token pair is created.&#x20;

### Event Parameters

| Name             | Type    | Description                   |
| ---------------- | ------- | ----------------------------- |
| id               | uint128 | The id of the pair.           |
| sortedTokens\[0] | address | The first token in the pair.  |
| sortedTokens\[1] | address | The second token in the pair. |


# StrategyCreated()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
   event StrategyCreated(
        uint256 id,
        address indexed owner,
        Token indexed token0,
        Token indexed token1,
        Order order0,
        Order order1
    );
```

{% endcode %}

This event is emitted when a new strategy is created.&#x20;

### Event Parameters

| Name   | Type    | Description                                          |
| ------ | ------- | ---------------------------------------------------- |
| id     | uint256 | The incrementally assigned id number of the strategy |
| owner  | address | The address of the owner of the strategy             |
| token0 | Token   | The first token in the strategy                      |
| token1 | Token   | The second token in the strategy                     |
| order0 | Order   | The first Order object in the strategy.              |
| order1 | Order   | The second Order object in the strategy.             |

```
// {y, z, A, B} order
```


# StrategyDeleted()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
   event StrategyDeleted(
        uint256 id,
        address indexed owner,
        Token indexed token0,
        Token indexed token1,
        Order order0,
        Order order1
    );
```

{% endcode %}

This event is emitted when a strategy is deleted.&#x20;

### Event Parameters

| Name   | Type    | Description                                          |
| ------ | ------- | ---------------------------------------------------- |
| id     | uint256 | The incrementally assigned id number of the strategy |
| owner  | address | The address of the owner of the strategy             |
| token0 | Token   | The first token in the strategy                      |
| token1 | Token   | The second token in the strategy                     |
| order0 | Order   | The first Order object in the strategy.              |
| order1 | Order   | The second Order object in the strategy.             |

```
// {y, z, A, B} order
```


# StrategyUpdated()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
    event StrategyUpdated(
        uint256 indexed id,
        Token indexed token0,
        Token indexed token1,
        Order order0,
        Order order1,
        uint8 reason
    );
```

{% endcode %}

This event is emitted when the parameters of a strategy are changed.

### Event Parameters

| Name   | Type    | Description                                                            |
| ------ | ------- | ---------------------------------------------------------------------- |
| id     | uint256 | The incrementally assigned id number of the strategy                   |
| token0 | Token   | The first token in the strategy                                        |
| token1 | Token   | The second token in the strategy                                       |
| order0 | Order   | The first Order object in the strategy. See below for details.         |
| order1 | Order   | The second Order object in the strategy. See below for details.        |
| reason | unit8   | Indicating if the update is a result of a user update (0) or trade (1) |

```
// {y, z, A, B} order
```


# TokensTraded()

{% code title="CarbonController.sol" overflow="wrap" lineNumbers="true" %}

```solidity
   event TokensTraded(
        address indexed trader,
        address indexed sourceToken,
        address indexed targetToken,
        uint256 sourceAmount,
        uint256 targetAmount,
        uint128 tradingFeeAmount,
        bool byTargetAmount
    );
```

{% endcode %}

This event is emitted when tokens are traded into one or more strategies.

### Event Parameters

| Name             | Type    | Description                                                                                                                                                                            |
| ---------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| trader           | address | The address that performed the trade.                                                                                                                                                  |
| sourceToken      | address | The token traded from.                                                                                                                                                                 |
| targetToken      | address | The token traded to.                                                                                                                                                                   |
| sourceAmount     | uint256 | The number of source tokens traded.                                                                                                                                                    |
| targetAmount     | uint256 | The number of target tokens received.                                                                                                                                                  |
| tradingFeeAmount | uint128 | The number of tokens earned by Carbon DeFi as a fee.                                                                                                                                   |
| byTargetAmount   | bool    | <p><strong>True:</strong> the trade was done using the tradeByTargetAmount() function. </p><p><strong>False:</strong> the trade was done using the tradeBySourceAmount() function.</p> |


# FeesWithdrawn()

{% code title="" overflow="wrap" %}

```solidity
    event FeesWithdrawn
    (Token indexed token, address indexed recipient, uint256 indexed amount, address sender);


```

{% endcode %}

This event is emitted when fees are withdrawn.

### Event Parameters

| Name      | Type    | Description                             |
| --------- | ------- | --------------------------------------- |
| token     | address | The token in which fees were withdrawn. |
| recipient | address | The address of the fee receiver.        |
| amount    | uint256 | The number of tokens.                   |
| sender    | address | The address of the sender.              |


# CarbonVortex Functions

Carbon DeFi generates protocol fees on each chain its deployed in two primary ways: on the taker side through orders being taken by traders on the Carbon DeFi protocol, and through arbitrage transactions powered by Bancor’s integrated Arb Fast Lane.

Taker fees from user trades are collected directly via Carbon DeFi. In parallel, the Arb Fast Lane performs chain-wide arbitrage and collects additional fees via its smart contracts. These combined fees are transferred into the Carbon Vortex contract, where they are made available for purchase through a Dutch auction pricing model.

These are popular flows that can be achieved using the Carbon Vortex:

### Trigger Execute() for caller rewards

The Carbon Vortex allows any user to check the available token balances and trigger a function to process them, with an incentive.

The caller can follow these steps to complete the process:

1. Identify the size of opportunity - call the `[read] availableTokens()` function to learn how many tokens are available to process.
2. Read the reward percentage - call the `[read] rewardsPPM()` function to learn what is the reward percentage and threshold&#x20;
3. Execute the transaction - call the `[write] execute()` function to receive caller rewards

### Trigger Trade() to interact with an active dutch auction

The Carbon Vortex offers tokens up for sale in a gradually descending price discovery flow known as Dutch auction. Any caller can identify and take opportunities when they occur.&#x20;

1. Identify the available amount of tokens for sale by calling the `[read]amountAvailableForTrading` function
2. Identify the current price by calling any of the following functions `[read] expectedTradeInput, expectedTradeReturn, tokenPrice`
3. Execute the trade by calling the `trade` function

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td></td><td>Write Functions</td><td></td><td><a href="/pages/mOdPqhck2uvSO8SMnEH4">/pages/mOdPqhck2uvSO8SMnEH4</a></td></tr><tr><td></td><td>Read Functions</td><td></td><td><a href="/pages/7d0gHdREcmewAXfulWOx">/pages/7d0gHdREcmewAXfulWOx</a></td></tr><tr><td></td><td>Data &#x26; Events</td><td></td><td><a href="/pages/gD5AtYIwwRtI1TBKGkfo">/pages/gD5AtYIwwRtI1TBKGkfo</a></td></tr></tbody></table>


# Write Functions

This section will group and organize all `write` functions that can trigger transactions against the Carbon Vortex contract.&#x20;

Carbon Vortex contract offers a permissionless way to initiate Dutch auctions on fees collected on the Carbon DeFi contracts. It offers users a public function that allows them to trade this liquidity for a single token, ensuring a transparent and efficient exchange process.


# trade()

```solidity
    function trade(Token token, uint128 targetAmount) external payable;
```

This function will allow anyone to trade the existing tokens held by the contract at the indicated price available in the contract at the moment of execution.&#x20;

Currently, ETH is paired with BNT while all other tokens are paired with ETH.

{% hint style="info" %}
It is recommended to first identify the current price using the relevant [read functions](/contracts-and-functions/carbonvortex-functions/read-functions)
{% endhint %}

### **Function Arguments**

<table><thead><tr><th width="162">Name</th><th width="114.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>token</td><td>Token</td><td>The token address of the token you would like to trade out of the contract</td></tr><tr><td>targetAmount</td><td>uint128</td><td>The amount of target tokens you would like to trade out of the contract</td></tr></tbody></table>

### Example

{% code overflow="wrap" %}

```solidity
trade(
0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c, //token address
1000000000000000000000 //token amount indicated in the token wei 
)
```

{% endcode %}

During function execution, the required source token amount would be deducted from the caller wallet in return for the target token amount the caller is asking to trade out of the contract.

{% hint style="warning" %}
Approve is required for this transaction
{% endhint %}


# execute()

{% code overflow="wrap" %}

```solidity
    function execute(Token[] calldata tokens) external
```

{% endcode %}

This `write` function allows any caller to process all available token amounts collected by Carbon DeFi and Arb Fast Lane activities and receive the caller incentives.

The function will process all token amounts in `carbonController` AND the `carbonVortex` contract balance ([view availableTokens](/contracts-and-functions/carbonvortex-functions/read-functions/availabletokens)).

### **Function Arguments**

<table><thead><tr><th>Name</th><th width="192.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>tokens</td><td>List</td><td>The list of token addresses of the token. Input can be a single token, or an array of addresses.</td></tr></tbody></table>

### Example

```solidity
execute(
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE // token
)
```

{% hint style="info" %}
For the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# Read Functions

This section will group and organize all `read` functions that are available under the Carbon Vortex contract.&#x20;

<br>


# amountAvailableForTrading()

{% code overflow="wrap" %}

```solidity
    function amountAvailableForTrading(Token token) external view returns (uint128);
```

{% endcode %}

This function is used to identify the amount of tokens currently available for sale for the token.

### **Function Arguments**

<table><thead><tr><th>Name</th><th width="246.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>token</td><td>Token</td><td>The address of the token.</td></tr></tbody></table>

### Returns

This returns the amount of tokens that are available for sale.

### Example

```solidity
accumulatedFees(
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE // token
)

// Return the value in WEI format
// 11039415659335871026  
```

{% hint style="info" %}
For the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# availableTokens()

{% code overflow="wrap" %}

```solidity
    function availableTokens(address token) external view returns (uint256);
```

{% endcode %}

This function is used to identify the amount of fees accumulated in the specified token. The returned amount is the sum of tokens from both the `carbonController` and `carbonVortex`.

### **Function Arguments**

<table><thead><tr><th>Name</th><th width="186.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>token</td><td>Token</td><td>The address of the token.</td></tr></tbody></table>

### Returns

This returns the amount of fees accumulated by the protocol for the specified token.

### Example

```solidity
accumulatedFees(
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE // token
)

// Return
// 415000000000000000000 fees
```

{% hint style="info" %}
For the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# expectedTradeInput()

{% code overflow="wrap" %}

```solidity
    function expectedTradeInput(Token token, uint128 targetAmount) external view returns (uint128 sourceAmount);
```

{% endcode %}

Using this function, one can query the contract indicating the target token amount they would like to receive, and receive an indication of the expected source token amount required.&#x20;

Note that since the rate changes over time, the required amount might reduce with time as the price changes.

### **Function Arguments**

<table><thead><tr><th width="162">Name</th><th width="114.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>token</td><td>Token</td><td>The token address of the token you would like to trade out of the contract</td></tr><tr><td>targetAmount</td><td>uint128</td><td>The amount of target tokens you would like to receive at the end of the trade</td></tr></tbody></table>

### Example

{% code overflow="wrap" %}

```solidity
expectedTradeInput(
0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c, //token address
4027872880331900000000 //target amount indicated in wei
)
returns (
1000000000000000000 //the required amount of source tokens indicated in wei
)
```

{% endcode %}


# expectedTradeReturn()

{% code overflow="wrap" %}

```solidity
    function expectedTradeReturn(Token token, uint128 sourceAmount) external view returns (uint128 targetAmount);
```

{% endcode %}

Using this function, one can query the contract indicating the source token amount they would like to use, and receive an indication of the expected target token amount.&#x20;

Note that since the rate changes over time, the target amount of tokens might grow with time as the price changes.

### **Function Arguments**

<table><thead><tr><th width="162">Name</th><th width="114.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>token</td><td>Token</td><td>The token address of the token you would like to trade out of the contract</td></tr><tr><td>sourceAmount</td><td>uint128</td><td>The amount of source tokens you are willing to trade out of your wallet against the indicated token</td></tr></tbody></table>

### Example

{% code overflow="wrap" %}

```solidity
expectedTradeReturn(
0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c, //token address
1000000000000000000 //source token amount indicated in wei
)
returns (
4027872880331900000000 //the returned amount of target tokens 
)
```

{% endcode %}


# finalTargetToken()

```solidity
    function finalTargetToken() external view returns (Token);
```

This function returns the token address of the "finalTargetToken". This token is the one paired with the "targetToken" for the last step of auctions.

{% hint style="info" %}
A bit about the structure:

All tokens are paired against "targetToken" to allow aggregation to a common liquid token.

There is an option that this "targetToken" will be paired against a "finalTargetToken" to allow trading the common token into a specific destination token.
{% endhint %}

### Example

{% code overflow="wrap" %}

```solidity
finalTargetToken()
returns (
    0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C  
)
```

{% endcode %}


# minTargetTokenSaleAmount()

```solidity
    function minTargetTokenSaleAmount() external view returns (uint128);
```

This function returns the minimum amount of "targetToken" that can be in the account balance before triggering a top up and price update.

{% hint style="info" %}
Once "targetToken" sale amount is below this value, it will reset the price and restart the auction
{% endhint %}

### Example

{% code overflow="wrap" %}

```solidity
minTargetTokenSaleAmount()
returns (
    10000000000000000000; 
)
```

{% endcode %}


# minTokenSaleAmount()

```solidity
    function minTokenSaleAmount(Token token) external view returns (uint128);
```

Once new funds are added to the auction using the execute() function, there is a check whether to reset the price or not.

`minTokenSaleAmount` is defined as half the contract updated balance (available for sale).

### Example

{% code overflow="wrap" %}

```solidity
minTokenSaleAmount(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)
returns (
    5215367497312276769; 
)
```

{% endcode %}


# pairDisabled()

```solidity
    function pairDisabled(Token token) external view returns (bool);
```

This function returns true/false to indicate if a token pair is disabled for trading.

### Example

{% code overflow="wrap" %}

```solidity
pairDisabled(0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C)
returns (
      false
)
```

{% endcode %}


# priceDecayHalfLife()

```solidity
    function priceDecayHalfLife() external view returns (uint32);
```

This function allows to identify what is the half life of the price decay function.

### Example

{% code overflow="wrap" %}

```solidity
priceDecayHalfLife()
returns (
864000 //the half life indicator in seconds
)
```

{% endcode %}


# rewardsPPM()

{% code overflow="wrap" %}

```solidity
    function rewardsPPM() external view returns (uint32);
```

{% endcode %}

This function returns the caller incentive rewards in PPM the caller will receive from calling the `execute()` function.

### Example

{% code overflow="wrap" %}

```solidity
// Returns:
[
20000,                   //portion in PPM
]
```

{% endcode %}

{% hint style="info" %}
For the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# targetToken()

```solidity
    function targetToken() external view returns (Token);
```

This function returns the token address of the "targetToken". This is the token all auctions will be paired with excluding the tradeToken->finalTargetToken pair.

{% hint style="info" %}
A bit about the structure:

All tokens are paired against "targetToken" to allow aggregation to a common liquid token.

There is an option that this "targetToken" will be paired against a "finalTargetToken" to allow trading the common token into a specific destination token.
{% endhint %}

### Example

{% code overflow="wrap" %}

```solidity
targetToken()
returns (
    0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE  
)
```

{% endcode %}


# targetTokenPriceDecayHalfLife()

```solidity
    function targetTokenPriceDecayHalfLife() external view returns (uint32);
```

This function allows to identify what is the half life of the price decay function for the targetToken auction.

### Example

{% code overflow="wrap" %}

```solidity
targetTokenPriceDecayHalfLife()
returns (
864000 //the half life indicator in seconds
)
```

{% endcode %}


# targetTokenSaleAmount()

```solidity
    function targetTokenSaleAmount() external view returns (SaleAmount memory);
```

This function returns the "targetToken" amount available for sale.

### Example

{% code overflow="wrap" %}

```solidity
targetTokenSaleAmount()
returns (
    10000000000000000000; 
)
```

{% endcode %}


# tokenPrice()

```solidity
    function tokenPrice(Token token) external view returns (Price memory price);
        struct Price {
        uint128 sourceAmount;
        uint128 targetAmount;
    }
```

This function allows to identify the current price of the token. Keeping in mind that the price change over time, which means that once you query the price, a moment later it would be a less as more time has passed.

### **Function Arguments**

<table><thead><tr><th width="162">Name</th><th width="114.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>token</td><td>Token</td><td>The token address of the token you would like to trade out of the contract </td></tr></tbody></table>

### Example

{% code overflow="wrap" %}

```solidity
tokenPrice(
0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 //token address
)
returns (
  {
   uint128 sourceAmount; 
   uint128 targetAmount; 
  } 
)

```

{% endcode %}

{% hint style="info" %}
To check ETH, use the following address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# totalCollected()

```solidity
    function totalCollected() external view returns (uint256);
```

This function returns the amount of tokens collected by the Carbon Vortex to date. If `finalTargetToken` is defined, this value will represent amount collected in this token, otherwise, it will represent `targetToken`.

### Example

{% code overflow="wrap" %}

```solidity
totalCollected(0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C)
returns (
      10000000000000
)
```

{% endcode %}


# tradingEnabled()

```solidity
    function tradingEnabled(Token token) external view returns (bool);
```

This function allows you to identify if the token is available for trading.

{% hint style="info" %}
Notice, all tokens are paired with "targetToken" which means the caller needs to send "targetToken" to the contract in order to receive the tokens.

However, "targetToken" might be traded against "finalTargetToken", in such case, to receive "targetToken", the caller needs to send "finalTargetToken" to the contract.
{% endhint %}

### **Function Arguments**

<table><thead><tr><th width="162">Name</th><th width="114.66666666666663">Type</th><th>Description</th></tr></thead><tbody><tr><td>token</td><td>Token</td><td>The token address of the token you would like to trade out of the contract. </td></tr></tbody></table>

### Example

{% code overflow="wrap" %}

```solidity
tradingEnabled(
0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 //token address
)
returns (
true/false //true indicates that trading is enable for this token
)
```

{% endcode %}

{% hint style="info" %}
To trade directly with the ETH token, use the contract address: *0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE*&#x20;
{% endhint %}


# CarbonVortexBridge Functions

This section will explain how to interact with the CarbonVortexBridge contract.&#x20;

{% content-ref url="/pages/ce9ek0T9YnVdiKN6H74m" %}
[Bridge()](/contracts-and-functions/carbonvortexbridge-functions/write-functions/bridge)
{% endcontent-ref %}


# Write Functions

CarbonVortexBridge includes 1 `write`  function

{% content-ref url="/pages/ce9ek0T9YnVdiKN6H74m" %}
[Bridge()](/contracts-and-functions/carbonvortexbridge-functions/write-functions/bridge)
{% endcontent-ref %}


# Bridge()

For chains that support StarGate bridge

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

```solidity
    function bridge(uint256 amount) external payable override nonReentrant returns (uint256) {
```

{% endcode %}

This function allows anyone to trigger a bridge transaction where the consolidated fees (typically in the `finalTargetToken` format) will be sent to the Ethereum blockchain.

### **Function Arguments**

<table><thead><tr><th width="196">Name</th><th width="168.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>amount</td><td>uint256</td><td>This value represents the amount of tokens to bridge over from the contract on the selected chain to Ethereum</td></tr><tr><td>bridge</td><td>uint256</td><td>This value represents the bridge fee in native gas token units</td></tr></tbody></table>

This function requires 2 values to successfully work:

1. Amount

   This value represents the amount of `finalTargetToken` you would like to bridge over. When passing the value 0, it will try to bridge the entire available amount.\
   **How to identify the available amount?**

   1. Visit the CarbonVortex contract ([follow the address in the relevant chain](/contracts-and-functions/contracts))
   2. `Read` `finalTargetToken`  to find the address of the token to bridge over (if the address is null, check `targetToken` address instead)
   3. Check the contract balance for the token address<br>
2. Bridge&#x20;

   This value represents the **bridge fee** which is required in order to pay for the 2nd transaction to claim the bridged amount on the ethereum blockchain. \
   **How to identify the required bridge fee?**\
   Different chains have different bridge implementation. Follow this step closely to find the correct value to use

#### Overview

The prove/finalize script lives in the [bancorprotocol/carbon-vortex-bridge](https://github.com/bancorprotocol/carbon-vortex-bridge) repo. Clone it and install dependencies:

{% tabs %}
{% tab title="Celo" %}

#### Completing a Celo → Ethereum Vortex Bridge Withdrawal

> <sub>Operator guide for the canonical OP-stack Celo Vortex bridge (</sub><sub>VortexOpStackBridge</sub><sub>).</sub>

#### Overview

Celo is an **OP-stack L2**, and the Vortex bridges WETH to Ethereum over the **canonical Standard Bridge**. A canonical L2→L1 withdrawal has **three on-chain steps** and an unavoidable **\~7-day** delay:

```
(L2: Celo)            (L1: Ethereum)                         (L1: Ethereum)
  1. bridge()    ──►    2. prove        ── wait ~7 days ──►    3. finalize
  burns WETH,          submits a Merkle proof of the          releases WETH to
  queues message       withdrawal to OptimismPortal2          the vault
```

* **Step 1** is a single contract write on Celo (a Celoscan "Write").
* **Steps 2 & 3** happen on Ethereum L1 and are driven by a script in the repo,&#x20;
* scripts/withdraw\.mjs (pnpm withdraw \<tx>) — the proof construction is far&#x20;
* too complex to do by hand in a block explorer.

The bridge is **permissionless** to prove/finalize: any funded EOA can run steps 2 and 3, and the WETH still lands in the vault regardless of who submits them.

***

#### Setup

The prove/finalize script lives in the [bancorprotocol/carbon-vortex-bridge](https://github.com/bancorprotocol/carbon-vortex-bridge) repo. Clone it and install dependencies:

```
 git clone https://github.com/bancorprotocol/carbon-vortex-bridge
cd carbon-vortex-bridge
pnpm install
```

Requires **Node ≥ 18** and **pnpm**. Nothing else — scripts/withdraw\.mjs is a self-contained [viem](https://viem.sh) script (no Hardhat/Foundry needed for the withdrawal flow).

***

#### Prerequisites

* A signing key for the L1 transactions, passed explicitly as PRIVATE\_KEY on the command line&#x20;
* (see the commands below).
* That EOA needs **ETH on Ethereum mainnet** for gas (prove ≈ 350k gas; finalize is similar or smaller).
* For Step 1, just **CELO** for gas on Celo.

***

#### Step 1 – Initiate the bridge on Celo

1. Open the VortexOpStackBridge proxy on Celoscan → **Contract → Write as Proxy**:&#x20;
2. [0x753425e27aE996f0DB75C759C6E5EBa5c74D6aAF](https://celoscan.io/address/0x753425e27aE996f0DB75C759C6E5EBa5c74D6aAF#writeProxyContract)
3. Connect your wallet.
4. Find the bridge function. It takes one argument, amount:
   1. payableAmount (CELO) – **leave** 0 (this bridge does not take a native fee; sending any value reverts).
   2. amount – 0 bridges the entire WETH balance held by the Vortex; or pass a specific amount (wei).
5. Click **Write** and sign. This burns the L2 WETH and queues the canonical withdrawal message.

6\. **Copy the transaction hash** – you need it for steps 2 and 3.

> <sub>The L2 token being withdrawn is the bridged WETH</sub> <sub></sub><sub>0xD221812de1BD094f35587EE8E174B07B6167D9Af</sub><sub>; on L1 it is released as canonical WETH</sub> <sub></sub><sub>0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2</sub> <sub></sub><sub>to the vault.</sub>

***

#### Step 2 – Prove the withdrawal on Ethereum

The withdrawal can only be proven once a **dispute game** covering its L2 block has been posted to L1 by Celo's proposer (OP-Succinct validity proofs). This usually takes **tens of minutes to a few hours**.

From the repo root, check status any time (read-only, no key):

```
pnpm withdraw 0x6a5069be8e8f8a17107cacfb1502b3532d6b40eb85ce23e17eab0de7edffe7fe
```

When it reads ready-to-prove, run the **same command with your key** to send the prove tx:

```
PRIVATE_KEY=0x<your-key> pnpm withdraw 0x6a5069be8e8f8a17107cacfb1502b3532d6b40eb85ce23e17eab0de7edffe7fe
```

The script is **status-aware** — with a key set, the *same command* takes the correct next action at each stage; without a key it only reports status:

| Status it prints    | What it does (with PRIVATE\_KEY)                                    |
| ------------------- | ------------------------------------------------------------------- |
| waiting-to-prove    | No game covers the L2 block yet. **Re-run later.**                  |
| ready-to-prove      | Builds the proof and send the prove tx, then waits for the receipt. |
| waiting-to-finalize | Proven – prints the remaining time in the last 7-day window.        |
| ready-to-finalize   | Sends the finalize tx (see Step 4).                                 |
| finalized           | Done – WETH is in the vault.                                        |

On ready-to-prove it submits proveWithdrawalTransaction on the L1 portal and reports:

```
status: ready-to-prove
→ ready to prove against game index=35063 (l2Block=69633498)
   prove tx sent: 0x3812198829...
   prove success in block 25323683. 7-day finalize window starts now.
```

**The 7-day proof-maturity timer starts at the moment the prove tx confirms.**

***

#### Step 3 — Wait \~7 days

Re-running the read-only command during this period prints the countdown:

```
status: waiting-to-finalize
→ proven, in the 7-day window. ~168.0h left (ready at 2026-06-22T15:04:56.784Z).
```

Nothing to do but wait — you don't need to keep a process running, just re-run later.

***

#### Step 4 — Finalize on Ethereum

After the window opens, run the command with your key again:

```
PRIVATE_KEY=0x<your-key> pnpm withdraw 0x6a5069be8e8f8a17107cacfb1502b3532d6b40eb85ce23e17eab0de7edffe7fe
```

It detects ready-to-finalize, submits finalizeWithdrawalTransaction, and the **WETH is released to the vault** 0x60917e542aDdd13bfd1a7f81cD654758052dAdC4:

```
status: ready-to-finalize
   finalize tx sent: 0x...
   finalize success in block .... L1 WETH released to the vault.
```

That completes the bridge.

***

#### Script Configuration

scripts/withdraw\.mjs reads these from the environment (pass them on the command line; nothing is loaded from .env):

| Env var            | Purpose                                                                       | Default                               |
| ------------------ | ----------------------------------------------------------------------------- | ------------------------------------- |
| PRIVATE\_KEY       | Signer key for the L1 prove/finalize tx (0x-prefixed). Omit to run read-only. | —                                     |
| L1\_RPC            | Ethereum mainnet RPC (reads + sends txs)                                      | <https://ethereum-rpc.publicnode.com> |
| CELO\_RPC          | Celo RPC (receipt + status)                                                   | <https://forno.celo.org>              |
| CELO\_ARCHIVE\_RPC | Celo **archive** RPC for eth\_getProof (prove step)                           | <https://celo.drpc.org>               |
|                    |                                                                               |                                       |

Passing no PRIVATE\_KEY runs read-only — it just prints the current status without sending anything.

***

#### Reference addresses

| Contract                        | Network | Address                                    |
| ------------------------------- | ------- | ------------------------------------------ |
| VortexOpStackBridge (proxy)     | Celo    | 0x753425e27aE996f0DB75C759C6E5EBa5c74D6aAF |
| Vortex                          | Celo    | 0xD9D89e8A0dfE549e5B424D5b511cB3b84A764857 |
| WETH (withdraw token, L2)       | Celo    | 0xD221812de1BD094f35587EE8E174B07B6167D9Af |
| L2 Standard Bridge (predeploy)  | Celo    | 0x4200000000000000000000000000000000000010 |
| L2ToL1MessagePasser (predeploy) | Celo    | 0x4200000000000000000000000000000000000016 |
| OptimismPortal2                 | L1      | 0xc5c5D157928BDBD2ACf6d0777626b6C75a9EAEDC |
| DisputeGameFactory              | L1      | 0xFbAC162162f4009Bb007C6DeBC36B1dAC10aF683 |
| L1 Standard Bridge              | L1      | 0x9C4955b92F34148dbcfDCD82e9c9eCe5CF2badfe |
| WETH (released to vault, L1)    | L1      | 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 |
| Vault (final recipient)         | L1      | 0x60917e542aDdd13bfd1a7f81cD654758052dAdC4 |

***

#### Troubleshooting

* eth\_getProof → **"Missing or invalid parameters"** – forno does not serve eth\_getProof. Use an&#x20;
* archive endpoint (the default celo.drpc.org, or rpc.ankr.com/celo). This is why the prove step uses&#x20;
* CELO\_ARCHIVE\_RPC separately from CELO\_RPC.
* **"Dispute game not found" / stuck on waiting-to-prove** – the proposer hasn't posted a game covering&#x20;
* your L2 block yet. Wait and re-run; this is normal for the first tens of minutes to a couple of hours.
* **Prove/finalize tx fails or never sends** – confirm the signing EOA has mainnet ETH for gas, and&#x20;
* that you passed PRIVATE\_KEY (without it the script is read-only by design).
* **Want to check status without spending gas** – run the command with no PRIVATE\_KEY; it stays&#x20;
* read-only and just prints the current status.

***

#### Doing it manually (raw contract calls)

To drive the flow yourself without the script — every L1/L2 function call, on which contract, and how to source each parameter — see the contract-level reference: [celo-bridge-withdrawal-technical.md](https://celo-bridge-withdrawal-technical.md).<br>
{% endtab %}

{% tab title="Coti" %}
**On Coti**

1. View the wETH token page on [readProxy on cotiscan](https://mainnet.cotiscan.io/address/0x639aCc80569c5FC83c6FBf2319A6Cc38bBfe26d1?tab=read_proxy)
2. Find the read function called `quoteGasPayment`\
   ![](/files/PdMuVGtJCrMTn3PHtFdU)
3. Input `1` to indicate Ethereum as the destination chain
4. Click `Read` to discover the required gas cost\
   ![](/files/dCalJcUV08AsrgwN4Vi6)

Once you have this information available, paste it on the `Send native COTI` field for the `bridge` function\
![](/files/Z4lis9uiEjHEnWsk36yb)<br>
{% endtab %}

{% tab title="BNB" %}
**On BNB**\
Bridge is utilizing the "across" bridge infrastructure which knows how to calculate all required fees during execution.&#x20;

1. **bridge fee** value should be set to zero (0)
2. Click "write" and initiate the briding process.

Thats it.

{% endtab %}

{% tab title="All other chains" %}
**On Sei, Base, Tac, Fantom, Mantle, Linea, Blast, Telos and Iota:**\
Bridge supports automatic "claim" and as such you are required to include the gas fee needed for the following transaction on the ethereum blockchain. In order for the transaction to go through successfully, you must identify the required gas fee by following this process:

1. Visit [StarGate interface](https://stargate.finance/bridge)
2. Connect wallet
3. Attempt to bridge any amount of tokens (you want to see the transaction details on your wallet signed page DO NOT SIGN THE TRANSACTION)\
   ![](/files/zE6zuENNnD1zL08PM8YB)
4. In the wallet confirmation popup, find the value under "Param #2" as outlined in the image (you can "Cancel" the wallet popup after coping the required value)\
   ![](/files/iJL2fsVAjAjw68wIUOjq)
5. Copy the indicated value and paste it into the `bridge` field of the transaction. Make sure you normalize the decimal correctly to the gas token of the chain. For example, on Base, the input value should be in "ETH" units i.e. 0.000666588492010473 and not as indicated in WEI.

### Example

<pre class="language-solidity" data-overflow="wrap"><code class="lang-solidity">bridge(
0, //zero will try to bridge the full available amount
<strong>0.000666588492010473 //bridge fee (some bridge require this value in WEI)
</strong></code></pre>

{% endtab %}
{% endtabs %}


# Carbon DeFi Public REST API

### API Endpoint

Visiting the API endpoint will expose all available endpoints that are currently exposed with details on how to use each and every one of them.

[`https://api.carbondefi.xyz/`](https://api.carbondefi.xyz/)

{% embed url="<https://api.carbondefi.xyz/>" %}

### Overview

Carbon DeFi provides a public REST API designed to improve visibility into on-chain activity. This API offers developers an easy and efficient way to access unique transaction data, aggregated trade volumes, and key insights into the activities taking place within the Carbon DeFi ecosystem.

### Key Features

* **On-Chain Activity Tracking**: Retrieve real-time and historical transaction data.
* **Aggregated Trade Volumes**: Gain insights into overall trading activity and volume trends.
* **Unique Transaction Data**: Access structured data on individual transactions for deeper analysis.
* **Developer-Friendly**: Well-documented endpoints with JSON responses for seamless integration.

### Use Cases

* **Market Analytics**: Monitor trade volumes and liquidity trends.
* **User Activity Insights**: Track specific transactions and interactions with the protocol.
* **Data Aggregation**: Incorporate Carbon DeFi activity data into dashboards, research, and analytical tools.

{% hint style="info" %}
AI Agents can find dedicated resources on the [AI Agents & MCP Server](/rest-api/ai-agents-and-mcp-server) page
{% endhint %}


# AI Agents & MCP Server

Carbon DeFi has an MCP (Model Context Protocol) server that allows AI agents to create and manage on-chain trading strategies programmatically.

{% hint style="info" %}
Experimental — still being worked on. Use at your own risk.
{% endhint %}

* MCP endpoint: [https://mcp.carbondefi.xyz](https://mcp.carbondefi.xyz/)
* REST API: <https://mcp.carbondefi.xyz/tools/:toolName>
* OpenAPI spec: <https://mcp.carbondefi.xyz/openapi.json>
* Plugin manifest: <https://mcp.carbondefi.xyz/.well-known/ai-plugin.json>
* Server info: <https://mcp.carbondefi.xyz/info>

#### Claude Desktop setup

Add this to your Claude Desktop config to connect:

json

```json
{
  "mcpServers": {
    "carbon-defi": {
      "command": "npx",
      "args": ["mcp-remote", "https://mcp.carbondefi.xyz"]
    }
  }
}
```

#### Key conventions for agents

* All write operations return unsigned transactions — the user always signs and broadcasts
* Always call get\_strategies first to check existing positions
* Market price is auto-fetched from the Carbon API — no need to provide it manually
* Prices are always in quote token per 1 base token
* buy\_budget is always in quote token; sell\_budget is always in base token
* Check the warnings array in every response before presenting a transaction

<br>


# Carbon DeFi SDK

{% hint style="warning" %}
The Carbon DeFi SDK is currently being updated, and as a result parts of this section will change.&#x20;
{% endhint %}

Carbon DeFi operates fully on-chain, meaning all actions, functions, transactions, and interactions, can be performed, read, and verified directly on-chain from the contracts and their available functions.&#x20;

The Carbon DeFi SDK simplifies developer interaction with Carbon DeFi, abstracting complexity and speeding up the overall development process. The SDK is intended to be Carbon DeFi's main point of entry for developers.&#x20;

The SDK is open-source, and contributions to improve it are welcome.&#x20;

{% hint style="info" %}
When describing the contract functionality, the SDK reference will be mentioned and is recommended.
{% endhint %}

## Carbon DeFi SDK Github

{% embed url="<https://github.com/bancorprotocol/carbon-sdk>" %}

## Carbon DeFi SDK NPM

Use npm or yarn to install carbon-sdk.

```
yarn add @bancor/carbon-sdk
```

{% hint style="info" %}
AI Agents can find dedicated resources on the [AI Agents & MCP Server](/rest-api/ai-agents-and-mcp-server) page
{% endhint %}


# Getting started

The SDK initialization process will connect to the blockchain, fetch all relevant data and make it ready for further functionality and instructions.&#x20;

{% hint style="info" %}
The main point of interaction is the `index.ts` file&#x20;
{% endhint %}

* Initialize the SDK with the [Constructor](/developer-guides/carbon-defi-sdk/sdk-functions/constructor).
* Sync strategy data by calling [startDataSync](/developer-guides/carbon-defi-sdk/sdk-functions/startdatasync).

More detailed step by step guide on setting things up can be found here\
<https://github.com/bancorprotocol/carbon-simulator/tree/main/resources/sdk>


# Interacting with the SDK

The Carbon DeFi SDK has several intended functionalities:&#x20;

* [Managing Strategies](/developer-guides/carbon-defi-sdk/interacting-with-the-sdk/managing-strategies)
* [Performing Trades](/developer-guides/carbon-defi-sdk/interacting-with-the-sdk/performing-trades)
* [Getting User and Pair Data](/developer-guides/carbon-defi-sdk/interacting-with-the-sdk/getting-user-and-pair-data)
* [Collecting Liquidity Data](/developer-guides/carbon-defi-sdk/interacting-with-the-sdk/collecting-liquidity-data)

{% hint style="info" %}
The SDK generates unsigned transactions, however, it does not include signing functionality by default. A code example showing how to perform this can be seen commented out in [index.ts](https://github.com/bancorprotocol/carbon-sdk/blob/main/src/index.ts).&#x20;
{% endhint %}


# Managing Strategies

Carbon DeFi supports the ability to edit and manage existing strategies. This flexibility was designed to allow cheaper edits and further flexibility in how users can and will be using the strategy to match their trading activities.

Supported edit options include:

* Create a new strategy - the ability to create new strategy with the desired buy/sell prices and allocated budget
* Edit prices - the ability to change the buy/sell prices of an existing strategy
* Withdraw funds - the ability to withdraw partial or full budget that is currently allocated to a strategy
* Deposit funds - the ability to deposit additional funds into an existing strategy
* Pause strategy - the ability to reset buy/sell prices and disable a strategy
* Delete strategy - the ability to delete the strategy NFT and withdraw all allocated funds to the owner's wallet

{% hint style="info" %}
Performing these operations requires calling the Constructor, however it does not require syncing the data.
{% endhint %}

#### To Manage a Strategy

1. Initialize the SDK with the [Constructor](/developer-guides/carbon-defi-sdk/sdk-functions/constructor).
2. Call the desired function:
   * [createBuySellStrategy](/developer-guides/carbon-defi-sdk/sdk-functions/createbuysellstrategy)
   * [updateStrategy](/developer-guides/carbon-defi-sdk/sdk-functions/updatestrategy)
   * [deleteStrategy](/developer-guides/carbon-defi-sdk/sdk-functions/deletestrategy)
3. Sign and submit the unsigned transaction to the blockchain.&#x20;


# Performing Trades

Carbon DeFi orders are built as an individual concentrated pools of one directional liquidity. Given that, when trading on carbon DeFi, you would need to indicate the orders you would like to use in order to fulfill your trade.

The SDK uses it's trade-matching algorithm to generate trade routes through Carbon DeFi strategies.

#### To Trade

1. Initialize the SDK with the [Constructor](/developer-guides/carbon-defi-sdk/sdk-functions/constructor).
2. Sync strategy data by calling [startDataSync](/developer-guides/carbon-defi-sdk/sdk-functions/startdatasync).
3. Generate a trade route using [getTradeData](/developer-guides/carbon-defi-sdk/sdk-functions/gettradedata).
4. Generate a trade transaction, using either:
   * [composeTradeByTargetTransaction](/developer-guides/carbon-defi-sdk/sdk-functions/composetradebytargettransaction)\
     or
   * [composeTradeBySourceTransaction](/developer-guides/carbon-defi-sdk/sdk-functions/composetradebysourcetransaction)
5. Sign and submit the unsigned transaction to the blockchain.


# Getting User and Pair Data

The SDK simplifies getting data related to token pairs and strategies. This includes viewing strategy details, seeing what pairs are currently active, and checking if a pair has liquidity.&#x20;

#### To Get User or Pair Data

1. Initialize the SDK with the [Constructor](/developer-guides/carbon-defi-sdk/sdk-functions/constructor).
2. Sync strategy data by calling [startDataSync](/developer-guides/carbon-defi-sdk/sdk-functions/startdatasync).
3. Call the desired data gathering function:
   * [pairs](/developer-guides/carbon-defi-sdk/sdk-functions/getcachedpairs)
   * [hasLiquidityByPair](/developer-guides/carbon-defi-sdk/sdk-functions/hasliquiditybypair)
   * [getLiquidityByPair](/developer-guides/carbon-defi-sdk/sdk-functions/getliquiditybypair)
   * [getUserStrategies](/developer-guides/carbon-defi-sdk/sdk-functions/getuserstrategies)


# Collecting Liquidity Data

The SDK includes several functions that simplify gathering liquidity-depth data.

#### To Get Liquidity Depth Data

1. Initialize the SDK with the [Constructor](/developer-guides/carbon-defi-sdk/sdk-functions/constructor).
2. Sync strategy data by calling [startDataSync](/developer-guides/carbon-defi-sdk/sdk-functions/startdatasync).
3. Call the relevant liquidity data function:
   * [getRateLiquidityDepthByPair](/developer-guides/carbon-defi-sdk/sdk-functions/getrateliquiditydepthbypair)
   * [getMinRateByPair](/developer-guides/carbon-defi-sdk/sdk-functions/getminratebypair)
   * [getMaxRateByPair](/developer-guides/carbon-defi-sdk/sdk-functions/getmaxratebypair)


# SDK Functions

The Carbon DeFi SDK's main point of interaction is exposed through the functions in **index.ts:**

| Name                                                                                                                 | Description                                                                                                |
| -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| [`constructor`](/developer-guides/carbon-defi-sdk/sdk-functions/constructor)                                         | Initializes the SDK.                                                                                       |
| [`startDataSync`](/developer-guides/carbon-defi-sdk/sdk-functions/startdatasync)                                     | Fetches event data to create a representation of all Carbon DeFi strategies.                               |
| [`pairs`](/developer-guides/carbon-defi-sdk/sdk-functions/getcachedpairs)                                            | Gets a list of all active token pairs.                                                                     |
| [`hasLiquidityByPair`](/developer-guides/carbon-defi-sdk/sdk-functions/hasliquiditybypair)                           | Checks if a pair currently has liquidity in one or more strategies.                                        |
| [`getLiquidityByPair`](/developer-guides/carbon-defi-sdk/sdk-functions/getliquiditybypair)                           | Returns the total amount of liquidity in Carbon DeFi strategies for a given pair.                          |
| [`getUserStrategies`](/developer-guides/carbon-defi-sdk/sdk-functions/getuserstrategies)                             | Gets the list of strategies owned by an address.                                                           |
| [`getTradeData`](/developer-guides/carbon-defi-sdk/sdk-functions/gettradedata)                                       | Generates and returns a trade route for a trade, including an unsigned transaction to execute the trade.   |
| [`composeTradeByTargetTransaction`](/developer-guides/carbon-defi-sdk/sdk-functions/composetradebytargettransaction) | Creates an unsigned trade transaction for trading by target amount.                                        |
| [`composeTradeBySourceTransaction`](/developer-guides/carbon-defi-sdk/sdk-functions/composetradebysourcetransaction) | Creates an unsigned trade transaction for trading by source amount.                                        |
| [`createBuySellStrategy`](/developer-guides/carbon-defi-sdk/sdk-functions/createbuysellstrategy)                     | Creates a Carbon DeFi strategy, formatted for smart contract input, and generates an unsigned transaction. |
| [`updateStrategy`](/developer-guides/carbon-defi-sdk/sdk-functions/updatestrategy)                                   | Generates an unsigned transaction with updated order parameters.                                           |
| [`deleteStrategy`](/developer-guides/carbon-defi-sdk/sdk-functions/deletestrategy)                                   | Generates an unsigned transaction to delete a strategy.                                                    |
| [`getRateLiquidityDepthByPair`](/developer-guides/carbon-defi-sdk/sdk-functions/getrateliquiditydepthbypair)         | This returns the amount of liquidity available for a token pair at a specific trade-rate.                  |
| [`getMinRateByPair`](/developer-guides/carbon-defi-sdk/sdk-functions/getminratebypair)                               | Gets the current lowest trade price for a given token pair.                                                |
| [`getMaxRateByPair`](/developer-guides/carbon-defi-sdk/sdk-functions/getmaxratebypair)                               | Gets the current highest trade price for a given token pair.                                               |


# constructor

The constructor initializes the SDK and sets the RPC endpoint used for network calls.&#x20;

```
public constructor(config: Config, decimalFetcher?: DecimalFetcher)
```

<table><thead><tr><th width="184">Name</th><th width="158.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>config</td><td>config</td><td>This includes the rpcURL, the endpoint that data will be acquired through.</td></tr><tr><td>decimalFetcher</td><td>decimalFetcher (<strong>optional</strong>) </td><td><p>This optional parameter allows flexibility to get only the decimals of tokens that will be used. <br></p><p>If unspecified, it is automatically generated and will fetch the decimals of all tokens. </p></td></tr></tbody></table>


# startDataSync

This function syncs the cache of Carbon DeFi strategies using event data.&#x20;

```
ppublic async startDataSync(cachedData?: string)
```

`cachedData` is an optional parameter that will be used to seed the cache, instead of syncing from scratch.

{% hint style="success" %}
Syncing data is required for all trade and data functions, however, it is not a requirement for strategy management.
{% endhint %}


# getCachedPairs

This function returns a list of all token pairs that contain active strategies.

```
public get getCachedPairs()
```

### Returns

A list of token pairs.&#x20;


# hasLiquidityByPair

This function checks if a specific token pair has liquidity in one or more strategies.&#x20;

```
public hasLiquidityByPair(sourceToken: string, targetToken: string))
```

<table><thead><tr><th width="166.33333333333331">Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>sourceToken</td><td>token address</td><td>The first token in the pair.</td></tr><tr><td>targetToken</td><td>token address</td><td>The second token in the pair.</td></tr></tbody></table>

### Returns

**True:** the pair has active strategies.

**False:** the pair does not have active strategies.


# getLiquidityByPair

This function gets the total amount of liquidity available for a given token pair.

```
public async getLiquidityByPair(sourceToken: string, targetToken: string)
```

<table><thead><tr><th width="166.33333333333331">Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>sourceToken</td><td>token address</td><td>The first token in the pair.</td></tr><tr><td>targetToken</td><td>token address</td><td>The second token in the pair.</td></tr></tbody></table>

### Returns

The total amount of liquidity contained by strategies in the pair.&#x20;


# getUserStrategies

This function gets the strategies owned by the specified address.&#x20;

```
public async getUserStrategies(user: string)
```

| Name | Type    | Description                              |
| ---- | ------- | ---------------------------------------- |
| user | address | The address for which to get strategies. |

### Returns

A list of strategies owned by the specified address. The strategies are automatically converted into human-readable format.&#x20;


# getTradeData

This function uses the SDK's matching algorithm to find a trade route given a set of trading parameters.

```
public async getTradeData(
    sourceToken: string,
    targetToken: string,
    amount: string,
    tradeByTargetAmount: boolean,
    filter?: (rate: Rate) => boolean
  )
```

<table><thead><tr><th width="221">Name</th><th width="152.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>sourceToken</td><td>token address</td><td>The address of the token being swapped in. </td></tr><tr><td>targetToken</td><td>token address</td><td>The address of the token received.</td></tr><tr><td>amount</td><td>string (number)</td><td>The number of tokens being traded in, if using tradeBySourceAmount, or the number of tokens to receive.</td></tr><tr><td>tradeByTargetAmount</td><td>boolean</td><td>True: Generates the trade using tradeByTargetAmount<br>False: Generates the trade using tradeBySourceAmount</td></tr><tr><td>filter</td><td>list (optional)</td><td>This optional parameter forces the route to only include strategies that allow trading at the specified rate. Rate is calculated as input/output. <br><code>type Rate = { input: BigNumber; output: BigNumber; };</code></td></tr></tbody></table>

### Returns

This function returns the trade route, including the following parameters:

<table><thead><tr><th width="221">Name</th><th width="152.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>tradeActions</td><td>list</td><td>A list of trade actions that can be passed into composeTradeTransaction, a function that returns an unsigned transaction.</td></tr><tr><td>actionsTokenRes</td><td>list</td><td>A list of trade actions in human-readable format.</td></tr><tr><td>totalSourceAmount</td><td>string (number)</td><td>The total amount of source tokens going into the trade.</td></tr><tr><td>totalTargetAmount</td><td>string (number)</td><td>The total number of target tokens received by the trade.</td></tr><tr><td>effectiveRate</td><td>string (number)</td><td>The effective rate of exchange, calculated from the total input vs total output. </td></tr></tbody></table>

###


# composeTradeByTargetTransaction

This function creates an unsigned transaction to trade by target amount.&#x20;

```
public async composeTradeByTargetTransaction(
    sourceToken: string,
    targetToken: string,
    tradeActions: TradeActionStruct[],
    deadline: BigNumberish,
    maxInput: string,
    overrides?: PayableOverrides
  )
```

| Name         | Type                  | Description                                                                                                                                                                                                                                       |
| ------------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| sourceToken  | token address         | The token being sent.                                                                                                                                                                                                                             |
| targetToken  | token address         | The token received.                                                                                                                                                                                                                               |
| tradeActions | list                  | The list of trade actions to be performed.                                                                                                                                                                                                        |
| deadline     | number                | The timestamp at which point the trade will no longer be valid.                                                                                                                                                                                   |
| maxInput     | string                | The maximum number of source tokens that can be swapped in for the trade to succeed.                                                                                                                                                              |
| overrides    | object (**optional**) | This optional object contains transaction parameters, such as gas price, Eth value, etc. See **overrides** in the [Ethers documentation](https://docs.ethers.org/v5/api/contract/contract/#:~:text=The-,overrides,-object%20for%20a) for details. |

### Returns

This function returns an unsigned transaction that is ready to be signed and submitted to the blockchain.


# composeTradeBySourceTransaction

This function creates an unsigned transaction to trade by source amount.&#x20;

```
public async composeTradeBySourceTransaction(
    sourceToken: string,
    targetToken: string,
    tradeActions: TradeActionStruct[],
    deadline: BigNumberish,
    minReturn: string,
    overrides?: PayableOverrides
  )
```

| Name         | Type                  | Description                                                                                                                                                                                                                                       |
| ------------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| sourceToken  | token address         | The token being sent.                                                                                                                                                                                                                             |
| targetToken  | token address         | The token received.                                                                                                                                                                                                                               |
| tradeActions | list                  | The list of trade actions to be performed.                                                                                                                                                                                                        |
| deadline     | number                | The timestamp at which point the trade will no longer be valid.                                                                                                                                                                                   |
| minReturn    | string                | The minimum amount of target tokens that must be received for the trade to execute.                                                                                                                                                               |
| overrides    | object (**optional**) | This optional object contains transaction parameters, such as gas price, Eth value, etc. See **overrides** in the [Ethers documentation](https://docs.ethers.org/v5/api/contract/contract/#:~:text=The-,overrides,-object%20for%20a) for details. |

### Returns

This function returns an unsigned transaction that is ready to be signed and submitted to the blockchain.


# createBuySellStrategy

This function creates an unsigned transaction to create a strategy, using a buy/sell format.

```
public createBuySellStrategy(
    baseToken: { address: string; decimals: number },
    quoteToken: { address: string; decimals: number },
    buyPriceLow: string,
    buyPriceHigh: string,
    buyBudget: string,
    sellPriceLow: string,
    sellPriceHigh: string,
    sellBudget: string,
    overrides?: PayableOverrides
  )
```

<table><thead><tr><th width="172.33333333333331">Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>baseToken</td><td>object {token address, number}</td><td>An object containing a token address and a string with the number of decimal places used for the given token.</td></tr><tr><td>quoteToken</td><td>object {token address, number}</td><td>An object containing a token address and a string with the number of decimal places used for the given token.</td></tr><tr><td>buyPriceLow</td><td>string (number)</td><td>The lowest price at which to buy the quote token, in the form of quoteTokens  per 1 baseToken. </td></tr><tr><td>buyPriceHigh</td><td>string (number)</td><td>The highest price at which to buy the quote token, in the form quoteTokens  per 1 baseToken. </td></tr><tr><td>buyBudget</td><td>string (number)</td><td>The number of base tokens to start the strategy with.</td></tr><tr><td>sellPriceLow</td><td>string (number)</td><td>The lowest price at which to buy the base token, in the form of baseTokens per 1 quote token. </td></tr><tr><td>sellPriceHigh</td><td>string (number)</td><td>The highest price at which to buy the base token, in the form of baseTokens per 1 quote token. </td></tr><tr><td>sellBudget</td><td>string (number)</td><td>The number of quote tokens to start the strategy with.</td></tr><tr><td>overrides</td><td>object (<strong>optional</strong>)</td><td>This optional object contains transaction parameters, such as gas price, Eth value, etc. See <strong>overrides</strong> in the <a href="https://docs.ethers.org/v5/api/contract/contract/#:~:text=The-,overrides,-object%20for%20a">Ethers documentation</a> for details. </td></tr></tbody></table>

### Returns

This function returns an unsigned transaction that is ready to sign and submit to the blockchain.

#### Example:

```
createBuySellStrategy(
    {"0x514910771AF9Ca656af840dff83E8264EcF986CA", 18}, // LINK token, 18 decimal places
    {"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", 18}, // ETH token, 18 decimal places
    "0.05", // Lowest number of ETH per LINK
    "0.07", // Highest number of ETH per LINK
    "1877.3", // number of LINK to start the strategy with
    "25", // Lowest number of LINK per ETH
    "30", // Highest number of LINK per ETH
    "5.2", // number of ETH to start the strategy with
    null // optional overrides - skipped
  )
```


# updateStrategy

This function creates an unsigned transaction to update an existing strategy.

```
public async updateStrategy(
    strategyId: BigNumberish,
    encoded: EncodedStrategy,
    baseToken: { address: string; decimals: number },
    quoteToken: { address: string; decimals: number },
    buyPriceLow: string,
    buyPriceHigh: string,
    buyBudget: string,
    sellPriceLow: string,
    sellPriceHigh: string,
    sellBudget: string,
    overrides?: PayableOverrides
  )
```

<table><thead><tr><th width="172.33333333333331">Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>strategyId</td><td>number</td><td>The id of the strategy to update.</td></tr><tr><td>encoded</td><td>EncodedStrategy</td><td>The encoded form of the strategy that is being updated. This can be acquired using the <a href="/pages/un1tUf2maQFRcYKHObsX">getUserStrategies</a> function. </td></tr><tr><td>baseToken</td><td>object {token address, number}</td><td>An object containing a token address and a string with the number of decimal places used for the given token.</td></tr><tr><td>quoteToken</td><td>object {token address, number}</td><td>An object containing a token address and a string with the number of decimal places used for the given token.</td></tr><tr><td>buyPriceLow</td><td>string (number)</td><td>The lowest price at which to buy the quote token, in the form of quoteTokens  per 1 baseToken. </td></tr><tr><td>buyPriceHigh</td><td>string (number)</td><td>The highest price at which to buy the quote token, in the form quoteTokens  per 1 baseToken. </td></tr><tr><td>buyBudget</td><td>string (number)</td><td>The number of base tokens to start the strategy with.</td></tr><tr><td>sellPriceLow</td><td>string (number)</td><td>The lowest price at which to buy the base token, in the form of baseTokens per 1 quote token. </td></tr><tr><td>sellPriceHigh</td><td>string (number)</td><td>The highest price at which to buy the base token, in the form of baseTokens per 1 quote token. </td></tr><tr><td>sellBudget</td><td>string (number)</td><td>The number of quote tokens to start the strategy with.</td></tr><tr><td>overrides</td><td>object (<strong>optional</strong>)</td><td>This optional object contains transaction parameters, such as gas price, Eth value, etc. See <strong>overrides</strong> in the <a href="https://docs.ethers.org/v5/api/contract/contract/#:~:text=The-,overrides,-object%20for%20a">Ethers documentation</a> for details. </td></tr></tbody></table>

### Returns

This function returns an unsigned transaction, ready to be signed and submitted to the blockchain.


# deleteStrategy

This function creates an unsigned transaction to delete an existing strategy. When deleted, the strategy will return all tokens within to the strategy owner.

```
public deleteStrategy(
    strategyId: BigNumberish
  )
```

| Name       | Type   | Description                       |
| ---------- | ------ | --------------------------------- |
| strategyId | number | The ID of the strategy to delete. |

### Returns

This function returns an unsigned transaction, ready to be signed and submitted to the blockchain.


# getMinRateByPair

This function is used to get the minimum exchange rate for a given token pair. &#x20;

```
public async getMinRateByPair(
    sourceToken: string,
    targetToken: string
  )
```

<table><thead><tr><th width="150.33333333333331">Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>sourceToken</td><td>token address</td><td>The token being sold.</td></tr><tr><td>targetToken</td><td>token address</td><td>The token being bought. </td></tr></tbody></table>

### Returns

This function returns a **string** with the minimum exchange rate for the given token pair.&#x20;


# getMaxRateByPair

This function is used to get the maximum exchange rate for a given token pair. &#x20;

```
public async getMaxRateByPair(
    sourceToken: string,
    targetToken: string
  )
```

<table><thead><tr><th width="150.33333333333331">Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>sourceToken</td><td>token address</td><td>The token being sold.</td></tr><tr><td>targetToken</td><td>token address</td><td>The token being bought. </td></tr></tbody></table>

### Returns

This function returns a **string** with the maximum exchange rate for the given token pair.&#x20;


# getRateLiquidityDepthByPair

This function is used to calculate the amount of liquidity that exists for a specific pair up to the specified exchange rate.&#x20;

```
public async getRateLiquidityDepthByPair(
    sourceToken: string,
    targetToken: string,
    rate: string
  )
```

<table><thead><tr><th width="160.33333333333331">Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>sourceToken</td><td>token address</td><td>The token being sold.</td></tr><tr><td>targetToken</td><td>token address</td><td>The token being bought. </td></tr><tr><td>rate</td><td>string (number)</td><td>The number of target tokens per base token.</td></tr></tbody></table>

### Returns

This function returns a **string** with the amount of liquidity available at the specified rate.&#x20;


# The Carbon DeFi versus Uniswap V3 Invariant Functions

Carbon DeFi makes use of the same geometric price sequences that have governed AMM behavior since its first realization in 2017. While Carbon DeFi is not an AMM, the majority of the underlying theory is indistinguishable from that of conventional “concentrated liquidity” AMM designs. However, rather than let the price curves be determined by one and the same invariant curve (which, traditionally described two different token balances), instead, each token balance is given its own implicit curve (i.e. one “bonding curve” per token). This allows for arbitrary separation of bidding and asking prices characterized by irreversible token swaps, from which emerges a trading “strategy” – the core object of Carbon DeFi.

### Naming Conventions and Nomenclature

The implicit curves of the invariant function used by Carbon Defi adhere to the following conventions:

* Assume the implicit curves are drawn on a Cartesian plane.
* The available token balance is always depicted on the y axis, whereas the x axis does ***not*** refer to a token balance.
* Therefore, during a token swap, the tokens sent from the swapper to the contract is always Δx, and the tokens sent from the contract to the swapper is always Δy.
* The marginal price quote, -∂y/∂x, refers to the rate of y tokens purchased during a swap relative to the x tokens sold by the swapper; therefore large -∂y/∂x values represent a higher valuation of the x token relative to the y token and small -∂y/∂x values represent a lower valuation of the x token relative to the y token.
* Carbon DeFi’s “liquidity providers” choose two separate price quotes or price quote ranges: one supports trades of TKN1 → TKN2, and the other supports trades TKN2 → TKN1. Since both tokens are featured independently on their own y axis, and owing to the swap conventions described above, both price quotes are expressed in the form - ∂y/∂x.
* Each token’s implicit real curve is parametrized by three (3) constant[^1] terms:
  1. 𝒂

     ▪ Defined as the **difference between the square roots of the marginal exchange rates** at the 𝑦-intercept, and the 𝑥-intercept.&#x20;

     ▪ $$\normalsize 𝑎 = \sqrt{𝑃\_{high}} − \sqrt{𝑃\_{low}} = \left( -\frac{𝜕𝑦}{𝜕𝑥}|*{𝑥=0}\right)^\frac{1}{2} − \left(− \frac{𝜕𝑦}{𝜕𝑥}|*{𝑦=0}\right)^\frac{1}{2}$$
  2. 𝒃&#x20;

     ▪ Defined as the **square root of the marginal exchange rate** at the 𝑥- intercept, only.&#x20;

     ▪ $$\normalsize b = \sqrt{𝑃\_{low}} = \left( -\frac{𝜕𝑦}{𝜕𝑥}|\_{y=0}\right)^\frac{1}{2}$$
  3. 𝒛&#x20;

     ▪ Defined as the value of the 𝑦-intercept.&#x20;

     ▪ $$\normalsize 𝑧 = y|\_{x=0}$$

### The Carbon DeFi versus Uniswap V3 Invariant Functions

The Carbon DeFi invariant function can be written as:

$$
\Large \left(x + \textcolor{#ffa2a1}{ \frac{z}{a \cdot (a+b)}}\right) \cdot \left( y + \textcolor{#dc70fa}{  \frac{z \cdot b}{a}}\right) = \textcolor{#90f597}{\frac{z^2}{a^2}}
$$

Which has the same structure as the familiar Uniswap V3 invariant function, as written in its whitepaper:

$$
\Large \left( x + \textcolor{#ffa2a1}{\frac{L}{\sqrt{P\_{high}}}}\right) \cdot \left( y + \textcolor{#dc70fa}{L \cdot \sqrt{P\_{low}}}\right) = \textcolor{#90f597}{L^2}
$$

Both Carbon DeFi’s and Uniswap V3’s invariant functions refer to the same underlying mathematical and geometric objects, and the terms highlighted above are equivalent to each other.

$$
\Large \textcolor{#ffa2a1}{\frac{z}{a \cdot (a+b)}} = \textcolor{#ffa2a1}{\frac{L}{\sqrt{P\_{high}}}}
$$

$$
\Large \textcolor{#dc70fa}{\frac{z \cdot b}{a}} = \textcolor{#dc70fa}{L \cdot \sqrt{P\_{low}}}
$$

$$
\Large \textcolor{#90f597}{\frac{z^2}{a^2}} = \textcolor{#90f597}{L^2}
$$

{% hint style="info" %}
For further assistance, please join the [Bancor Developer telegram](https://t.me/BancorDevelopers) group
{% endhint %}

[^1]: The 𝑍 parameter is always constant on a curve being traded upon; however, the 𝑍 parameter on its counterpart curve (the

    spectator) may be increased.


# Carbon DeFi Subgraph

The Carbon DeFi Subgraph enables lightning fast queries that can answer most, if not all, data-related questions for Carbon DeFi. The Carbon Defi Subgraph uses The Graph protocol, a decentralized data indexer, that enables rich queries that can be generated using their interactive UI.

The Subgraph can fetch details for:

* Strategies
* Trades
* Token pairs
* Users
* And more!&#x20;

See the following sections for more details about how to use the Subgraph:

* [Accessing the Subgraph](/developer-guides/carbon-defi-subgraph/accessing-the-subgraph)
* [Creating Subgraph Queries](/developer-guides/carbon-defi-subgraph/creating-subgraph-queries)
* [Subgraph Query in Python](/developer-guides/carbon-defi-subgraph/subgraph-query-in-python)
* [Sample Subgraph Queries](/developer-guides/carbon-defi-subgraph/sample-subgraph-queries)

### Carbon DeFi Subgraph Links

* [Carbon DeFi Subgraph](https://thegraph.com/explorer/subgraphs/3oYNFcwAGk5mVtzzMTDjanoMRsZRCGk88EFRn75dLRyp?view=Overview\&chain=arbitrum-one) hosted by The Graph.&#x20;
* [Carbon DeFi Subgraph on Github ](https://github.com/bancorprotocol/carbon-subgraph)


# Accessing the Subgraph

The Carbon DeFi Subgraph can be accessed via [The Graph's website](https://thegraph.com/explorer/subgraphs/3oYNFcwAGk5mVtzzMTDjanoMRsZRCGk88EFRn75dLRyp?view=Overview\&chain=arbitrum-one).

#### Prerequisites

To start querying the Carbon DeFi Subgraph, you will need:

* A development environment.
* To register an account and generate an API key at: <https://thegraph.com/studio/apikeys/>


# Creating Subgraph Queries

Queries for the Carbon DeFi Subgraph can be generated using The Graph's interactive explorer. The following explains how to interact&#x20;

### To Generate Queries

1. Navigate to the interactive explorer: [Carbon DeFi Subgraph](https://thegraph.com/explorer/subgraphs/3oYNFcwAGk5mVtzzMTDjanoMRsZRCGk88EFRn75dLRyp?view=Playground\&chain=arbitrum-one)
2. Click the folder icon on the right to open the explorer:<br>

   <figure><img src="/files/rNEAvwwXF9TQhlotRRo6" alt=""><figcaption></figcaption></figure>
3. **Select or deselect** variable names to adjust the query. \
   For example to see the latest trades and some of their relevant details, select **trades** and one or more variables below it. <br>

   <figure><img src="/files/m0rAqBcxfM1e36TahLIM" alt=""><figcaption></figcaption></figure>
4. **Click** the **play button** to see an example of the results of your current query. Once satisfied, continue.
5. Copy the query into your code. \
   For example, in Python:

   ```python
   query = """

   {
     trades {
       sourceToken {
         symbol
       }
       targetToken {
         symbol
       }
       sourceAmount
       targetAmount
       transactionHash
     }
   }
   """
   ```


# Subgraph Query in Python

The following example queries the Carbon DeFi Subgraph using Python.

#### 1. Copy the following code snippet into a Python development environment:

{% hint style="info" %}
Note that you must assign the value for **"GRAPH\_API\_KEY"** with your API key. This example acquires the key from an .env file. To get an API key, visit: <https://thegraph.com/studio/apikeys/>&#x20;
{% endhint %}

```python
import requests
import os

GRAPH_API_KEY = os.environ.get("GRT_API_KEY")

# function to use requests.post to make an API call to the subgraph url
def run_query(q):

    # endpoint where you are making the request
    request = requests.post(f'https://gateway-arbitrum.network.thegraph.com/api/{GRAPH_API_KEY}/subgraphs/id/3oYNFcwAGk5mVtzzMTDjanoMRsZRCGk88EFRn75dLRyp'
                            '',
                            json={'query': query})
    if request.status_code == 200:
        return request.json()
    else:
        raise Exception('Query failed. return code is {}.      {}'.format(request.status_code, query))


# The Graph query
query = """

{
  pairs {
    token0 {
      symbol
    }
    token1 {
      symbol
    }
  }
}
"""

result = run_query(query)

pairs = result['data']['pairs']

print(f"number of pairs from subgraph: {len(pairs)}")
print(f"first pair: {pairs[0]}")
```

#### 2. Run the code!

If successful, you will see a printout of:

* The number of pairs found in Carbon DeFi
* The token symbols of the first pair

The printout should look like:

`number of pairs from subgraph: 87`&#x20;

`first pair: {'token0': {'symbol': 'BIAO'}, 'token1': {'symbol': 'ETH'}}`


# Sample Subgraph Queries

The following queries can be swapped into the `query` variable in the [Subgraph Query in Python](/developer-guides/carbon-defi-subgraph/subgraph-query-in-python) example to fetch the indicated data.

### Strategies Sample Query

```python
# The Graph query
query = """

{
  strategies(first: 10) {
    id
    order0 {
      A
      B
      y
      z
      inputToken {
        symbol
      }
      outputToken {
        symbol
      }
    }
    token0 {
      id
    }
    token1 {
      id
    }
    order1 {
      A
      B
      y
      z
      inputToken {
        symbol
      }
      outputToken {
        symbol
      }
    }
    owner {
        id
      }
  }
}
"""
```

### Pairs Sample Query

```
# The Graph query
query = """
{
  pairs {
    token0 {
      symbol
    }
    token1 {
      symbol
    }
  }
}
"""
```

### Trades Sample Query

```
# The Graph query
query = """
{
  trades {
    sourceAmount
    targetAmount
    sourceToken {
      symbol
    }
    targetToken {
      symbol
    }
    tradingFeeAmount
    transactionHash
    blockNumber
  }
}
"""
```


# Using CarbonVortex

The `CarbonVortex` is a contract designed to auction off fees collected within a Carbon DeFi ecosystem. It incentivizes arbitrageurs and public callers to interact with it and facilitates token trading through an auction mechanism.&#x20;

This guide explains how to deploy and interact with the contract effectively.

***

### **1. Deploying the `CarbonVortex` Contract**

#### **Steps to Deploy:**

1. **Obtain the Source Code**\
   Download the verified `CarbonVortex.sol` from the official [Bancor GitHub](https://github.com/bancorprotocol/carbon-contracts/tree/dev/contracts/vortex) repository.
2. **Configure Deployment Parameters**
   * **Token Address:** Define the token for which fees will be auctioned.\
     `CarbonVortex` supports 2 dimentional auction for increased flexibility:
     * `targetToken` : This token will be the destination to which all fees collected in multiple different and unique tokens (stables such as USDC and USDT, popular such as wETH, wBTC, or meme such as PEPE, SHIB) will be auctions for. The result is that all tokens collected would be auctioned and traded for this `targetToken` eventually.
     * `finalTargetToken`: This 2nd destination token allows the deployer to define another token in which the `targetToken` will be auctions for. This structure enables a secondary auction that can work for less liquid tokens yet allow consolidation. Deployer can decide to leave this address blank and avoid this step altogether.
   * **Auction Parameters:** Allow flexibility in auction flow and speed as well as the process in which the auction price reacts to trades and restart the auction price as a result.
   * **Caller Incentive:** Define the public incentive to encourage community engagement and interaction with the contract and auctions.&#x20;
3. **Deploy the Contract**

   Ensure deployment is on the intended blockchain network (e.g., Ethereum, Polygon).
4. **Verify Deployment**
   * Check the deployed contract address.
   * Verify the deployment on a block explorer to ensure all constructor arguments are set correctly.

***

### **2. Caller Incentive: When and Why to Trigger `execute()`**

The `execute()` function plays a central role in the lifecycle of the `CarbonVortex`:

1. **Transfers Collected Fees**: Aggregates fees from the protocol into the CarbonVortex contract.
2. **Initiates an Auction**: Starts an auction to consolidate various tokens into the `targetToken`.
3. **Provides Caller Incentives**: Rewards the caller of the function to encourage execution.

#### **Caller Incentive:**

* **Caller Rewards:** Callers are rewarded with a portion of the auction proceeds as defined in the contract.
* **Profit Opportunity:** Callers may profit by executing when they can acquire tokens below market value.

#### **Steps to Identify Profitability and Use `execute()`**

1. **Evaluate Tokens Collected by the Contract**
   * Before calling `execute()`, assess the amount of tokens currently held by the `CarbonVortex` contract. These tokens represent fees accumulated by the system.
2. **Identify the Collected Tokens:**

   The contract incentivizes execution by offering rewards to the caller. This incentive is derived from the collected tokens that will be transferred and auctions when calling the `execute()` function.

   * Use `availableTokens()` to identify the available balance of the token at hand.
   * Calculate caller incentives by multiplying this value by the returned value from `rewardsPPM()` .
3. **Trigger `execute()`**\
   Once the incentive is profitable, call the `execute()` function.

#### **What Happens After `execute()` is Called?**

1. **Auction Initialization:**
   * The contract sets up a new auction or restart an existing one, with parameters such as:
     * Starting price.
     * Auction duration.
     * Token amount for auction.
   * Auction details are typically emitted as an event for external tracking.
2. **Caller Reward:**
   * The caller receives their incentive, as calculated earlier, immediately upon execution.

***

### **3. Identifying Auction Prices and Trading Tokens**

#### **Fetching Auction Data**

This process requires retrieving some information from the contract

1. Call the `amountAvailableForTrading()` to identify the amount of tokens that are currently being auctions. This call requires passing the token address.
2. Call the `tokenPrice()` to know the current price for the token
3. Call `tradingEnabled()` and `pairDisabled()` to verify the token auction is enabled
4. Call `expectedTradeReturn()` or `expectedTradeInput()` to confirm the required amount for the trade (this can also help in defining the minReturn correctly to avoid loses)
5. Execute `trade()` to trade against the active auction in the contract

Alternatively, once can calculate the prices off-chain by analyzing the price dynamics:

* Auctions have a decaying price model half life (Dutch auction).
* As time progresses, prices decrease, incentivizing early bids.

#### **Executing a Trade**

Use the `trade()` function to buy tokens:

* Specify the amount you wish to trade.
* Ensure sufficient token allowance or ETH (if applicable).
* Specify the maxInput (commonly known as minReturn) to avoid loses as a result of MEV activity.

***

### **Conclusion**

The `CarbonVortex` contract is a powerful tool for decentralized fee auctions. By understanding its mechanisms and incentives, teams can effectively deploy, maintain, and interact with it to maximize utility and ensure a seamless auction process.


# CarbonVortex Dynamics

## **Initial Contract Settings**

The contract requires the deployer to predefine parameters which are used for the different function and functionalities of the contract and dutch auction.

#### Non adjustable values:

* Auction initial price - set at uint128, it enables every auction to start at a price point of 34×10^37
* targetToken - token address to consolidate all fees into
* finalTargetToken - \[optional] token address to auction targetToken to

#### Adjustable values:

* priceDecayHalfLife - on existing deployments it is set at 6h. This determine the speed in which the "**AnyToken to targetToken**" auction price moves once initiated (following `execute()`).&#x20;
* targetTokenPriceDecayHalfLife - on existing deployments it is set at 6h. This determine the speed in which the "**targetToken to finalTargetToken**" auction price moves once initiated (following `execute()`).
* targetTokenPriceDecayHalfLifeOnReset - on existing deployments it is set at 10days. This determine the speed in which the "**targetToken to finalTargetToken**" auction price slows down to following a trade.
* targetTokenSaleAmount - unlike other auctions that auction the entire available balance of the token, targetToken auctions use buckets. This value indicates the maximum amount of tokens the bucket can auction at once.

## **Initiating and Restarting Auctions**

Upon calling `execute()` , token balance will be transferred into the CarbonVortex contract and be included in an active auction. If there is no active auction, a new one will be created. There are some specific cases in which an auction price will reset to allow new tokens to rediscover their market price.


# Carbon DeFi Transaction Encoding

This page documents how to independently verify unsigned transactions returned by the Carbon DeFi MCP server or REST API. Use this to confirm that calldata matches what you requested before signing.

***

### Contract Addresses

All write operations target the CarbonController contract above. The `to` field in every unsigned transaction must match the address for the requested chain.

{% hint style="info" %}
Contract addresses can be found in the "[Mainnet Contracts](/contracts-and-functions/contracts/deployments/mainnet-contracts)" section
{% endhint %}

***

### Function Signatures

| Function                                                                                        | Selector     | Use                                        |
| ----------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------ |
| `createStrategy(address,address,(uint128,uint128,uint64,uint64)[2])`                            | `0xf727473a` | Create a new strategy                      |
| `updateStrategy(uint256,(uint128,uint128,uint64,uint64)[2],(uint128,uint128,uint64,uint64)[2])` | varies       | Edit/reprice/pause/resume/deposit/withdraw |
| `deleteStrategy(uint256)`                                                                       | `0x7831c1d7` | Delete a strategy                          |
| `tradeBySourceAmount(address,address,(uint256,uint128)[],uint256,uint128)`                      | `0xf1c5e014` | Swap — spend exact source amount           |
| `tradeByTargetAmount(address,address,(uint256,uint128)[],uint256,uint128)`                      | varies       | Swap — receive exact target amount         |

The first 4 bytes of the `data` field identify which function is being called.

***

### Order Encoding

Each strategy order is encoded as a struct with four fields:

```
struct Order {
  uint128 y;   // current token balance (liquidity) in wei
  uint128 z;   // capacity (max token balance) in wei
  uint64  A;   // encodeFloat(sqrt(highRate) - sqrt(lowRate)) * 2^48
  uint64  B;   // encodeFloat(sqrt(lowRate)) * 2^48
}
```

#### Price Encoding Pipeline

Prices in the Carbon DeFi protocol are stored as sqrt-rates using a custom float encoding. Here is the full pipeline:

**Step 1 — Normalize the price**

Prices are always expressed as `quote per base`. For the sell order (order0), prices are inverted and adjusted for token decimals:

```
normalizedRate = price * 10^(baseDecimals - quoteDecimals)
invertedRate = 1 / normalizedRate   # for sell order
```

The buy order (order1) uses the normalized rate directly.

**Step 2 — Convert to sqrt-rate**

```
sqrtRate = sqrt(normalizedRate)   # or sqrt(invertedRate) for sell
```

**Step 3 — Float encoding**

Carbon uses a custom 64-bit float encoding with a 48-bit mantissa and 16-bit exponent:

```
function encodeFloat(value):
  if value == 0: return 0
  exponent = floor(log2(value)) - 47   # so mantissa fits in 48 bits
  mantissa = round(value / 2^exponent)
  return (exponent + 2^15) << 48 | mantissa   # biased exponent
```

**Step 4 — Encode A and B**

```
A = encodeFloat(sqrtHighRate - sqrtLowRate)
B = encodeFloat(sqrtLowRate)
```

Where `sqrtHighRate` and `sqrtLowRate` are the sqrt-rates of the high and low prices respectively.

**Step 5 — Budget encoding**

```
y = parseUnits(budget, tokenDecimals)   # standard ERC20 wei conversion
z = y   # for new orders; may differ after partial fills
```

***

### Verification Checklist

When you receive an unsigned transaction from the MCP server:

1. **Check `to`** — must match the CarbonController address for the requested chain
2. **Check function selector** — first 4 bytes of `data` must match the expected function
3. **Check token addresses** — next 32-byte slots encode source/target or base/quote token addresses
4. **Check `value`** — must be 0 for ERC20 source tokens; must equal budget in wei for ETH as source
5. **Check order prices** — decode A and B fields and reverse the pipeline above to recover human-readable prices
6. **Check budget** — y field in wei must match the requested budget

***

### SDK Source References

For the exact encoding implementation:

* Price encoding: `@bancor/carbon-sdk` — `src/utils/encoders.ts`
* Float encoding: `@bancor/carbon-sdk` — `src/utils/numerics.ts`
* Strategy building: `@bancor/carbon-sdk` — `src/strategy-management/utils/index.ts`

***

### Trust Model

The MCP server returns unsigned transactions. It never signs or broadcasts. The user or their wallet signs and broadcasts.

If you are verifying a transaction from the MCP server, use the steps outlined in this page for further verification.


