# What is Mangrove?

Mangrove is an order book DEX that allows liquidity providers to post arbitrary smart contracts (hooks) as offers. This enables features such as re-staking of liquidity held on other protocols, liquidity amplification and liquidity provision via custom strategies.

## Unlock your liquidity[​](https://docs.mangrove.exchange/#unlock-your-liquidity)

Mangrove's order book DEX lists promises instead of locked commitments (liquidity is not locked on Mangrove). It can be employed elsewhere until the offer is matched. For example, you can provide liquidity (LP) on another exchange and use this LPed liquidity on Mangrove at the same time to trade or run strategies. This way, you can earn from up to any sources of yields, spread and rewards.


# Smart offers

The main difference between Mangrove and other DEXs is the ability to attach code to offers (check out Smart Offers for more information). This translates into several disruptive mechanisms:

* **Reactive liquidity**\
  The liquidity on offer on Mangrove **is not locked in a pool**. As long as an offer posted on Mangrove is not taken, it can generate yield elsewhere on the chain - Aave, Compound or Morpho are great examples of protocols where you could leave your liquidity to grow, waiting to be sourced.
* **Last look** \
  Since an offer contains code, **defensive mechanisms can be baked in** to cancel a promise previously made:
  * For instance, if the market conditions are not anymore satisfactory at the time the offer is taken VS when it was posted
  * Code can cover any unwanted case scenarios (ex: high volatility), and therefore can mitigate/solve problems of slippage and arbitrage
  * Code helps make zero-latency trading decisions, with as much information as available on-chain at the time the trade occurs
* **Persistence** \
  Through the executed code, the **offer can automatically repost itself** on the order book. For someone who is posting offers (we call them Makers, or Market Makers), this is very handy because they can immediately update the amount of tokens they are offering after some of it has been taken. People that take offers are called Takers.

Smart contracts can be attached to offers, which gives the Maker total freedom in setting his sourcing trade parameters.

**Other powerful applications of smart offers**[**​**](https://docs.mangrove.exchange/#powerful-applications-of-smart-offers)**:**

* **Bounty:** every single failed offer is compensated with a bounty; Keeper bots can make money, and Takers don't lose any.
* **Permissionless:** everyone can interact with the core protocol without having to ask permission nor risking to be censored.
* **Non-custodial:** Mangrove users retain full control over their funds - the exchange does not hold custody of their assets.


# Bounty

What if everyone makes empty promises, and the offers in the book are all meant to fail? This is where Makers **must leave a native token provision (the bounty)** in their offer. Nothing prevents them from posting offers that will always fail. So, to ensure that the offers displayed on the book are credible, it must be costly for Makers to post orders that are not meant to go through. And in that case scenario, the bounty is then given to the Taker as compensation.&#x20;

At first, **this might appear to favor Makers**. However, with advanced market-making features that allow them to accept or cancel offers, **Makers can mitigate their risk** and offer better prices. Ultimately, both Makers and Takers benefit: the risk of offer failure is essential for the effectiveness of smart offers.

Let's spend more time understanding [Makers](/start-here/what-is-mangrove/makers-takers-keepers/makers), [Takers](/start-here/what-is-mangrove/makers-takers-keepers/takers), and [Keepers ](/start-here/what-is-mangrove/makers-takers-keepers/keepers)(yes, that last one is a new term), shall we?


# Makers, Takers, Keepers

In the Mangrove ecosystem, three key participants interact to facilitate a dynamic and decentralized trading environment: [Makers](/start-here/what-is-mangrove/makers-takers-keepers/makers), [Takers](/start-here/what-is-mangrove/makers-takers-keepers/takers), and [Keepers](/start-here/what-is-mangrove/makers-takers-keepers/keepers). Together, they form the backbone of the Mangrove ecosystem, each playing a unique yet interconnected role in ensuring a seamless and effective trading experience.

Here is a simplified three-step diagram of Mangrove unlocked assets and offer-is-code approach. It also introduces the three main actors on Mangrove DEX.


# Makers

Makers are participants or entities within the Mangrove ecosystem who are responsible for creating and listing offers on the platform. They can specify the conditions of their offers, such as the type and quantity of assets to be exchanged, the price, and any other relevant terms. For example, they promise to give a Taker some apples 🍎 if he gives them oranges 🍊 in return.

By initiating these offers, Makers enable transactions to occur within the Mangrove Protocol, contributing to a vibrant market.


# Takers

**Takers** respond to the offers set up by [Makers](/start-here/what-is-mangrove/makers-takers-keepers/makers). They critically assess these offers, considering factors like asset types, quantities, and prices.

The role of Takers is crucial in completing transactions within the Mangrove marketplace. When a Taker agrees to the terms of an offer, they effectively seals the deal proposed by the Maker, leading to the execution of the trade.

Takers provide the necessary demand and liquidity in the marketplace, ensuring that the offers created by Makers are fulfilled. Their actions complete the cycle of trading activity within the Mangrove ecosystem, making it a dynamic and interactive platform for exchanges.

Takers have the ability to buy or sell assets on Mangrove, using either market or limit orders, akin to a traditional orderbook. They can execute these offers through general orders or choose to clean them individually.

This interaction between Takers and Makers completes the trading cycle in the Mangrove ecosystem, enhancing its interactivity and liquidity.

The workflow for Takers involves executing the logic of all relevant smart offers upon an order's placement. Successful orders are removed from the book, and the process continues until the Taker's order is completely filled. If a Maker withdraws their offer and fails to match the liquidity, the Taker is compensated with a penalty (bounty), and Mangrove proceeds to the next offer. This ensures that Takers are appropriately remunerated and that the order book remains efficient.


# Keepers

Keepers functioning as automated bots that ensure the order book remains relevant and efficient. As market conditions evolve, the order book may become congested with outdated or irrelevant orders. Keepers play a pivotal role in addressing this by continuously monitoring the order book.

Their primary responsibility is to identify offers that are failing. Once a failing offer is detected, Keepers targets them to clean them off the book. This action involves setting a gas price in such a way that the offer’s bounty offsets the gas expenditure. Essentially, Keepers act as the custodians of the Mangrove ecosystem, maintaining its integrity and smooth operation.

In addition to managing failing offers, Keepers are tasked with keeping the gas price up to date. This is crucial for determining the compensation for [Takers ](/start-here/what-is-mangrove/makers-takers-keepers/takers)who remove a failing offer from the list. By doing so, Keepers ensure that Takers are appropriately remunerated for their role in sustaining the efficiency and cleanliness of the order book.

Through these functions, Keepers play an indispensable role in the maintenance and operational effectiveness of the Mangrove ecosystem, safeguarding its functionality and reliability.


# Why Mangrove?

## **Deploy Your Own Composable Strategy**

Mangrove empowers liquidity providers with unparalleled flexibility, enabling them to customize and control their strategies:

* **Customizable Offer Management**: Liquidity providers can incorporate defensive code within their offers, post unprovisioned offers, and redisplay liquidity seamlessly after their offers are taken, ensuring optimized participation in the market.
* **Full Control Over Strategy Parameters**: Mangrove gives you the freedom to set precise parameters for your strategy, allowing you to align your liquidity provision with your specific risk and reward preferences.
* **Amplified Liquidity**: Maximize your trading potential by leveraging your liquidity across multiple pairs simultaneously. For example, you can place offers on both the WETH/USDB and WBTC/USDB pairs using the same USDB liquidity, efficiently broadening your market presence.
* **Multi-Liquidity Sourcing**: Your smart offers on Mangrove can source liquidity from external sources, dynamically offering it to the taker. This capability enables profitable arbitrage opportunities, as your offer can bridge liquidity from various sources in real time.

## **Explore Yield Opportunities on the Earn Page**

The [**Earn** ](/dapp-guide/earn)page on Mangrove’s DApp lets you explore and manage yield-generating positions within available vaults, built on Mangrove's. This feature not only allows liquidity providers to earn rewards but also enables **vault managers** to design and implement innovative DeFi strategies. By harnessing Mangrove’s unique liquidity provisioning, vault managers can create dynamic, adaptable strategies that respond to market conditions in real time, opening up new avenues for yield generation.&#x20;


# Who is the Mangrove dApp for?

The **Mangrove DApp** is designed for DeFi users seeking flexible, efficient, and innovative ways to manage liquidity and execute trades. It’s particularly suited for:

* **Liquidity Providers**: Those who want to earn yield by placing offers in multiple markets without locking up their assets. Mangrove’s unique approach allows liquidity providers to source funds dynamically, maximizing capital efficiency and unlocking additional earning opportunities.
* **Traders**: From beginners to experienced DeFi traders, Mangrove offers advanced trading features, including limit and amplified orders, with real-time order book data, market depth, and price charts. Traders can benefit from customized order options, like setting specific prices and durations for limit orders.
* **Yield Farmers**: For DeFi users aiming to maximize their rewards, Mangrove’s unique approach to liquidity provisioning offers a powerful advantage. By allowing assets to remain unlocked, Mangrove enables yield farmers to participate in multiple opportunities simultaneously, effectively compounding their earning potential across various protocols. With the flexibility to dynamically source liquidity, farmers can respond to market conditions, moving their funds to the most profitable yield-generating options without being restricted by asset lock-up.
* **Developers and Integrators**: Mangrove’s protocol is designed as a foundational layer for developers and projects that want to bring decentralized trading and liquidity management capabilities to their platforms. By leveraging Mangrove’s flexible, modular infrastructure, developers can integrate novel liquidity strategies, such as the amplified order feature, allowing assets to be used in multiple orders at once. This enables new and innovative DeFi applications that extend beyond traditional models, paving the way for composable and efficient decentralized financial solutions. As highlighted in our recent article, Mangrove is redefining the potential of liquidity in DeFi, offering developers a toolkit for the next generation of financial applications.

In summary, Mangrove is ideal for anyone in the DeFi space looking for innovative, flexible tools to optimize liquidity and trading strategies across multiple markets.


# FAQ

<details>

<summary>Why do my transactions keep failing?<a href="https://docs.mangrove.exchange/general/FAQ/#why-do-my-transactions-keep-failing">​</a></summary>

Here are a few reasons as to why your transactions are failing on Mangrove exchange:

* The amount of gas or slippage you selected is too low - we encourage you to tweak those values and find out what works best for your trades.
* The density for your Limit order is too low - if you're trying to place a Limit order with a small amount, your order will fail and will not be executed. Mangrove requires that you provide a token amount greater than the amount of gas the triggered offer requires to be executed (called density).
* You can check the minimum volume required to post a limit order [here](/dapp-guide/trade/how-to-make-an-order/limit-order).

💡 Note: if you still want to place a limit order with a small amount (ex: 10 USDC), you can avoid the density check by using [IOC (Immediate Or Cancel)](/dapp-guide/trade/how-to-make-an-order/more-on-order-types) orders.

</details>

<details>

<summary>The approval amount for my limit orders seems odd - what is going on?<a href="https://docs.mangrove.exchange/general/FAQ/#the-approval-amount-for-my-limit-orders-seems-odd---what-is-going-on">​</a></summary>

**TL;DR**

* A rule of thumb for limit orders to avoid order failure due to lack of approval is to make sure you approve at least double the amount you target (or infinite approval).
* The easy way to do this is to use the "Use default" option on your wallet when executing an approval.

**Let's now clarify the difference between the "Max" and "Use default" approval values offered by your wallet.**

* "Max" will give you the maximum amount available in your wallet.
* If you have ticked the "allow infinite approval" on Mangrove app, "Use default" will give you an "infinite approval" amount.
* If you have unticked the "allow infinite approval" on Mangrove app, "Use default" will give you the maximum amount available in your wallet based on what you've keyed in. That amount differs **whether you are executing a market order or a limit order**.

**Example (no infinite approval)**

* Market order: if you want to buy some WMATIC with let's say 20 USDT, "Use default" will set the approval amount at *20 + slippage*. For a 2% slippage, the amount to approve would be 20.4 USDT.
* Limit order: if you want to buy some WMATIC for 20 USDT of worth with a limit order (ex: Good til time), "Use default" will set the approval amount at *40 (20 \* 2)*.
  * If you have multiple open limit orders for the same token, the approvals then need to compound.
  * Example: if you create another Good til time limit order for 20 USDT of worth, the approval amount will be 40 (previous limit order) + 40 (new limit order) = 80 USDT.

</details>

<details>

<summary>Where can I get Mangrove’s addresses?<a href="https://docs.mangrove.exchange/general/FAQ/#where-can-i-get-mangroves-addresses">​</a></summary>

The deployment addresses for the core contract for Mangrove, as well as the most important periphery contracts are available at [Deployment Addresses](/quick-links/deployment-adresses).

</details>

<details>

<summary>Where is my transaction history?<a href="https://docs.mangrove.exchange/general/FAQ/#where-is-my-transaction-history">​</a></summary>

Which order type are you trying to execute? There are subtle differences between the various limit orders available on our Trade page. They might appear/be processed differently. We encourage you to first read the [More on order types](/dapp-guide/trade/how-to-make-an-order/more-on-order-types) section.

</details>

<details>

<summary>Who pays the gas on Mangrove?<a href="https://docs.mangrove.exchange/general/FAQ/#who-pays-the-gas-on-mangrove">​</a></summary>

If the offer succeeds, the gas costs for the execution of the trade are paid by the offer taker. If the offer fails the taker is compensated for these gas costs.

</details>

<details>

<summary>What happens when an offer fails?<a href="https://docs.mangrove.exchange/general/FAQ/#what-happens-when-an-offer-fails">​</a></summary>

Offers in the order book may fail when taken, either because the maker consciously chose to renege on the offer to trade, or because the maker contract reverted for other reasons. In that case, the taker has wasted some gas and will be compensated using the offer provision (in native token) that the maker has deposited in Mangrove.

</details>

<details>

<summary>Are Mangrove market orders the same as traditional market orders?<a href="https://docs.mangrove.exchange/general/FAQ/#are-mangrove-market-orders-the-same-as-traditional-market-orders">​</a></summary>

Mangrove's market orders are DeFi market orders - which are different from market orders in TradFi:

In TradFi, a market order is an order to buy or sell immediately at the best available price.

In DeFi, where transactions can be [front-run](https://www.investopedia.com/terms/f/frontrunning.asp) or [sandwiched](https://coinmarketcap.com/alexandria/article/what-are-sandwich-attacks-in-defi-and-how-can-you-avoid-them), adversaries may manipulate the best available price and thus extract value from a market order as there is no limit on the price. TradFi market orders are therefore unsafe for fully on-chain DEX'es like Mangrove.

To protect the user, Mangrove's market order therefore corresponds to a [**limit order**](https://www.investopedia.com/terms/l/limitorder.asp) in TradFi: An order to buy or sell at or below a given price. More precisely, Mangrove ensures that the **average** price of the offers matched with the order does not exceed the specified price.

TL;DR: Mangrove market order = TradFi limit order.

</details>

* [Why do my transactions keep failing?](https://docs.mangrove.exchange/general/FAQ/#why-do-my-transactions-keep-failing)
* [The approval amount for my limit orders seems odd - what is going on?](https://docs.mangrove.exchange/general/FAQ/#the-approval-amount-for-my-limit-orders-seems-odd---what-is-going-on)
* [Where can I get Mangrove’s addresses?](https://docs.mangrove.exchange/general/FAQ/#where-can-i-get-mangroves-addresses)
* [Where is my transaction history?](https://docs.mangrove.exchange/general/FAQ/#where-is-my-transaction-history)
* [Who pays the gas on Mangrove?](https://docs.mangrove.exchange/general/FAQ/#who-pays-the-gas-on-mangrove)
* [What happens when an offer fails?](https://docs.mangrove.exchange/general/FAQ/#what-happens-when-an-offer-fails)
* [Are Mangrove market orders the same as traditional market orders?](https://docs.mangrove.exchange/general/FAQ/#are-mangrove-market-orders-the-same-as-traditional-market-orders)


# Glossary

#### [Amplified Liquidity](/dapp-guide/trade/how-to-make-an-order/amplified-order)[​](https://docs.mangrove.exchange/developers/glossary#amplified-liquidity) <a href="#amplified-liquidity" id="amplified-liquidity"></a>

An offer on Mangrove that is undercollateralized.

#### Base / Quote[​](https://docs.mangrove.exchange/developers/glossary#base--quote) <a href="#base--quote" id="base--quote"></a>

Base token is the traded asset, quoted in Quote token.

#### [Bounty](/start-here/what-is-mangrove/bounty)[​](https://docs.mangrove.exchange/developers/glossary#bounty) <a href="#bounty" id="bounty"></a>

A portion of an offer provision that is sent to the taker to compensate a failure to deliver.

#### [Cleaning Bot](/start-here/what-is-mangrove/makers-takers-keepers/keepers)[​](https://docs.mangrove.exchange/developers/glossary#cleaning-bot) <a href="#cleaning-bot" id="cleaning-bot"></a>

An off-chain bot that keeps the order books clean by sniping failing offers.

#### Density[​](https://docs.mangrove.exchange/developers/glossary#density) <a href="#density" id="density"></a>

The ratio of tokens promised by an offer over the gas it requires to be executed.

#### Dual offer[​](https://docs.mangrove.exchange/developers/glossary#dual-offer) <a href="#dual-offer" id="dual-offer"></a>

An offer that is posted as a consequence of previous offer being taken.

#### gasLimit[​](https://docs.mangrove.exchange/developers/glossary#gaslimit) <a href="#gaslimit" id="gaslimit"></a>

The maximum gas requirement the taker will tolerate for an offer.

#### gasprice[​](https://docs.mangrove.exchange/developers/glossary#gasprice) <a href="#gasprice" id="gasprice"></a>

An estimate of the price of a gas unit in native token amount.

#### gasreq[​](https://docs.mangrove.exchange/developers/glossary#gasreq) <a href="#gasreq" id="gasreq"></a>

An upper bound of the gas units that an offer requires when called by Mangrove.

#### Gives[​](https://docs.mangrove.exchange/developers/glossary#gives) <a href="#gives" id="gives"></a>

The volume of tokens an offer promises in exchange of the full volume of required (or wanted) tokens.

#### Hook[​](https://docs.mangrove.exchange/developers/glossary#hook) <a href="#hook" id="hook"></a>

Internal functions in the building blocks of the Strat Lib, which may be overridden to change the default behavior of an offer logic.

#### Inbound[​](https://docs.mangrove.exchange/developers/glossary#inbound) <a href="#inbound" id="inbound"></a>

The token type that an offer taker must send.

#### [Keeper Bot](/start-here/what-is-mangrove/makers-takers-keepers/keepers)[​](https://docs.mangrove.exchange/developers/glossary#keeper-bot) <a href="#keeper-bot" id="keeper-bot"></a>

An off-chain bot that helps keep Mangrove functioning optimally.

#### Last Look[​](https://docs.mangrove.exchange/developers/glossary#last-look) <a href="#last-look" id="last-look"></a>

Feature of an offer logic that verifies whether trade execution should be cancelled.

#### Maker Contract[​](https://docs.mangrove.exchange/developers/glossary#maker-contract) <a href="#maker-contract" id="maker-contract"></a>

A maker contract is a smart contract that is bound to a smart offer posted on Mangrove.

#### Maker Partial Fill[​](https://docs.mangrove.exchange/developers/glossary#maker-partial-fill) <a href="#maker-partial-fill" id="maker-partial-fill"></a>

When an incoming order partially takes the volume given by an offer.

#### makerExecute[​](https://docs.mangrove.exchange/developers/glossary#makerexecute) <a href="#makerexecute" id="makerexecute"></a>

Callback function of an offer logic that is called by Mangrove prior to trade settlement.

#### makerPosthook[​](https://docs.mangrove.exchange/developers/glossary#makerposthook) <a href="#makerposthook" id="makerposthook"></a>

The callback function of an offer logic that is called by Mangrove immediately after trade settlement.

#### Offer ID[​](https://docs.mangrove.exchange/developers/glossary#offer-id) <a href="#offer-id" id="offer-id"></a>

The identifier of an offer in a given offer list.

#### Offer List[​](https://docs.mangrove.exchange/developers/glossary#offer-list) <a href="#offer-list" id="offer-list"></a>

A list of offers on the same token pair, ranked from best price to worst price.

#### Offer Logic[​](https://docs.mangrove.exchange/developers/glossary#offer-logic) <a href="#offer-logic" id="offer-logic"></a>

The part of a maker contract that is executed as a consequence of a call by Mangrove when processing a market order.

#### Offer Owner[​](https://docs.mangrove.exchange/developers/glossary#offer-owner) <a href="#offer-owner" id="offer-owner"></a>

An account that is allowed to post, update or retract a specific offer posted by a maker contract.

#### On-the-fly Offer[​](https://docs.mangrove.exchange/developers/glossary#on-the-fly-offer) <a href="#on-the-fly-offer" id="on-the-fly-offer"></a>

An offer posted by an EOA, in contrast with a smart offer, which is posted by a smart contract.

#### Outbound[​](https://docs.mangrove.exchange/developers/glossary#outbound) <a href="#outbound" id="outbound"></a>

The token type that an offer taker will receive.

#### Price[​](https://docs.mangrove.exchange/developers/glossary#price) <a href="#price" id="price"></a>

Amount of quote tokens per base token that an offer demands or a taker is willing to pay

#### Provision[​](https://docs.mangrove.exchange/developers/glossary#provision) <a href="#provision" id="provision"></a>

An amount of native tokens that is attached to a live offer on Mangrove and that is used to compensate a fail-to-deliver.

#### Ratio[​](https://docs.mangrove.exchange/developers/glossary#ratio) <a href="#ratio" id="ratio"></a>

The ratio 'wants/gives' between the amount an offer 'gives' and the amount it 'wants'.

#### Reactive Liquidity[​](https://docs.mangrove.exchange/developers/glossary#reactive-liquidity) <a href="#reactive-liquidity" id="reactive-liquidity"></a>

Liquidity providers can post offers that are not fully provisioned. It is enough that their code brings the promised liquidity at match-time. In the meantime, it can be put to work.

#### Renege[​](https://docs.mangrove.exchange/developers/glossary#renege) <a href="#renege" id="renege"></a>

Makers can renege on the offer to trade by incorporating defensive code in the maker contract (e.g., because the market conditions changed).

#### Reserve identifier[​](https://docs.mangrove.exchange/developers/glossary#reserve-identifier) <a href="#reserve-identifier" id="reserve-identifier"></a>

An immutable address identifying the fund owner when using a router

#### Router[​](https://docs.mangrove.exchange/developers/glossary#router) <a href="#router" id="router"></a>

A smart contract building block provided by the Strat Lib that is used by an offer logic to manage liquidity in a modular fashion.

#### [Smart Offer](/start-here/what-is-mangrove/smart-offers)[​](https://docs.mangrove.exchange/developers/glossary#smart-offer) <a href="#smart-offer" id="smart-offer"></a>

An offer that is bound to a smart contract, as opposed to an on-the-fly offer.

#### Taker Fee[​](https://docs.mangrove.exchange/developers/glossary#taker-fee) <a href="#taker-fee" id="taker-fee"></a>

A portion of the tokens promised to the taker that are sent to the Mangrove protocol's vault.

#### Tick[​](https://docs.mangrove.exchange/developers/glossary#tick) <a href="#tick" id="tick"></a>

A 'price point' corresponding to the ratio 1.0001^tick

#### tickSpacing[​](https://docs.mangrove.exchange/developers/glossary#tickspacing) <a href="#tickspacing" id="tickspacing"></a>

Controls the granularity of available price points in an offer list.

#### Wants[​](https://docs.mangrove.exchange/developers/glossary#wants) <a href="#wants" id="wants"></a>

The volume of tokens an offer wants in exchange of the full volume of promised (or given) tokens.


# Terms & Conditions

## Terms of Use

<https://www.mangrove.exchange/terms-of-use>

## Potential risks

Kandel strategy is subject to some risks that should be taken into consideration. By using Kandel, you acknowledge (i) having the necessary knowledge and understanding of the blockchain technology and the tokens, and (ii) comprehended the risks associated with blockchain-based software systems and tokens, as described below and in the disclaimer.

### Economical risks[​](https://docs.mangrove.exchange/general/kandel/potential-risks/#economical-risks) <a href="#economical-risks" id="economical-risks"></a>

As a user of the Kandel strategy, you understand that using Kandel can be affected by economic risks, including but not limited to:

* Partial or total loss of the tokens used;
* Partial or total loss of the value of the tokens used;
* Market extreme volatility;
* Insolvency of a third-party platform or company;
* Absence of liquidity and impossible resale on markets of the tokens.

### Impermanent Loss[​](https://docs.mangrove.exchange/general/kandel/potential-risks/#impermanent-loss) <a href="#impermanent-loss" id="impermanent-loss"></a>

Kandel is a passive market-maker where profit is generated from the spread. An example of impermanent loss on an ETH/USDC pair would be as follows:

1. If the current price of ETH/USDC pair moves up, asks will be consumed.
2. If the price keeps going up and crosses the max price range value, Kandel strategy will be left only with active bid offers on the ETH/USDC market.
3. It is likely that no one would be interested in taking these bids since they would not match the current price (you would be offering too little USDC for ETH, considering the new current price). This is what we call impermanent loss - your strategy stops generating profit from the spread.

### Smart contract and technological risks[​](https://docs.mangrove.exchange/general/kandel/potential-risks/#smart-contract-and-technological-risks) <a href="#smart-contract-and-technological-risks" id="smart-contract-and-technological-risks"></a>

You understands that even though the strategy has been implemented by an experienced team of researchers and developers, the use of Kandel can be affected by smart contract and technological risks, including but not limited to:

* Security error or failure allowing and/or resulting in hacking and stealing of user, third-party platform and/or website/app data;
* Stealing or loss of the user external wallet private key or his access to the third-party platform;
* Risks associated with blockchains used for the strategy, including but not limited to due to successful attacks from hackers or other criminal groups or organizations or countries, including but not limited to denial of service attacks, Sybil attacks, spoofing, smurfing malware attacks, consensus-based attacks, or phishing, or other new methods that may or may not be known;
* Lack of transparency in crypto asset management and markets;

That being said, please note that the **Kandel strategy has been thoroughly audited** by ChainSecurity.


# Kandel Aave

##


# What is Kandel and Kandel Aave?

Kandel is an Automated Market Making strategy that uses on-chain order flow to repost offers instantly, without any latency. It could be considered as a market-making bot equivalent that operates solely on the blockchain. It leverages **the interaction between buyers and sellers** that creates price movement, rather than the price itself.

Within a market and price range you select, Kandel automatically posts Bids and Asks. **Its main goal is to buy low and sell high** - profits are made through accumulated spread, i.e. the difference between the Bids and Asks that are taken.

## Kandel Aave

Kandel Aave is a strategy based on Kandel, but with funds deposited on [Aave](https://aave.com/) at any given time, the leading lending protocol on EVM. This allows users to combine trading fees generated on Mangrove while also benefiting from Aave’s yield.


# How does Kandel Work?

This section is a detailed explanation of how Kandel works, introducing configuration parameters and key mechanics. For the sake of simplicity, we have clearly separated the startup steps and picked round numbers.

Kandel is not intended as a "set and forget" strategy, and needs ongoing maintenance and checks.


# Step-by-step visual explanation

### Setting things up <a href="#setting-things-up" id="setting-things-up"></a>

Before launching your customized Kandel strategy, you will be asked to set specific input parameters. For more information, you can refer to the Parameters description table, as well as the Choosing parameters section.

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

Based on the selected **price range** and either the `number of offers` or `ratio`, the price grid is constructed using a geometric progression. The `min` and `max` prices of the user inputs are the limits of the grid.

The increments are calculated using a key metric called **ratio** (of the geometric progression). Kandel starts from the `min` price, all the way up to the `max` price. By default, the ratio is \~1% (due to ticks it will not be exactly 1%).

**Note** : In this example, the user selected an ETH/USDC trading pair.

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

Based on the selected amount of initial liquidity to be deposited, Kandel draws the **volume distribution** (i.e. the initial volume at each price point). In the example of a uniform volume distribution, the user's liquidity is spread evenly throughout the price grid.<br>

**Note** : For this explanation, we are conveniently using a 1 ETH allocation for each increment. If based on our parameters, our Kandel would create a price grid of 10 points, for example, then we would use 10 ETH in total (1 ETH \* 10 price points).

### Populating Bids and Asks <a href="#populating-bids-and-asks" id="populating-bids-and-asks"></a>

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

Afterwards, the Kandel strategy contract populates the price grid by posting offers:

* **Bids** are posted from min price to mid price (current price)
* **Asks** are on the other side of the book, from mid price to max price

### Bid is taken <a href="#bid-is-taken" id="bid-is-taken"></a>

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

When a **bid** is taken, the Kandel strategy contract sends the corresponding amount of **quote tokens** (USDC) and receives a corresponding amount of **base tokens** (ETH).

### Reposting liquidity as an Ask <a href="#reposting-liquidity-as-an-ask" id="reposting-liquidity-as-an-ask"></a>

<figure><img src="/files/3wQA1ynFLtFF5JcFBD9R" alt=""><figcaption></figcaption></figure>

The received amount of **base tokens** (ETH) is used to post a dual offer at a **step size k=1 above**. This is automatically handled by Kandel, it is part of its trading behaviour.

**Note** : Since the volume objective at the relevant index is 1 ETH, all the received liquidity is used to populate corresponding **ask**. Our Kandel just received 1 ETH (previous Bid), and is using it all to repost an offer, an Ask (called dual offer).

### Ask is taken <a href="#ask-is-taken" id="ask-is-taken"></a>

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

Inversely to the **bid** example, when an ask is taken, the Kandel strategy contract sends the corresponding amount of **base tokens** (ETH) and receives a corresponding amount of **quote tokens** (USDC).

### Reposting liquidity as an Bid <a href="#reposting-liquidity-as-an-bid" id="reposting-liquidity-as-an-bid"></a>

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

The received amount of **quote tokens** (USDC) is used to post a dual offer **step size k=1 below**.

In our example:

* We just received 1,300 USDC for sending 1 ETH through our **ask**
* Previously, we sent 1,287 USDC and received 1 ETH through our **bid**

Therefore, 13 USDC is reinvested into the strategy. A new **bid** at k=1 steps below is reposted, and offers 1,300 USDC for 1.01 ETH.

**Calculation**

* *Profit = 1,300 USDC - 1,287 USDC = 13 USDC*
* *13 / 1300 = 0.01 = 1%*
  * i.e. we made a 1% profit on the spread
* Kandel will repost our **bid** to offer *1,287+13 USDC* for *1\*1.01 ETH*, reinvesting the 1% profit we just made

### Another Ask is taken <a href="#another-ask-is-taken" id="another-ask-is-taken"></a>

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

When another **ask** is taken, once again Kandel sends the corresponding amount of **base tokens** (ETH) and receives a corresponding amount of **quote tokens** (USDC).

### Reposting liquidity as a Bid #2 <a href="#reposting-liquidity-as-a-bid-2" id="reposting-liquidity-as-a-bid-2"></a>

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

Similarly to our previous **bid**, the received amount of **quote tokens** (USDC) is used to post a dual offer **step size k=1 below**.

Note :

If an **ask** was to be taken next, the profit from the spread would be reinvested into the strategy.


# Parameters

This section describes Kandel's parameters. For more contextual information, head over to the visual explanation.

| Parameters        | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Pair              | <p>The pair represents the chosen market on which a Kandel strategy is running (along with the technical tick spacing).</p><p><em>Example: ETH/USDC is a trading pair</em></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Price range       | <p>The price range is needed to run any market-making strategy. It consists of the lowest and highest prices in the price grid at which Kandel instance posts its bids and asks.</p><p><em>Example of a price range:</em><br><em>• Lowest price = 1000 USDC per ETH</em><br><em>• Highest price = 1500 USDC per ETH</em></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| Current price     | <p>The current price of the base token that is used for constructing the price distribution.</p><p><em>Example: the price of ETH is used for the ETH/USDC pair</em></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Number of offers  | The number of offers to be published by the Kandel strategy within the selected price range.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| Ratio             | <p>The ratio defines the distance between price points which is derived using geometric progression.</p><p><em>Example:</em><br><em>• Ratio is <code>0.01</code> (due to ticks it will not be exact)</em><br><em>• Mid price is <code>1000</code></em><br><em>• Price point below mid price: <code>10000.99</code></em><br><em>• Price point above mid price: <code>10001.01</code></em>Additionally, the ratio could be derived from price points <code>PricePoint(i+1) / PricePoint(i) - 1</code>.<br><em>Example: <code>1010 / 1000 - 1 = 0.01</code></em></p>                                                                                                                                                                                                                                                                                                                                                                     |
| Step size         | <p>It is the distance between an executed bid/ask and its dual offer.</p><p>Whenever a Kandel ask is taken at a given price point, Kandel uses the amount of quote just received to place a bid at a lower price point. With a step size of 1, it will place the bid at the price point immediately below. With a step size of 2, Kandel will repost two price points below, etc. (Technical aside: if in attempting to repost say 3 steps below Kandel hits the boundaries of its range it will transport as far below as possible). The same applies symmetrically for bids.</p><p>Using a step size ≥ 2 allows one to publish a more continuous liquidity on the books, regularising the strat’s PnL, while at the same time keeping a reasonable spread between price points. Indeed, what matters to PnL is not the distance between price points, but how far money moves along the price grid each time an offer is taken.</p> |
| Initial inventory | <p>The initial inventory is the amount of base tokens and quote tokens that must be deposited into the strategy. The minimum to be deposited into the strategy depends on the selected price range and density of the selected market.</p><p><em>Example on the ETH/USDC pair:</em><br><em>• Base token is ETH</em><br><em>• Quote token is USDC</em></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| Bounty            | <p>It is the required amount of native tokens to be deposited into the strategy. A provision is required to post an offer, in order to pay a potential bounty. The bounty is only a subset, smaller in value than the provision.</p><p>The provision covers the whole price grid, hence:<br>• <em>Kandel provision = Provision per offer x Number of offers</em></p><p>Example: if the selected pair is on the Polygon network, the bounty would be an amount of MATIC tokens.\*</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                  |


# Choosing Kandel parameters

This section goal is to help you develop an intuition to choose your Kandel parameters. It should be taken as an explanation on how the various parameters can impact your Kandel, and how the market conditions (ex: volatility) could be taken into account. It is **not** a trading advice.

**Note** : As a reminder, Kandel is not intended as a "set and forget" strategy, and needs ongoing maintenance and checks.

We will be going through standard steps you might want a take in order to check the market and deploy a new Kandel. Essentially, that means that by using discrete AMM such as Kandel, you can fix the level of liquidity you are offering adjusted per volatility. So choosing the spread starts with answering the question - what is the volatility? If you can estimate or predict it well enough, the only thing you need to do is pick the spread (i.e. your parameters for Kandel).

### Check-in frequency <a href="#check-in-frequency" id="check-in-frequency"></a>

First, it is good practice to know how often you aim to update your Kandel. Depending on the trading pair you chose, markets can behave very differently.

**Example** : I will update my Kandel every 24h.

### Set your price range <a href="#set-your-price-range" id="set-your-price-range"></a>

Next, you should try to anticipate how much the market/price will vary during that period you just decided on. You are kind of betting on daily volatility.

**Example :** I will look at the market volatility for the past 24h, and decide on the price range for my new Kandel.

### Number of Offers / Ratio <a href="#number-of-offers--ratio" id="number-of-offers--ratio"></a>

This is the number of offers / ratio of the progression used to calculate the price grid. You would logically bet on intra-day volatility (few min or hours). If the volatility is increasing, you might want to increase the grid size (space between the offers). You will find more information about its calculation in the previous table.

**Note :**&#x20;

* High volatility: spaced out offers (less offers in the chosen range) -> higher ratio
* Low volatility: narrow offers (more offers in the chosen range) -> smaller ratio

### Step size <a href="#step-size" id="step-size"></a>

The general idea to configure your step size, is that a bigger volatility would likely lead to a bigger step size.

### Simple use case <a href="#simple-use-case" id="simple-use-case"></a>

Let's say you want to have a continuous Kandel, and maybe your current paramaters allow you only 2 offers:

* The solution to this is instead of having 2 offers with a step size = 1, you can configure 16 offers with a step size of 8
* That gives you continuity (more offers for a similar interval)
* When your offers are taken, Kandel will be able to "grab" lower prices


# Published Liquidity

Kandel instances don't lock your funds into the strategy. It uses the funds on the selected source, for publishing the chosen amount of liquidity.

Published liquidity is the amount of liquidity in active offers that are managed by the particular Kandel instance.


# More on failing offers

This section explains the reasons why some offers might fail using Kandel.

### Definition <a href="#definition" id="definition"></a>

When we talk about an offer "failing", we mean that it could not execute. An offer can also fail to update itself. While we won't go into details in this part of the documentation, it is important to mention and differentiate those cases to further understand Kandel strategy's behavior.

* [`makerExecute()`](about:/developers/strat-lib/technical-references/code/strats/src/strategies/MangroveOffer/#makerexecute): it is the callback function that is called when an offer is matched. Its role is to execute all offers that were posted on Mangrove by a given contract.
  * A failure in `makerExecute()` means the trade is canceled, and the bounty is given to the Taker as a [compensation](about:/developers/protocol/technical-references/market-order/#bounties-for-taking-failing-offers). The offer is removed from the book.
* [`makerPosthook()`](about:/developers/strat-lib/technical-references/code/strats/src/strategies/MangroveOffer/#makerposthook): it is the callback function that is called after the offer execution (i.e. after a successful execution of `makerExecute()`).
  * A failure in `makerPosthook()` means the offer cannot update or repost itself after being taken. It does not cancel the trade, since it is called after `makerExecute()`.

**Note** : For a more visual explanation, see the [call sequence overview](https://old.docs.mangrove.exchange/developers/protocol/technical-references/overview#call-sequence-overview) diagram.

### Kandel and `makerExecute()` failure <a href="#kandel-and-makerexecute-failure" id="kandel-and-makerexecute-failure"></a>

After launching a Kandel strategy, Bids and Asks are populated with a certain volume. Kandel strategy's contract is handling all the posting for the user, using liquidity that has been previously deposited.\
Therefore, since the user is not in charge of writing and maintaining the smart contract, failures to execute [`makerExecute()`](about:/developers/strat-lib/technical-references/code/strats/src/strategies/MangroveOffer/#makerexecute) can be almost entirely ruled out, with the exception of some very specific scenarios such as:

* Someone severely modifies the volume distribution/sourcing methods, creating issues when a Kandel Bid/Ask is taken (via the SDK)
* Kandel runs on AAVE, and the user's liquidity is not available for sourcing at the time the offer is taken. That could happen if the user's funds are suddenly borrowed entirely (on AAVE)

### Kandel and `makerPosthook()` failure <a href="#kandel-and-makerposthook-failure" id="kandel-and-makerposthook-failure"></a>

The main failures that Kandel could run into are linked to reposting Bids and Asks. This has little incidence for the user, nor does it affect the behavior of his Kandel strategy.\
Non-reposted liquidity will be placed into the [Unallocated liquidity](about:/general/kandel/how-does-kandel-work/strategy-reserve#unallocated-liquidity) reserve, and the offer will be "empty" for Kandel, until the user replenishes it.<br>

**Note** :

> If too many empty offers stack up, it would diminish Kandel's ability to profit from the spread, and therefore the overall generated yield. Kandel is not intended as a "set and forget" strategy, and needs ongoing maintenance and checks.

Reposting offers is handled with [`makerPosthook()`](about:/developers/strat-lib/technical-references/code/strats/src/strategies/MangroveOffer/#makerposthook), and failure could happen if:

* The residual of a partially taken offer is too small with regard to density:
  * A partially taken offer is the result of a Taker placing a Market order
  * If an offer is almost entirely taken, the remainder (dust) could be too small to pass the density check, leading to a failure to repost itself
* Kandel runs out of gas during the execution of the `makerPosthook()` because the gas requirements suddenly changed
  * This is unlikely to happen, but it theoretically could (if the order book becomes very dense in offers, for example)


# Potential risks

Kandel strategy is subject to some risks that should be taken into consideration. By using Kandel, you acknowledge (i) having the necessary knowledge and understanding of the blockchain technology and the tokens, and (ii) comprehended the risks associated with blockchain-based software systems and tokens, as described below and in the disclaimer.

### Economical risks <a href="#economical-risks" id="economical-risks"></a>

As a user of the Kandel strategy, you understand that using Kandel can be affected by economic risks, including but not limited to:

* Partial or total loss of the tokens used;
* Partial or total loss of the value of the tokens used;
* Market extreme volatility;
* Insolvency of a third-party platform or company;
* Absence of liquidity and impossible resale on markets of the tokens.

### Impermanent Loss <a href="#impermanent-loss" id="impermanent-loss"></a>

Kandel is a passive market-maker where profit is generated from the spread. An example of impermanent loss on an ETH/USDC pair would be as follows:

1. If the current price of ETH/USDC pair moves up, asks will be consumed.
2. If the price keeps going up and crosses the max price range value, Kandel strategy will be left only with active bid offers on the ETH/USDC market.
3. It is likely that no one would be interested in taking these bids since they would not match the current price (you would be offering too little USDC for ETH, considering the new current price). This is what we call impermanent loss - your strategy stops generating profit from the spread.

### Smart contract and technological risks <a href="#smart-contract-and-technological-risks" id="smart-contract-and-technological-risks"></a>

You understands that even though the strategy has been implemented by an experienced team of researchers and developers, the use of Kandel can be affected by smart contract and technological risks, including but not limited to:

* Security error or failure allowing and/or resulting in hacking and stealing of user, third-party platform and/or website/app data;
* Stealing or loss of the user external wallet private key or his access to the third-party platform;
* Risks associated with blockchains used for the strategy, including but not limited to due to successful attacks from hackers or other criminal groups or organizations or countries, including but not limited to denial of service attacks, Sybil attacks, spoofing, smurfing malware attacks, consensus-based attacks, or phishing, or other new methods that may or may not be known;
* Lack of transparency in crypto asset management and markets;

That being said, please note that the **Kandel strategy has been thoroughly audited** by ChainSecurity.


# Swap

With Mangrove’s swap page, you can swap tokens quickly and seamlessly. This feature allows you to execute market orders with ease, ensuring that you get the best available price without the hassle of complicated configurations.

#### **Step 1: Connect Your Wallet**

Click the **"Connect Wallet"** button at the bottom of the swap interface. This will open a pop-up for selecting and authorizing your wallet, allowing it to interact with Mangrove’s DApp on the chosen network.

**Disconnecting Your Wallet**: To disconnect your wallet, click on your wallet address in the top right corner. This will bring up a small pop-up with options to **Copy Address** and **Disconnect**. Click **Disconnect** to securely log out your wallet from the DApp.

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

**Step 2: Select the Network**

At the top right corner of the swap interface, you’ll find the **Network Selection** dropdown, located just beside your wallet address. Click this dropdown to choose the appropriate blockchain network for your transaction, such as **Arbitrum One** or **Blast**. Selecting the correct network is essential, as it determines the available tokens and fees for your transaction.

**Note**: You can switch networks at any time by using this dropdown. If you need to change the network during the process, just click the **Network Selection** button and choose a different network, but be aware that doing so may reset your token selections.

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

#### **Step 3: Select Tokens for Swapping**

* With your wallet connected and network set, proceed with choosing the tokens for the swap.
* **Sell** and **Buy Sections**: The swap interface is divided into two main sections:
  * **Sell**: The token you’re offering in the swap.
  * **Buy**: The token you’ll receive in exchange.

1. **Token Selection**: Click the dropdown next to each token icon to select the token type. The available options may vary depending on the selected network.
2. **Enter Amount**:
   * **Sell Amount**: Enter the amount of the token you want to swap in the **Sell** field. An equivalent USD value is displayed below for reference.
   * **Buy Amount**: After entering the sell amount, the buy amount will auto-calculate based on the current market rate.

If you wish to reverse the **Sell** and **Buy** tokens, you can click **Swap Direction** button (↔) between the Sell and Buy sections to reverse the tokens and quickly switch the trade direction. This will instantly switch the tokens, making the **Buy** token the **Sell** token, and vice versa, without needing to re-enter amounts.

**Note**: If the swap amount exceeds your balance, an **"Insufficient Balance"** message will appear. Make sure you have enough tokens to proceed.

#### **Step 4: Set Slippage Tolerance**

This controls the maximum price variation you’re willing to accept for the trade.

* **Available Options**: Choose from 0.1%, 0.5%, 1%, or set a **custom percentage**.
* **Use Case**: A lower tolerance limits price variation but may cause failed transactions if prices move. Higher tolerance increases the success rate but allows for more price fluctuation.

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

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

#### **Step 5: Confirm Swap Details**

* Double-check all details, including token selections, amounts, and slippage tolerance.

#### **Step 6: Execute the Swap**

1. **Swap Button**: When ready, click the **"Swap"** button.
2. **Wallet Confirmation**: Approve the transaction in your connected wallet, including any gas fees required by the network.

#### **Additional Interface Elements**

**Network and Account Information**: Located in the top right corner, this area shows both your network and wallet address. You can switch networks or wallet anytime by using these buttons.


# Trade

The **Trade** page in Mangrove’s DApp provides a streamlined interface for trading tokens using three types of orders: **market**, **limit**, and **amplified orders**. This page also includes real-time order books, trade history, and charting tools for tracking price movements and depth, enabling users to make informed trading decisions.

## **Types of Orders on Mangrove DEX**

On Mangrove DEX, there are three types of orders available:

1. **Market Order**: This type allows you to buy or sell a token at the current market price. Market orders are executed immediately, providing a quick and efficient trading option.
2. **Limit Order**: With a limit order, you set a specific buy or sell price for a token. The order will only execute when the market reaches the designated price, allowing you to control the trade’s entry or exit point based on your target price.
3. **Amplified Order**: Amplified orders are enhanced limit orders that leverage Mangrove’s unique **unlocked liquidity** principle. By using the **Liquidity Sourcing** option, you can place limit orders across multiple markets using the same funds, maximizing efficiency without locking assets. This strategy allows your funds to serve multiple trading opportunities simultaneously, boosting potential returns.

> **Note**: Before placing your first order, you will need to **approve** Mangrove to spend tokens on your behalf. This one-time authorization allows Mangrove to execute trades using your specified funds.

***

## **Accessing the Trade Page**

In the Mangrove DApp sidebar, click the **"Trade"** icon (two candlestick icons). This will open the trading interface, showing market information, order types, and trading options.

### **Market Data Overview**

* **Price**: Displays the current price of the selected pair.
* **24h Change**: Shows the price change percentage over the last 24 hours.
* **24h High/Low**: Indicates the highest and lowest prices within the past 24 hours.
* **24h Volume**: Shows the total trading volume for the pair in the past 24 hours.

### **Charting Options**

* **Depth Chart**: This chart visually represents the buy and sell orders on the order book, giving insights into market depth and potential liquidity at different price points.
* **Price Chart**: The price chart (often integrated with TradingView) provides price movements over time. You can add indicators, adjust timeframes, and customize views to analyze historical trends and price action for the trading pair.

## Fees[​](https://docs.mangrove.exchange/general/web-app/trade/#fees) <a href="#fees" id="fees"></a>

Makers on Mangrove have no fees to pay, all fees are paid by the takers! Below is a table of the fees on different markets available on Mangrove.

| Market        | Fee (Taker)                                                            |
| ------------- | ---------------------------------------------------------------------- |
| WETH/USDB     | <mark style="background-color:green;">2bps \| 0.02% all markets</mark> |
| Other markets | 5bps \| 0.05%                                                          |


# How to make an order

Due to the way mangrove works, there is a minimum volume that you need to be aware of when you are placing your order.

## How to make an Order

In the following pages you can see the way to make various types of orders on mangrove:

| Type            | Description                                                                                            |
| --------------- | ------------------------------------------------------------------------------------------------------ |
| Market Order    | Buy or sell a token at the current market price, executed immediately                                  |
| Limit Order     | Set a specific buy/sell price for a token, executed only when the market reaches that price            |
| Amplified Order | Set limit orders on several markets with the same funds leveraging our principle of unlocked liquidity |


# Market Order

A **Market Order** is the simplest and quickest way to trade on Mangrove. It allows you to buy or sell a token at the current market price and is executed immediately.

**Step 1: Access the Trade Page**

In the Mangrove DApp sidebar, click the **Trade** icon (two candlestick icons) to open the trading interface.

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

**Step 2: Select Trading Pair**

Choose the trading pair you wish to trade (e.g., **WETH/USDC**) from the dropdown at the top of the page.

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

**Step 3: Choose Order Type**

In the right-side panel, select Buy or Sell, then select **Market** under the **Buy** or **Sell** tab.

**Step 4: Enter Trade Details**

* **Send Amount**: Input the amount of the token you want to buy or sell. Use shortcuts like **25%**, **50%**, **75%**, or **Max** to quickly select a portion of your balance.
* **Receive Amount**: This will auto-calculate based on the current market price.

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

**Step 5: Set Slippage Tolerance**

Define an acceptable slippage tolerance (e.g., 0.5%) to manage potential price variations during execution.

**Step 6: Review Fees**

The system displays the transaction fee for the market order.

**Step 7: Place the Market Order**

* Click **Buy** or **Sell** to execute the market order instantly.
* **Confirm the transaction** in your wallet.

Your order will execute at the best available price, and your tokens will be transferred immediately upon confirmation.


# Limit Order

A **Limit Order** allows you to specify a price at which you want to buy or sell a token. The order will only execute if the market reaches your specified price, giving you more control over the trade.

**Step 1: Access the Trade Page**

In the Mangrove DApp sidebar, click the **Trade** icon to open the trading interface.

**Step 2: Select Trading Pair**

Choose the trading pair you wish to trade from the dropdown at the top (e.g., **WETH/USDC**).

**Step 4: Choose Order Type**

Select Buy or Sell, then select **Limit** under the **Buy** or **Sell** tab on the right side of the interface.

**Step 5: Enter Trade Details**

* **Set Limit Price**: Enter the specific price at which you want to buy or sell the token.
* **Send Amount**: Input the amount of the token you want to trade. You can use shortcuts like **25%**, **50%**, **75%**, or **Max** based on your wallet balance.
* **Total**: This field shows the total amount in the quote currency (e.g., USDC) calculated from the limit price and amount entered.
* [**Minimum Volume**](/dapp-guide/trade/minimum-volume): The minimum required trade volume will be displayed.

**Step 6: Liquidity Sourcing**

Leave this as **Wallet** if you want this limit order to execute only from your wallet funds. Look at Amplified Orders' page if you want to surce liquidity from elsewhere.

<div><figure><img src="/files/smykWWYOk2KvqYELjolQ" alt=""><figcaption></figcaption></figure> <figure><img src="/files/a0WgUrd4sz4WkR5ghGNN" alt=""><figcaption></figcaption></figure></div>

**Step 7:** [**Set Time in Force**](/dapp-guide/trade/how-to-make-an-order/more-on-order-types)

* **GTC (Good Till Canceled)**: The order remains open until it is either fully executed or canceled by the user.
* **PO (Post Only)**: The order will only be added to the order book and will not match with an existing order immediately. This is ideal for users who want to avoid immediate execution and instead provide liquidity to the book.
* **IOC (Immediate or Cancel)**: The order will attempt to execute immediately for as much volume as possible. Any portion that cannot be filled instantly will be canceled.
* **FOK (Fill or Kill)**: The order will only execute if it can be filled completely at the specified price. If the full volume cannot be matched, the entire order is canceled.

Additionally, you can specify a **Time in Force duration** to further customize the order’s validity:

* After choosing your preferred **Time in Force** option, set a specific time duration in **days**, **hours**, or **minutes**. This allows you to specify, for example, "28 Days" or "6 Hours" for your order to remain active within those parameters.

**Step 8: Place the Limit Order**

* Click **Buy** or **Sell** to place the limit order.
* **Confirm the transaction** in your wallet to finalize the order.

Your limit order will now appear in **Open Orders** and will only execute if the market reaches your specified price.[<br>](https://docs.mangrove.exchange/general/web-app/trade/how-to-make-an-order/minimum-volume)


# Amplified Order

An **Amplified Order** on Mangrove is an enhanced limit order that utilizes the **Liquidity Sourcing** option. This allows you to place limit orders across multiple markets with the same funds, leveraging Mangrove’s principle of unlocked liquidity for efficient capital use.

When setting up a [**Limit Order**](/dapp-guide/trade/how-to-make-an-order/limit-order) on the Trade page, you can configure the **Liquidity Sourcing** options to enable an **Amplified Order**. This allows you to make the most of Mangrove’s unlocked liquidity features.

1. **Choose Order Type**: Select **Limit** under the Buy or Sell tab on the right-side panel.
2. **Enter Limit Price and Amount**: Set the specific price and amount for your limit order.
3. **Configure Liquidity Sourcing**:

**Send from**:

This option allows you to choose the specific wallet or source from which the liquidity for the limit order will be drawn.

**Receive to**:

This option defines where the proceeds from the trade will go once the order is executed.

For **Amplified Orders**, setting up **Liquidity Sourcing** with specific **Send from** and **Receive to** wallets enables:

* **Multi-Wallet Management**: Users can choose to fund the order from one wallet and receive the output in another, adding flexibility in asset management.
* **Amplified Liquidity**: By using Mangrove’s unlocked liquidity, your funds in one wallet can simultaneously support multiple orders across markets, maximizing liquidity efficiency.[<br>](https://docs.mangrove.exchange/general/web-app/trade/how-to-track-open-orders)


# More on order types

This section provides an overview of the various order types available on Mangrove:

* [Market order](https://docs.mangrove.exchange/general/web-app/trade/more-on-order-types#market-order)
* [Immediate or Cancel (IOC)](https://docs.mangrove.exchange/general/web-app/trade/more-on-order-types#immediate-or-cancel-ioc)
* [Good 'til time (GTT)](https://docs.mangrove.exchange/general/web-app/trade/more-on-order-types#good-til-time-gtt)
* [Fill or kill (FOK)](https://docs.mangrove.exchange/general/web-app/trade/more-on-order-types#fill-or-kill-fok)

### Market order[​](https://docs.mangrove.exchange/general/web-app/trade/more-on-order-types#market-order) <a href="#market-order" id="market-order"></a>

A market order is an order type used to buy or sell at the current market price.

* It is executed immediately, prioritizing speed over the specified price.
* The execution price of a market order may vary due to market fluctuations and order book liquidity.
* Unlike limit orders, market orders do not have a specific price parameter and **are subject to slippage**, where the executed price may differ from the expected price.

Example

You place an market order to buy 1 WETH, with a 3% slippage (i.e. you are willing to accept up to 3% of price slippage on your order). Your order could either be executed:

* In full at 1,800 USDC (desired price).
* In full at a price between 1,800 USDC and 1,854 USDC (with a slippage of 3%).
* Partially, depending on the liquidity available on the offer on the order book.
  * Ex: 0.5 WETH at 1,800 USDC + 0.25 WETH at 1,818 USDC (1% slippage) + 0.25 WETH at 1,854 USDC (3% slippage)

### Immediate or Cancel (IOC)[​](https://docs.mangrove.exchange/general/web-app/trade/more-on-order-types#immediate-or-cancel-ioc) <a href="#immediate-or-cancel-ioc" id="immediate-or-cancel-ioc"></a>

While it may seem similar to a market order, there is a fundamental difference.

* With an IOC order, you set a specific limit price at which you want the order to be executed.
* The order will either be immediately filled at that exact price, fully or partially, or canceled entirely. It's about ensuring that your order is executed at your desired price, or not executed at all.
* The IOC order **does not allow for slippage**, meaning it won't be filled at a different price than what you specified (unlike a market order).

Example

You place an IOC order to buy 1 WETH at a max price limit of 1,800 USDC. Your order could either be:

* Fully taken immediately, i.e. you get your 1 WETH at the desired price.
* Partially taken immediately, i.e. you get 0.8 WETH at the desired price, and the rest is "canceled" (there is no resting order asking for the remainder).
* Canceled if there is no match on the order book.

### Good 'til time (GTT)[​](https://docs.mangrove.exchange/general/web-app/trade/more-on-order-types#good-til-time-gtt) <a href="#good-til-time-gtt" id="good-til-time-gtt"></a>

It allows you to set an expiry date for your limit order (ex: active for 3 days, then canceled if not filled). A GTT order that was created, but that has not yet been filled will always show as "Filled" in the UI - it is a normal behavior.<br>

Let us explain:

* When placing a GTT order, Mangrove will attempt to fill it entirely at the desired price.
* **Instant order** = the first execution of the order:
  * If it is a match and the fill is in full, it will be recorded in the UI as is.
  * If it can't be matched just yet, a fill at quantity "0" will be recorded in the UI for the instant order, and a **resting order** will be created.
* More on the fill at quantity "0":
  * That allows you to track in the UI that the order was successfully executed, even if no actual quantity was **yet** bought or sold.
  * It is crucial - without this, there would be no visual trace of what happened to the order you just placed (if not taken).
  * Your resting order is then waiting to be filled. There could potentially be multiple fills for that same order. Typically, there will be one fill for the initial order (0 or any other amount taken), and additional fills up until the resting order is fully taken.
* This mechanism ensures that even if there are partial fills or subsequent trades on the resting order, each execution is recorded separately.

Example

You place an GTT order to buy 1 WETH at a max price limit of 1,800 USDC, with a time limit of 3 days. Your order could be processed in several ways:

* **Instant full fill**: Your order is fully taken, immediately.
  * That means you obtain the target 1 WETH at the desired price.
  * A fill of the transaction will be recorded in the UI.
* **Instant partial fill + Resting Order**:
  * If your order is not entirely filled, a fill with the quantity that has been partially executed will be recorded in the UI.
  * Then, a new order will be created to capture the remaining quantity at the requested price. This order will be resting on the order book, waiting to be fully or partially taken, until the expiry date.
  * Each subsequent transaction that matches your resting order will be logged as a new fill until the order is fully executed or expired
* **No instant fill + Resting Order**:
  * If there is no matching order available on the order book at the time of placement, a "resting" order is posted in the book, waiting to be taken, either fully or partially.
  * Each transaction will log a new fill until the order is fully taken or expired.
* **Order Cancellation**: If there is no match for your order on the order book by the end of the specified time period (3 days in this case), the order will be automatically canceled.

### Fill or Kill (FOK)[​](https://docs.mangrove.exchange/general/web-app/trade/more-on-order-types#fill-or-kill-fok) <a href="#fill-or-kill-fok" id="fill-or-kill-fok"></a>

The KOF order is an "all or nothing" instant order. It is similar to the [IOC order](https://docs.mangrove.exchange/general/web-app/trade/more-on-order-types#immediate-or-cancel-ioc) in the sense that it executes immediately, but it does not allow for partial filling.

Example

You place an FOK order to buy 1 WETH at a max price limit of 1,800 USDC. Your order could either be:

* Fully taken immediately, i.e. you get your 1 WETH at the desired price.
* Canceled if there is no match on the order book.


# Approvals

## Infinite approval[​](https://docs.mangrove.exchange/general/web-app/trade/approve-buy#infinite-approval) <a href="#infinite-approval" id="infinite-approval"></a>

Before your order can succeed, you will have to approve mangrove to transfer the funds.

1. After choosing your order parameters, you will have to click the "Buy" or "Sell" button.
2. It will trigger the approval process, starting with a pop-up. Click on "Proceed" then "Approve".
3. Your wallet will open - you can leave the suggested amount for an "infinite approval".

   caution

   Clicking "Max" will give you the maximum amount available in your wallet. This means you will have to re-approve each time you make an order.
4. Click next, review the transaction and click "Approve" on your wallet.
5. Wait for the transaction to be processed, and that's it - you're ready to trade!

On the following pages, you will find more details on how to execute different order types

## About Approvals[​](https://docs.mangrove.exchange/general/web-app/trade/approve-buy#about-approvals) <a href="#about-approvals" id="about-approvals"></a>

You can read some more about approvals in the FAQ section.

Here are a few things you should consider when it comes to approvals:

1. An approval is valid only for a specific order type of a specific market.

   > 💡 For example, if you approved a BUY market order for the WETH/USDB market, this approval is not valid for SELL market orders for that same market. You have to approve again.
2. Approvals accumulate together.

   > 💡 For example, if you approve buy market order for WETH/USDB market with a 1000 USDB and perform a market order for 100 USDB, you have 900 USDB in approved balance. If you perform the same action again ("Approve & Buy"), you'll have 1800USDB of approved balance.
3. If your pre-approved amount is used up, your order will fail. An easy way around this is to perform an infinite approval.

## Revoke token approvals[​](https://docs.mangrove.exchange/general/web-app/trade/approve-buy#revoke-token-approvals) <a href="#revoke-token-approvals" id="revoke-token-approvals"></a>

To remove a dApp access to your wallet's tokens, you can revoke approvals previously granted. An easy way to do it would be to use [Revoke](https://revoke.cash/), for example. This will however risk your orders failing if you have open orders, so be sure you don't need the approvals.


# Minimum Volume

Due to the density on each market, there is a minimum token requirement when placing limit orders (except for IOC orders). You can read more about why your transactions might be failing in the FAQ.

This value will change based on the market and the source of liquidity you select, so please check the volume below in the app to make sure before you place your order!


# How to Track and Manage Orders

Mangrove’s Trade page dashboard is designed to help you efficiently manage and track all of your active, filled, and historical orders for each trading pair. Here’s a breakdown of how to monitor and interact with your orders.

## **Trades Tab**

The **Trades** tab shows recent transactions for the selected trading pair. This log of recent trades helps you understand market activity and price trends. It includes:

* **Size**: The amount of the asset traded.
* **Price**: The price at which the trade occurred.
* **Date**: The timestamp of each trade.

This tab provides a quick way to gauge market trends and see how frequently trades are happening at different price points.

## **Open Orders Tab**

The **Open Orders** tab is where you’ll find all your active limit orders that haven’t been filled or canceled yet. This tab is essential for tracking orders that are waiting for specific market conditions. Here’s what you’ll see:

* **Market**: The trading pair associated with the order, such as WETH/USDC.
* **Side**: Indicates whether it’s a Buy or Sell order.
* **Type**: Specifies the type of order, typically Limit or Market.
* **Filled/Amount**: Shows how much of the order has been filled versus the total order amount.
* **Price**: The set price for the order to execute.
* **Time in Force**: Indicates the order’s duration condition (e.g., GTC - Good Till Canceled, FOK - Fill or Kill).
* **Action**: An option to cancel the order directly from this tab if needed.

This tab is particularly useful for monitoring your ongoing trades and adjusting or canceling them as necessary.

## Managing Orders from the Open Orders Tab

From the **Open Orders**, you can quickly manage your orders: Modify or cancel them.

* **Modify**: Click **Modify** (the pen) to open the **Order Details** window, where you can adjust:
  * **Limit Price**: Change the price at which you want the order to execute.
  * **Amounts**: Adjust the amounts for **Send from Wallet** or **Receive to Wallet** to increase or decrease the funds allocated to this order.
* **Cancel**: If you no longer want the order to remain open, click **Cancel** (the cross) to remove it from the Open Orders list and cancel your order.

## **Orders History Tab**

The **Orders History** tab provides a comprehensive log of all your completed, expired, or canceled orders. Here, you can review past trades and actions. The fields in this tab include:

* **Market**: The trading pair involved in the order.
* **Side**: Shows whether it was a Buy or Sell.
* **Type**: Indicates the order type, such as Market or Limit.
* **Received/Sent**: Details the amounts of assets traded or received.
* **Price**: The price at which the trade was executed.
* **Date**: The date and time the order was filled or canceled.
* **Status**: Displays the final status of the order, such as Filled, Expired, or Canceled.
* **Explorer**: A link to the blockchain explorer for each transaction, enabling you to verify and track transactions on-chain.


# Earn

The **Earn** page on Mangrove’s DApp lets you explore and manage yield-generating positions within available vaults, built on Mangrove's flexible liquidity engine. These vaults leverage Mangrove’s unique liquidity provisioning to offer optimized yield strategies, allowing you to earn rewards while maintaining liquidity flexibility. With Mangrove’s composable infrastructure, yield opportunities are more dynamic and adaptable to market conditions, giving liquidity providers enhanced control over their earnings. You can deposit tokens to earn yields, view your active positions, and monitor key metrics for each vault.

#### **Step 1: Accessing the Earn Page**

In the Mangrove DApp sidebar, click the **"Earn"** icon (the piggy bank icon). This will take you to the Earn page, where you can view all available vaults and your active positions.

#### **Step 2: Viewing Vaults and Strategies**

The Earn page is divided into two sections:

* **My Positions**: Displays any active positions you currently hold in different vaults.
* **All Vaults**: Shows all available vaults, including their associated **market pairs** (e.g., WETH-USDC), **strategies** (such as Kandel), and **vault managers** (e.g., Redacted Labs). Key metrics, such as Total Value Locked (TVL) and annual percentage yield (APY), are also shown if available.

1. **Vault Market**: Each vault lists the token pair it supports, such as **WETH-USDC**.
2. **Strategy and Manager**: Each vault is managed by a specific strategy (like **Kandel**) and a vault manager (such as **Redacted Labs**).
3. **APY and TVL**: View potential returns (APY) and the total funds locked in the vault (TVL).
   * **Filter and Search Options**: Use the **Search Vault** bar to find a specific vault by name or market. You can also use the **Filter** button to narrow down the list based on different criteria.

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

#### **Step 3: Selecting a Vault and Viewing Details**

1. **Select a Vault**: Click on a vault from the list to view more detailed information. This will open the **Vault Details** page, providing deeper insights into the vault’s performance and requirements.
2. **Vault Details Overview**:
   * **TVL and APY**: Shows the total value locked in the vault and its projected annual yield.
   * **Performance Fee**: This is the percentage fee taken by the vault manager from the profits generated.
   * **Strategy and Manager**: Details on the strategy used in the vault and the entity managing it.
   * **Deposit and Withdrawal Options**: The page provides sections for **Deposit** and **Withdraw**, allowing you to manage your funds within the vault.
3. **Vault Description and Charts**: Each vault includes a description (currently placeholder text in some cases) and a **performance chart** displaying metrics like APY and TVL trends over time. Charts labeled "Vault charts coming soon!" indicate that historical data is not yet available.

#### **Step 4: Depositing Funds into a Vault**

1. **Deposit Section**: On the right side of the Vault Details page, you’ll find the **Deposit** section.
2. **Select Deposit Amount**:
   * You can deposit tokens like WETH or USDC by selecting the desired amount. Use the percentage shortcuts (25%, 50%, 75%, Max) to quickly choose how much of your balance you want to deposit.
3. **Confirm Deposit**: Once you’ve selected the amount, click the **Deposit** button. Confirm the transaction in your wallet to finalize the deposit.

   **Note**: Ensure you have enough tokens in your wallet for the selected deposit, as well as enough to cover any network fees.

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

#### **Step 5: Withdrawing Funds from a Vault**

1. **Withdraw Tab**: Next to the Deposit tab, you’ll see the **Withdraw** tab. Click here if you wish to remove funds from the vault.
2. **Select Withdrawal Amount**: Choose the percentage of your funds in the vault you’d like to withdraw (25%, 50%, 75%, Max).
3. **Confirm Withdrawal**: Click the **Withdraw** button and confirm the transaction in your wallet to complete the withdrawal process.

   **Note**: Be aware of any withdrawal fees or delays that might apply depending on the vault’s strategy.

#### **Step 6: Monitoring Your Position and Rewards**

1. **My Position**: Under **My Position**, you can track your current balances in the vault, including each token (e.g., WETH and USDC), the minted amount of any vault-specific tokens, and other details.
2. **Rewards**: Below My Position, you’ll see the [**Rewards** ](/dapp-guide/rewards)section, which shows any rewards you’ve accrued from the vault, such as **MGV tokens**. Click **Claim Rewards** to transfer any available rewards to your wallet.

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

#### **Additional Vault Details**

At the bottom of the Vault Details page, you’ll find more specific information about the vault, such as:

* **Strategy Details**: Shows the vault’s strategy name, performance fee, and other technical data.
* **Chain and Manager Information**: Includes details on the blockchain network (e.g., Arbitrum One), vault manager, and any audits or security certifications.
* **Creation Date and Addresses**: Provides the creation date of the vault and addresses for the strategy and vault contracts.


# Rewards

The **Rewards** page on Mangrove’s DApp is where users can monitor their reward progress across different activities, view their rank in the reward program, and claim any available rewards.&#x20;

***

#### **Step 1: Accessing the Rewards Page**

In the Mangrove DApp sidebar, click the **"Rewards"** icon (the 'hand bearing a coin' icon). This will take you to the Rewards page, which displays your current rewards, rank, and other details.

#### **Step 2: Understanding the Reward Epoch and Program Details**

1. **Epoch Information**: At the top of the Rewards page, you’ll see the current **Epoch** number and details about the reward cycle. The epoch represents a specific time period over which rewards are calculated.
   * **Ends In** and **Current p** ([Reward rate](/mgv-incentives/ms2-program-closed/how-rewards-are-calculated/reward-rate-r)): These fields may indicate the time remaining for the epoch and the current performance level if they are active, helping you track the reward cycle’s progress.
2. **Total Epoch Reward**: The total MGV reward amount available for the current epoch is displayed, broken down into specific reward categories:
   * **Taker Rewards**: Rewards for users who engage in trading activity.
   * **Maker Rewards**: Rewards for liquidity providers.
   * **Kandel Rewards**: Rewards specific to the Kandel strategy (if applicable).

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

#### **Step 3: Tracking Your Points and Rank in Season Program**

1. **Season 1 Points Program**: Below the epoch section, the **Season 1 Points Program** table shows the leaderboard and ranks of users based on their accumulated points. This includes:

   * **Rank**: Your ranking among other participants based on total points.
   * **Address**: The wallet addresses of participants. If you’re logged in, your address will show as "You" in the list.
   * **LP Points**: Points earned from liquidity provision.
   * **Trading Points**: Points from trading activities.
   * **Referral Points**: Points earned by referring others to Mangrove.
   * **Community Points**: Points from community engagement.
   * **Total Points**: The sum of all points from the above activities.

   Use this table to view your ranking in the [MS1 Program](/mgv-incentives/ms1-program-closed) and, soon, in the [new MGV Incentives' program](/mgv-incentives/fee-rewards) to see how you compare to other participants.

#### **Step 4: Checking Your Available, Claimed, and Total Rewards**

1. **Available Rewards**: On the right side of the page, your **Available Rewards** section shows the amount of MGV tokens you can currently claim. These rewards are updated periodically based on your activity and point accumulation.
2. **Claimed Rewards**: This shows the amount of MGV tokens you’ve already claimed during the current season or epoch.
3. **Total Rewards**: The total amount of MGV rewards you’ve earned, including both claimed and unclaimed tokens.

#### **Step 5: Claiming Your Rewards**

1. **Claim Rewards Button**: If you have available rewards, the **Claim Rewards** button will be active. Click this button to initiate the claiming process.
2. **Wallet Confirmation**: Confirm the transaction in your connected wallet to finalize the claim and transfer the MGV rewards to your wallet.

   **Note**: Ensure you have enough funds to cover any transaction fees on the network.


# Kandel


# Bridge

The **Bridge** feature on Mangrove’s DApp, powered by Synapse, enables users to seamlessly transfer tokens across blockchain networks. This functionality is accessible on the **More** page, under the **Bridge** tab, allowing users to move their assets between networks without leaving the Mangrove platform.

#### **Step 1: Accessing the Bridge Feature**

1. **Navigate to the More Page**: In the Mangrove DApp sidebar, click the **"More"** icon (three dots icon) at the bottom of the sidebar.
2. **Select the Bridge Quick Option** or on the More page, locate the **Bridge** tab at the top. This will open the bridge interface, where you can begin setting up your cross-chain transfer.

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

#### **Step 2: Choosing the Source and Destination Networks**

1. **Select Source Network**: In the bridge interface, use the **Source Network** dropdown (the top section) to select the blockchain network you’re transferring tokens **from** (e.g., **Arbitrum**).
2. **Select Destination Network**: Similarly, use the **Destination Network** dropdown (the bottom section) to select the network you’re transferring tokens **to** (e.g., **Blast**).

   **Note**: Only supported networks will be displayed, and both networks must support the token you wish to transfer.

#### **Step 3: Selecting the Token and Entering the Amount**

1. **Select Source Token**: Click on the **Token** dropdown within the Source Network section to choose the token you want to transfer. The interface will display only tokens that are available for bridging between the chosen networks.
2. **Enter Amount**: Input the amount of the token you wish to transfer. Ensure that you have enough balance in your wallet for the selected amount, as well as additional funds to cover any transaction fees.

   **Note**: Minimum and maximum transfer limits may apply based on the networks and token chosen.

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

#### **Step 4: Confirm and Send the Transaction**

1. **Review Details**: Double-check the network, token, and amount details to ensure accuracy. Transferring assets across networks involves fees and may not be reversible, so confirming the details is crucial.
2. **Send**: Once all details are verified, click the **Send** button to initiate the transfer.

   **Wallet Confirmation**: You’ll need to confirm the transaction in your wallet, including any gas fees associated with the source network.

#### **Step 5: Switching Networks (If Necessary)**

1. **Network Switch Prompt**: If the transfer requires you to interact with a different network, a prompt may appear advising you to switch to the destination network for further actions.
2. **Network Switching**: You can easily switch networks by clicking the **Network Selection** dropdown in the top right corner of the DApp interface. Select the destination network to continue interacting with your transferred assets.

   **Note**: A warning message at the bottom of the interface may remind you to switch networks to fully access your transferred funds.

#### **Tips for Using the Bridge**

* **Powered by Synapse**: Mangrove’s bridge functionality is supported by Synapse, a trusted protocol for cross-chain transfers. This integration ensures secure and efficient asset transfers.
* **Token Availability**: Check that your selected token is supported on both the source and destination networks to avoid transfer issues.
* **Transaction Fees**: Remember to account for transaction fees on the source network, which will be deducted from your wallet balance.


# Wrap

The **Wrap** feature on Mangrove allows you to convert ETH into wETH (Wrapped ETH), which is essential for trading on many decentralized platforms that operate using ERC-20 tokens. Wrapped ETH has the same value as regular ETH but can be used in ERC-20 compatible environments.

#### **Step 1: Accessing the Wrap Feature**

1. **Navigate to the More Page**: In the Mangrove DApp sidebar, click the **"More"** icon (three dots icon) at the bottom of the sidebar.
2. **Select the Wrap Quick Option** or on the More page, locate the **Wrap** tab at the top. This will open the bridge interface, where you can begin setting up your cross-chain transfer.

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

**Step 2: Wrapping Your ETH**

1. **Enter Amount**: In the **Amount to wrap** field, type the amount of ETH you want to convert into wETH. The interface will display your **current ETH balance** in the bottom right to guide you on how much you have available.
2. **Wrap ETH**: Once you enter the amount, the **Wrap ETH** button will become active. Click this button to initiate the wrapping transaction. You may need to confirm the transaction in your connected wallet (e.g., MetaMask) to complete the wrapping process.
3. **Confirmation**: After the transaction is confirmed on the blockchain, your ETH will be converted into wETH, ready for use in ERC-20 compatible DeFi applications.

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

**Why Wrap ETH?**

Wrapped ETH is crucial for participating in various DeFi protocols, as it makes your ETH compatible with ERC-20 standards, allowing you to use it in trades, liquidity pools, and other yield-generating strategies on Mangrove and other platforms.


# Fee Rewards

Mangrove is reserving the possibility to distribute rewards based on the fees you paid while trading on  Mangrove.


# How the programs Work

Rewards are token rewards distributed in exchange of the fees paid while trading on Mangrove. Creating offers (posting limit orders) does not incur any fees, thus no rewards. The only way is to consume offers that are posted on the Mangrove Book.

{% hint style="warning" %}
A market order on mangrove does not generate fees automatically, thus there could be no rewards distributed for given market orders.
{% endhint %}

Typical fees for a market order that consumes Mangrove Orders are 2 bips (0.02%). Let's take this example:

You sell 1 WETH for 2000 USDC. Fees are going to be 0.4 USDC. Let's say this program redistributes 1 MGV per dollar, you will earn 0.4 MGV tokens.

Each program will contain the following parameters:

| Parameter     | Desccription                                                                       |
| ------------- | ---------------------------------------------------------------------------------- |
| Program range | timestamps for start and end (in UNIX seconds)                                     |
| Token         | The token with which the fees are paid                                             |
| Multiplier    | The multiplier to get the number of rewards from the fee                           |
| Budget        | Maximum rewards distributed (rewards will stop flowing when the budget is reached) |


# Current programs

<details>

<summary>Fees program April 2025 (April 7th to May 7th)</summary>

<table><thead><tr><th width="202.796875">Token</th><th>Rewards per token</th></tr></thead><tbody><tr><td>USDC, EURC</td><td>27 MGV</td></tr><tr><td>WETH, cbETH, wstETH, superOETHb </td><td>43,200 MGV</td></tr><tr><td>cbBTC</td><td>2,160,000 MGV</td></tr></tbody></table>

</details>


# Vault LP programs

### Overview

Mangrove is launching a series of Liquidity Provider (LP) reward programs to incentivize liquidity provision across different trading pairs. Each program is designed to reward users who provide liquidity to specific vaults with MGV tokens.


# How the Programs Work

### Program Structure

* Each vault has its own dedicated reward program
* Programs run for a fixed duration (typically one month)
* Rewards are distributed continuously based on users' LP token balances
* Each program has a predetermined budget (maximum rewards)
* Important: Program parameters (budget and duration) may be adjusted upward only

### Reward Distribution

* Rewards flow continuously to LP token holders
* The reward rate is specified per day
* Users earn rewards proportional to their share of the total LP tokens
* Early liquidity providers may benefit from a slight advantage as the share value typically grows over time

### Important Note for Early LPs

Early liquidity providers have a natural advantage in these programs. As more users join and the total value in the vault increases, the share value of LP tokens will gradually rise. This means:

* Early LPs will receive slightly higher rewards per dollar of liquidity
* The reward rate per dollar will naturally decrease as more liquidity joins
* This decrease is typically minimal and helps reward early supporters

### Reward Claims

Please note that rewards will be claimable once the MGV token becomes transferrable. Until then, rewards will continue to accumulate based on your LP positions.


# Current programs

All Vault LP programs currently running on Arbitrum

Below are the active LP programs launching on April 7th, 2025, and running for one month until May 7th, 2025. Each program has a budget of 600,000 MGV tokens.

| Trading Pair | Vault Address | Reward Rate                |
| ------------ | ------------- | -------------------------- |
| WETH-USDC    | 0xCC1b...3C52 | \~0.01 MGV per $ per day   |
| cbBTC-USDC   | 0x365c...18ce | \~0.01 MGV per $ per day   |
| cbBTC-EURC   | 0xC95a...2119 | \~0.01 MGV per $ per day   |
| wstETH-WETH  | 0x8ec6...2bc8 | \~20 MGV per ETH per day\* |

\*Note: For the wstETH-WETH pair, a static value of 2000 USD per ETH is used for reward calculations. This means the reward rate is effectively around 20 MGV per ETH (not per dollar) per day.

#### Program Design Rationale

The reward rate of approximately 0.01 MGV per dollar per day has been carefully chosen to:

* Provide meaningful incentives for liquidity providers
* Ensure sustainable distribution of rewards throughout the program duration
* Create a balanced reward structure across different trading pairs


# Earning rewards

### Participation

To participate in these programs:

1. Provide liquidity to any of the listed vaults
2. Hold your LP tokens
3. Rewards will automatically accrue based on your LP token balance
4. Rewards will become claimable once the MGV token is transferrable

### Monitoring Your Rewards

Your rewards will accumulate continuously based on your LP token balance. The actual rewards earned may vary slightly depending on:

* The total liquidity in the pool
* The duration you maintain your position
* The timing of your entry relative to other LPs

### Program Flexibility

Please note that while the initial parameters (budget and duration) are set, these values may be adjusted upward in the future. Any such adjustments will only increase the rewards or duration, never decrease them.


# Example

### Reward Calculation Example

Let's walk through a hypothetical example to illustrate how the rewards mechanism works:

### Scenario

* A user deposits the equivalent of $1,000 into the USDC-USDT vault
* They maintain this position for 10 days
* The reward rate is 0.01 MGV per dollar per day

### Rewards Calculation

1. Daily MGV rewards = $1,000 × 0.01 MGV/$ = 10 MGV per day
2. Total MGV rewards for 10 days = 10 MGV × 10 days = 100 MGV

### Hypothetical Value Example

***IMPORTANT DISCLAIMER: The following calculations use a hypothetical token value for illustration purposes only. This is NOT the actual or projected value of the MGV token. Users should not rely on these figures for investment decisions.***

To help understand the magnitude of rewards, let's use a purely hypothetical example value:

* Assuming a hypothetical FDV (Fully Diluted Valuation) of $100,000,000:
  * With total supply of 1B MGV, each MGV would be valued at $0.10
  * 100 MGV earned would be equivalent to $10 in rewards value for 10 days
  * This would represent an annualized rate of approximately 36.5% APR on the $1,000 principal

### Important Notes

* The actual value of MGV tokens has not been determined
* The example above uses arbitrary values for illustration only
* Actual returns will depend on:
  * The future market value of MGV tokens once transferrable
  * Changes in total liquidity in the pool
  * Duration of liquidity provision
  * Potential adjustments to reward rates
  * Market conditions and other factors


# Previous programs

list of the previous Vault LP programs (Mangrove Vault)

<details>

<summary>Arbitrum - December 2024 to January 2025</summary>

Below are the active LP programs launching on December 23rd, 2024, and running for one month until January 23rd, 2025. Each program has a budget of 600,000 MGV tokens.

| Trading Pair | Vault Address | Reward Rate                |
| ------------ | ------------- | -------------------------- |
| ARB-USDC     | 0x1708...8402 | \~0.01 MGV per $ per day   |
| WETH-USDC    | 0x533f...0cC1 | \~0.01 MGV per $ per day   |
| WBTC-USDT    | 0xD972...4B7B | \~0.01 MGV per $ per day   |
| weETH-WETH   | 0x1700...b12a | \~35 MGV per ETH per day\* |
| USDC-USDT    | 0xa99C...C19D | \~0.01 MGV per $ per day   |

\*Note: For the weETH-WETH pair, a static value of 3500 USD per ETH is used for reward calculations. This means the reward rate is effectively around 35 MGV per ETH (not per dollar) per day.

#### Program Design Rationale

The reward rate of approximately 0.01 MGV per dollar per day has been carefully chosen to:

* Provide meaningful incentives for liquidity providers
* Ensure sustainable distribution of rewards throughout the program duration
* Create a balanced reward structure across different trading pairs

</details>


# MS2 Program (closed)

MS2 (Mangrove Season 2), Mangrove's second Incentives Program is now closed. This program was on arbitrum from November 2024 to February 2025.

### Introduction

Mangrove’s incentive program rewards users for the effective trading volume they generate. Through a straightforward farming model, participants earn MGV tokens—Mangrove DAO’s governance token—for each dollar in trading volume which they generate (either as maker or taker). This document describes the process for calculating MGV token rewards.

The parameters affecting MGV’s yield may change over time, and any changes will be publicly announced regularly. At the beginning of each [epoch](/mgv-incentives/ms2-program-closed/epochs-and-updates)—spanning two weeks—the total amount of MGV available for claiming will be updated.

However, the principles behind the MGV incentives program are set.

Mangrove's incentive program is carefully designed to:

* Adjust Dynamically: By varying the [reward rate ](/mgv-incentives/ms2-program-closed/how-rewards-are-calculated/reward-rate-r)in response to changes in platform trading volume.
* [Encourage quality orders:](/mgv-incentives/ms2-program-closed/how-rewards-are-calculated/adjusted-volume-for-makers) By rewarding orders close to the market price.
* [Differentiate incentives by use cases](/mgv-incentives/ms2-program-closed/mgv-token-allocation-per-user-type): By allocating rewards differently among makers, takers, and Kandel's LPs, adjusting parameters as needed while keeping the core principles unchanged.

Note: MGV incentives are exclusively available for transactions on Arbitrum.


# How Rewards Are Calculated

### The Core Philosophy: Rewarding Absolute Effort

Our program marks a shift from rewarding relative effort (comparing users against each other) to rewarding absolute effort based on actual trading volume. This approach ensures:

* Predictable rewards, unaffected by other users' activity
* Earnings based directly on your contribution to the ecosystem
* A reward structure that scales with market growth


# Reward Rate ρ

The reward rate (ρ) is the conversion rate between the effective trading volume and the amount of MGV tokens earned. This rate serves as the foundation of Mangrove’s transparent and balanced incentive system, ensuring participants are rewarded for their genuine contributions to market activity.

The ρ is subject to adjustment based on the volume to meet the target of total MGV distributed per epoch and per user type. In general, the ρTaker is typically assumed to be 10 times smaller than the ρMaker (meaning makers can receive up to 10 times more rewards than takers).

The traded volume—whether adjusted or not—is expressed in the quote currency of the market. For example, on the weETH/WETH market, the volume is measured in ETH. The ρ coefficient (taker or maker) serves as a conversion factor, expressed in MGV per quote, translating the traded volume into MGV rewards. This simple conversion mechanism ensures a transparent link between user activity and the rewards earned, aligning incentives across the ecosystem.


# Takers Rewards

Taker rewards are directly proportional to the volume of trades they generate (i.e., the offers they consume). For example, if during a specific period where ρTaker remains constant, a taker generates V (in quote), their reward will be calculated as:

$$
Reward=ρTaker×V
$$


# Adjusted Volume for Makers

Incentive programs in DeFi often face  a key challenge: ensuring high-quality orders for a healthy market with competitive prices.

The core of our reward system uses an adjusted volume calculation that considers both the quality and age of orders. Adjustments are critical to ensure that makers who provide competitive, high-quality liquidity receive the most rewards, aligning incentives with market health and sustainability.

The adjusted volume calculation incorporates the following elements:

1. **The historical spread quality:**&#x20;

Orders placed closer to the mid-price receive higher rewards due to tighter spreads. Tighter spreads improve market competitiveness and favor makers who offer the best prices for takers.

2. **The historical volume consistency:**&#x20;

The system evaluates whether the maker’s historical activity aligns with the effective volume generated over time. Consistent contributions are rewarded proportionally.

3. **Historical window (historicity):**

A “window” is used to assess past activity. This window can be adjusted (made narrower or wider) to more or less account for long-term contributions or [adapt to specific users](/mgv-incentives/ms2-program-closed/mgv-token-allocation-per-user-type) ([like Kandel’s Makers](/mgv-incentives/ms2-program-closed/mgv-token-allocation-per-user-type/specific-allocation-for-kandel-users-and-vault-managers)).


# How to Maximize Your Score

To maximize your rewards, focus on:

1. Keeping offers active: Longer live offers before execution earn more rewards.
2. Competitive pricing: Tighter spreads near the mid-price earn greater incentives.
3. Consistent order volumes: Regular activity over time ensures higher scores.

Together, these factors foster a healthy, competitive market where genuine participation is naturally rewarded.


# MGV Token Allocation per User Type

Mangrove allocates rewards differently across its three main user types:

* Makers: Users who post offers to the market.
* Takers: Users who accept existing offers.
* Kandel’s LPs: Liquidity providers using Kandel strategies, which involve placing orders across various price points.

Each group receives MGV tokens based on their contribution to the market, with special attention given to Kandel’s LPs for their role in providing liquidity across price ranges.

Mangrove DAO's Ecosystem Council defines the total amount of MGV allocated during an epoch and how it is distributed to each type of usage. This announcement is public and shared on our social channels.


# Specific Allocation for Kandel users and vault managers

Because the core principle of MGV's incentive program is the effective volume traded, particular attention is given to Kandel users. Kandel is a market-making strategy that involves posting orders along a price range, providing liquidity across various price points. To support this, a parameter in the reward calculation for Kandel makers differs from that of general makers.

To account for the influence of historical data, we have established a "[historical window](/mgv-incentives/ms2-program-closed/how-rewards-are-calculated/adjusted-volume-for-makers)" that determines how past activity impacts reward calculations. To maintain the quality of offers on Mangrove’s DEX, this window is typically wider for makers, giving more weight to past data in the calculations. However, this approach can unintentionally reduce the eligible volume for rewards in the case of Kandel makers, as their orders often remain far from the mid-price for extended periods. To address this, the window for Kandel users is narrower and specifically adjusted to ensure they are not unfairly penalized while still upholding the integrity of the reward system.

Considering this, Kandel benefits from an additional reserve of incentives and specific parameter adjustments to ensure that vault managers and LPs are well rewarded for their efforts.


# Community Contributors

Mangrove has launched and will maintain social quests on [Galxe](https://app.galxe.com/quest/mangrovedao/GC9ANtVkLU) and other platforms. Our "community contributors" who participate in these quests and other activities that promote the Mangrove community will also be rewarded in points, leading to a future allocation in MGVs.


# Incentives with a custom strategy

With mangrove you can write your own contracts in order to create offers and bring liquidity programmatically. In order to track ownership for the length of the incentive program, use the API from `MangrovePoints.sol`.

## MangrovePoints

MangrovePoints is a smart contract designed to keep track of the custom maker contract links with their owners. This contract allows for the management of operators for accounts, providing a flexible and secure way to handle permissions.

`MangrovePoints` is deployed on Arbitrum at `0x26e9e34839b5f150B66eA30cd8B503FFa1B4BFd4`.

### How to Use

To use the `MangrovePoints` contract in your custom maker contract, follow these steps:

1. Include the IMangrovePoints interface in your contract:

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

/**
 * @title IMangrovePoints
 * @notice Interface for the MangrovePoints contract
 */
interface IMangrovePoints {
  /**
   * @notice Emitted when an operator is set for an account
   * @param account The account for which the operator is set
   * @param operator The address of the operator
   */
  event OperatorSet(address indexed account, address indexed operator);

  /**
   * @notice Sets the operator for an account
   * @param account The account for which to set the operator
   * @param operator The address to set as the operator
   */
  function setOperator(address account, address operator) external;

  /**
   * @notice Returns the operator for a given account
   * @param account The account to check
   * @return The address of the operator for the given account
   */
  function operators(address account) external view returns (address);
}
```

```solidity
import {IMangrovePoints} from "./IMangrovePoints.sol";
```

2. Call the `setOperator` method directly from your contract:

```solidity
IMangrovePoints mangrovePoints = IMangrovePoints(MANGROVE_POINTS_ADDRESS);
mangrovePoints.setOperator(address(this), OPERATOR_ADDRESS);
```

Replace `MANGROVE_POINTS_ADDRESS` with the deployed address of the MangrovePoints contract, and `OPERATOR_ADDRESS` with the address you want to set as the operator for your contract.

### Mangrove's Role

While the primary method for setting operators is through the custom maker contracts themselves, Mangrove also has the ability to add operators in cases where the contract may have missed calling this function. However, this is subject to certain conditions:

* There must be a proof linking the custom maker contract to the admin, deployer, or other authorized entity.
* It will be at Mangrove's discretion to accept or refuse any requests for operator assignment.

This feature ensures that legitimate contracts are not left without operators due to oversight or technical issues, while maintaining the integrity of the system.


# Epochs and Updates

Time is divided into epochs for several purposes:

* Distribution and Claimability: Rewards in MGV are continuously calculated and accrue over time. Users will be able to claim their earned MGV tokens at the end of each epoch, and once the MGV token becomes transferable.&#x20;
* Rewards page: Earned MGV tokens are shown on the dApp's "[Rewards](/dapp-guide/rewards)" page.
* Announcements: Any changes to incentive parameters—including the allocation to types of usage and the reward rates ρ—are announced at the start of a new epoch.
* Core principles remain unchanged: While the [Mangrove’s DAO Council](/governance/councils) may adjust allocations and parameters during each epoch to respond to market conditions, the core principles of fairness, transparency, and rewarding genuine activity remain steadfast.

The distribution will consist of 6 epochs lasting 2 weeks each. Here are the dates with the unix timestamps (in second) :

Date: Tuesday, 11/19/2024, 12 GMT+1 - Timestamp: 1732014000

Date: Tuesday, 12/3/2024, 12 GMT+1 - Timestamp: 1733223600

Date: Tuesday, 12/17/2024, 12 GMT+1 - Timestamp: 1734433200

Date: Tuesday, 12/31/2024, 12 GMT+1 - Timestamp: 1735642800

Date: Tuesday, 1/14/2025, 12 GMT+1 - Timestamp: 1736852400

Date: Tuesday, 1/28/2025, 12 GMT+1 - Timestamp: 1738062000

Each epoch will have a budget of 1.6M MGV.


# MS1 Program (closed)

MS1 (Mangrove Season 1), Mangrove's first Incentives Program is now closed.


# Intro

### TL;DR[​](https://docs.mangrove.exchange/general/points/#tldr) <a href="#tldr" id="tldr"></a>

The Mangrove Season 1 Points Program rewards active participants, known as 'Makers' (liquidity providers) and 'Takers' (traders) in the Mangrove ecosystem. Points are allocated for trading activities, liquidity provision, referrals, and community participation. The scheme is structured as follows:

$$
Total points=(Trading Points+LP Points)∗Boosts+Referral Points
$$

Community Points do not contribute to Total Points for Leaderboard Rankings. They will be allocated specifically after the MS1 program concludes

* **Trading Points**: Calculated based on trade volume, with different weightings for each market. Includes market, limit and amplified orders,where the limit order is partially filled with market order
* **Liquidity Provision (LP) Points**: Derived from uptime, liquidity's proximity to mid-price, and generated volume and also market weighted. Includes limit orders, amplified orders and strategies.
* **Boosts**: A tiered level system increasing LP and trading points, determined by consistent activity and volume levels.
* **Referral Points**: Gives a 10% bonus in points for both referee and referrer, based on the referee's LP and trading points.
* **Community Points**: Gives points to past and future active participants in MangroveDAO-organised campaigns.

Stay updated with these opportunities by following [@MangroveDAO on X](http://x.com/MangroveDAO) and joining the MangroveDAO Discord community.


# Trading Points

Takers earn points daily, based on their trading volume within the Mangrove DEX and a specific weight for each market.

For example, in the WETH/USDB markets, every $1 traded equals 1 point, motivating participants to increase their trading activity.

### Liquidity Provision Points​ <a href="#liquidity-provision-points" id="liquidity-provision-points"></a>

One of the core goals of the MS1 Program is to reward a balanced orderbook, in order to do this, we currently reward those who keep their positions balanced at a higher rate than those who do not.

Because of this, you will gain greater rewards if you have bids and asks on the book at the same time, if you look at the paper linked below, you will see this:

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

What this means is that your points are based on the minimum points you gained from your asks and your bids. With no asks for example, you will get only a small reward.

Makers contribute to the ecosystem's health by providing liquidity, earning points for their crucial role, with a predetermined weight for each market. The best quality liquidity close to the market price and on both sides of the book gets rewarded the most.The distribution of points among makers isn't purely proportional to the volume generated by their liquidity.

The calculation encapsulates the essential contributions of Makers, rewarding consistency (uptime), market relevance (proximity to the spread), and the effectiveness of the liquidity provided (volume).

**Competitive Makers**: These are the pillars of market efficiency, providing liquidity that's on both sides of the book and closely aligned with the current market prices, thereby ensuring minimal spreads.

**Non-Competitive Makers**: Recognized for adding to the market's liquidity pool, these Makers might offer asymmetric liquidity at prices farther from the market's current rate. The program still rewards them but emphasizes encouraging more market-conducive offers over time.

For a detailed description of the MS1 points calculation, refer to the MS1 Whitepaper.


# Boost

The program features a boost mechanism, where participants' trading and liquidity provision volumes over a 7-day period determine their boost level. Higher activity levels result in greater boosts, amplifying the total points earned. To maintain or attain a higher boost level, a participant needs to consistently engage in higher volume trading or generating volume through its liquidity.

<table><thead><tr><th width="97">Level</th><th width="171">Boost</th><th>Requirements in a 7 day epoch</th></tr></thead><tbody><tr><td>0</td><td>x1 (No Boost)</td><td>For volume between $0 and $9,999.</td></tr><tr><td>1</td><td>x1.75</td><td>For volume between $10,000 and $19,999.</td></tr><tr><td>2</td><td>x2.5</td><td>For volume between $20,000 and $49,999.</td></tr><tr><td>3</td><td>x3</td><td>For volume between $50,000 and $99,999</td></tr><tr><td>4</td><td>x3.5</td><td>For volume between $100,000 and $499,000.</td></tr><tr><td>5</td><td>x4</td><td>For volume of $500,000 or more.</td></tr></tbody></table>

This tiered system ensures that the more a participant trades or generates volume, the higher the boost they can achieve, incentivizing consistent and increased trading activity.

Finally, each participant's boost is applied to the LP + trading points earned from both taker and maker activities. The level of boost depends on the participant's level, which in turn is determined by their traded and generated volume.

For instance, a participant earning 100,000 taker and maker points at Level 1 will receive a x1.75 boost, resulting in a total of 175,000 points.


# Referral Points

Encouraging ecosystem growth and a tight community, the Referral Program rewards users who introduce active traders and liquidity providers to Mangrove. Both referrer and referee receive a 10% bonus on trading and LP points.

### How does it work?[​](https://docs.mangrove.exchange/general/points/referral-points#how-does-it-work) <a href="#how-does-it-work" id="how-does-it-work"></a>

1. Access the referral page on [Mangrove dApp](https://app.mangrove.exchange/referrals)
2. Select “Create a referral link” and sign the transaction on your wallet
3. Share your link on social media and with your friends
   * For each maker & trader point they generate they get 10% extra as Referral points.
   * You earn 10% of their boosted maker and taker points as Referral points. Their points are unaffected by the extra 10% points that you receive.

🥳There is no limit on the number of referrals. The more friends join the party, the more points for you!

🎈You receive your referral points based on the boosted amounts of points earned by the referee. However your own boost level doesn’t affect your referral points.

#### Example[​](https://docs.mangrove.exchange/general/points/referral-points#example) <a href="#example" id="example"></a>

1. Bob refers Alice to Mangrove.
2. Alice earns 100 points from her market volume.
3. Alice has her boost applied, giving her an end total of 250 points

* Alice's bonus: Receives an extra 25 points (0.1 \* 250) as a referral bonus, totaling 275 points.
* Bob's benefit: Earns 25 points (10% of Alice's boosted 250 points) for referring Alice.

This referral program rewards both Alice for her activities and Bob for bringing a new participant to Mangrove.


# Community Points

The MangroveDAO may launch campaigns during the MS1 Points Program to reward past or current active traders. These campaigns are designed to assist in the growth of Mangrove and can provide participants with benefits.

### Testnet & Beta Mainnet Participants Benefits[​](https://docs.mangrove.exchange/general/points/community-points#testnet--beta-mainnet-participants-benefits) <a href="#testnet--beta-mainnet-participants-benefits" id="testnet--beta-mainnet-participants-benefits"></a>

To facilitate the testing of Mangrove Exchange, the Mangrove Testnet was launched in March 2023 on the Polygon testnet. Following this, the Mangrove Beta Mainnet began in July 2023 on the Polygon Mainnet.

#### Testnet NFT Holders Benefits[​](https://docs.mangrove.exchange/general/points/community-points#testnet-nft-holders-benefits) <a href="#testnet-nft-holders-benefits" id="testnet-nft-holders-benefits"></a>

During the testnet, participants were able to claim 3 different NFTs on Galxe. Depending on the highest NFT, these participants’ wallet addresses will have access to a specific Boost Level for a period of 4 weeks and a points allocation, to reward their early contribution to the protocol.

* [Mangrove Seed](https://opensea.io/collection/mangrove-seed-nft): 5,000 Community points (equivalent to $5,000 volume traded)
* [Mangrove Tree](https://opensea.io/collection/mangrove-tree-nft): Level 1 (x1.75 boost) and 10,000 Community points (equivalent to $10,000 volume traded)
* [Mangrove Forest](https://opensea.io/collection/mangrove-forest-nft): Level 2 (x2.5 boost) and 60,000 Community points (equivalent to $60,000 volume traded)

We do not encourage that you buy an NFT on the secondary market, because we have to take a snapshot on the Blast Mainnet Day. If you buy afterwards, you will not be eligible for any bonus or rewards.

#### Beta Mainnet Participants Benefits[​](https://docs.mangrove.exchange/general/points/community-points#beta-mainnet-participants-benefits) <a href="#beta-mainnet-participants-benefits" id="beta-mainnet-participants-benefits"></a>

Wallet addresses that participated in the Beta Mainnet are rewarded with a special Boost Level for a period of 4 weeks and a points allocation based on their trading volume. This includes:

* Level 3 (x3 boost)
* Community points depending on volume generated and volume traded, to be distributed later.


# Parameters

The Mangrove Season 1 Points Program can evolve from epoch to epoch to encourage the most beneficial behaviors for a specific epoch.

[This table](https://docs.google.com/spreadsheets/d/1cCckTUMtyjvrdyc5z6wxM4w8FCJobqbsmA3ejxltrFI/edit#gid=0) recaps all epochs, boosts and parameters.


# Technical Insights

Mangrove has thought a lot about making sure the points system is fair and can't be easily tricked. The underlying maths discourages cheating, like making many small trades to yourself to earn points.

The whitepaper elaborates on the complex calculation formulas for determining points, aimed at accurately reflecting each participant's contribution to the DEX.

A unified scoring system aggregates points across different roles (maker/taker) and markets, allowing for a comprehensive leaderboard that reflects participants' overall contributions. This aggregation is first per day, but the daily points are only indicative, as the points are further adjusted per epoch to consider the overall contribution.

The whitepaper discusses how this system flexibly adapts to changing market conditions and participant behaviors to ensure ongoing engagement and market health.

Specific mechanisms are designed to counteract potential manipulations such as washtrading and Sybil attacks. Where a user might try to game the system by splitting activity across multiple addresses, the scoring formula advantages unified, consistent liquidity provision over fragmented efforts. To secure points, users need to reach a minimum volume across the period.

The program employs detailed mechanisms to ensure that splitting liquidity does not provide an unfair advantage, thereby maintaining fairness and integrity within the ecosystem.

#### Bounties for whistleblowers[​](https://docs.mangrove.exchange/general/points/technical-insights#bounties-for-whistleblowers) <a href="#bounties-for-whistleblowers" id="bounties-for-whistleblowers"></a>

If a user provides proof (not suspicions) of washtrading which is banned, they will receive a bounty in the form of community points. We define washtrading as transactions where the maker and taker wallets are the same entity.


# MS1 FAQ

* How do you LP on Mangrove?

  Mangrove LPs, also called makers, are the users that deploy liquidity via limit orders and Kandels. The MS1 Points Program main goal is to attract good quality liquidity to Mangrove so LPs get a higher share of the rewards vs takers, also known as traders.
* Who are Mangrove traders?

  You are a trader when your swap using market orders, Mangrove traders correspond to takers of orders on Mangrove markets.
* I have proceeded to >$10k of transactions, how come I have no boost?

  Boosts are computed along a period of roughly one week and only applied to the following epoch, so there will be a delay between the moment you generate volume, and when you receive boosted points. More details on the [boost section](https://docs.mangrove.exchange/general/points/boosts)
* I have traded $500k but received few points?

  The MS1 Points Program aim is to shape Mangrove’s order book with the best price and market depth of Blast. As such the program favours Liquidity Providers (makers) over traders (takers).
* How to optimise your MS1 farming?

  The MS1 Points Program aim is to shape Mangrove’s order book with the best price and market depth of Blast rather than make everyone happy. As such users that contribute to making Mangrove liquidity Blast’s reap the most rewards. Typically the program favours market makers, with competitive liquidity meaning its positioned on both sides of the book, and liquidity that is very close to the market price to reduce the spread. More details in section Trading & LP Points or on the whitepaper.

  To make this system more equitable, Mangrove Kandel is a complex market making strategy available to any user. This is one of the easiest ways to develop and efficient market strategy. It provides very high liquidity for Mangrove’s order book, on both side of the book, with good upside. Feel free to join the Kandel Alpha Chat for guidance
* Why are points and incentives so concentrated on the top of the leaderboard?

  The current points distribution is based on the formula shared in the whitepaper and parameters shared in the section Parameters per Epoch. It is a fair distribution given it is impartial; rewarding the behaviours required for this goal without favouritism or discrimination. Users that take the time to truly understand the game can reach the top of the leaderboard, extremely quick. We’ve seen for example a user make 1B points in less than a week, surpassing other farmers. Given the complexity that can be implemented in Mangrove’s programmatic orders, sophisticated investors are in a better position to optimise their strategies for farming.


# Disclaimer

We reserve the right to modify point and level calculations at any time.

Wash trading is strictly prohibited in the MS1 Points Program, and any participant found engaging in wash trading will have their points revoked. For more information, refer to the Terms & Conditions page.


# General Governance

Mangrove DAO’s governance model combines multi-stakeholder general governance with specialized councils, analogous to legislative and executive branches in a parliamentary system.

General governance sets strategic directions and policies,, which encompasses:

* **Strategic Decision-Making**: Overseeing high-level goals and strategies of the DAO.
* **Council Oversight**: Electing, funding, and overseeing council decisions.
* **Operational Oversight**: Evaluating and approving key operational proposals initiated by the councils or the community.
* **Metagovernance**: Updating and refining governance parameters and processes.


# Key Stakeholders

Distributing influence among stakeholders is done by defining groups or classes of voters that have a set share of the overall voting power, regardless of the number of members in each group.

This ensures that the main interest groups are always represented in strategic decisions. Neither the turnover within each group nor the transfer of tokens can alter this balance.

At Mangrove, one third of the voting power to each of the three main groups of stakeholders: [Token Holders](/governance/general-governance/key-stakeholders/token-holders), [Builders](/governance/general-governance/key-stakeholders/token-holders/builders), and [Pods](/governance/general-governance/key-stakeholders/pods):

<figure><img src="https://docs.mangrove.exchange/img/assets/dao-multistakeholder-pie.png" alt="" width="285"><figcaption></figcaption></figure>

Each group has a third of the voting power. This is not an initial distribution scheme, but a permanent allocation of power to each class of stakeholders.

Votes are counted as the aggregated percentage of voting of each group.

*NB: Individuals or entities may hold memberships in more than one group. They have the option to consolidate these memberships under a single address for voting or maintain separate addresses to vote independently within each group.*


# Token Holders

Token Holders is the largest group participating in the governance of Mangrove DAO. MGV is the Mangrove's governance token, and anyone owning some can either vote or delegate their voting power to someone else. Their participation ensures that a wide range of voices are heard, particularly those with a vested interest in the protocol.

The voting power of a member of this group is directly proportional to the number of tokens held by or delegated to the voting address. The total number of vested MGVs is taken into account, regardless of whether they have been claimed or not.

*NB: The MGV token is currently not transferable and not available on public markets. It is expected that the DAO will start distributing MGVs to Mangrove's users, liquidity providers, market makers, and developers in early 2024.*


# Builders

The focus of Builders is on ensuring the ecosystem thrives sustainably over the long term. Builders bring a deep understanding of the protocol’s needs and a commitment to its ongoing development and growth.

The voting power of Builders is based on an activity score that reflects their period of contribution and intensity of collaboration (full-time or part-time). Quadratic voting is applied to balance voting power discrepancies within the group.

The distribution of voting power within this group is self-determined and may evolve over time without external validation.

<figure><img src="https://docs.mangrove.exchange/img/assets/dao-builders-directory2.png" alt=""><figcaption><p>Builders Directory</p></figcaption></figure>


# Builders

The focus of Builders is on ensuring the ecosystem thrives sustainably over the long term. Builders bring a deep understanding of the protocol’s needs and a commitment to its ongoing development and growth.

The voting power of Builders is based on an activity score that reflects their period of contribution and intensity of collaboration (full-time or part-time). Quadratic voting is applied to balance voting power discrepancies within the group.

The distribution of voting power within this group is self-determined and may evolve over time without external validation.

<figure><img src="https://docs.mangrove.exchange/img/assets/dao-builders-directory2.png" alt=""><figcaption><p>Builders Directory</p></figcaption></figure>


# Pods

Mangrove protocol is permissionless; anyone can use it to create and run their own *smart offers* or strategies. In order to incentivize talents to build long-lasting, value-added products on top of Mangrove, the DAO offers a Pod program. Pods have a say in general governance, and they are entitled to receive a share of the fee their generate on Mangrove markets.

Enabling the most active independent developers and strategists to participate in the governance is a guarantee of neutrality and permissionless nature of the protocol, providing them with a reliable foundation for developing their businesses.

Initially, each pod is given equal voice until their economic contributions can be objectively measured on-chain and there is a sufficient number of active pods. Subsequently, a pod’s voting power will be proportional to its economic contribution to the protocol. The transition to this new model of voting power distribution will be decided by the general governance.

Pods are curated by the Ecosystem Council.

<figure><img src="https://docs.mangrove.exchange/img/assets/dao-pods-directory.png" alt=""><figcaption><p>Pods Directory</p></figcaption></figure>

[Previous](https://docs.mangrove.exchange/general/governance/general-governance/key-stakeholders/builders)


# Guardians

Mangrove DAO Guardians play a crucial role in upholding the integrity and execution of the DAO's governance model. Independent from the Mangrove core team and [Councils](/governance/councils), Guardians are responsible for implementing specific DAO decisions, notably those concerning Councils' elections and budget allocations.

**Role and Responsibilities**[**​**](https://docs.mangrove.exchange/general/governance/general-governance/guardians#role-and-responsibilities)

Guardians are responsible for implementing specific DAO decisions, notably those concerning Councils' elections and budget allocations. This arrangement ensures that Councils cannot self-elect or assign budgets independently, safeguarding the DAO's democratic governance principles.

**Selection and Composition**[**​**](https://docs.mangrove.exchange/general/governance/general-governance/guardians#selection-and-composition)

Guardians are highly respected individuals within the community, known for their integrity and reputation. Their selection, initially facilitated by the Mangrove Association, emphasizes independence and trustworthiness. Each Guardian acts as a signer on a 5/9 multisig Safe, dedicated solely to executing Mangrove DAO decisions.

The current Guardians are:

* Adli Takkal Bataille, le Cercle du Coin (Co-founder)
* Astrid Woollard, SMAPE Capital (Co-founder)
* Clara Gromaches, dOrg (Operations)
* Disiaque, Mangrove Association
* Justice Conder, Polygon
* Pascal Tallarida
* Pierre Laurent, Atka (Co-founder)
* Romain Figuereo, Paladin (Founder)
* Tamara Helenius, Commons Stack (Co-founder)

The general governance renews Guardians on a regular basis.

**Operation and Governance**[**​**](https://docs.mangrove.exchange/general/governance/general-governance/guardians#operation-and-governance)

The multisig Safe operated by the Guardians is utilized exclusively for actions authorized by the DAO's governance processes, and tagged as such in associated proposals. This mechanism ensures transparency and accountability in executing critical decisions, reinforcing the Guardians' role as impartial executors.


# Governance Process


# Initial Discussions

**General Discussions**

The Mangrove DAO forum’s [general](https://forum.mangrove.exchange/c/governance/general/8) category is a space for open discussions on governance-related topics.

**Discussing Proposals**

For more focused proposal development, participants should use the [temp check](https://forum.mangrove.exchange/c/governance/temp-check/9) category. This section is designed to gauge stakeholder sentiment and foster informal debate around specific ideas that may lead to formal proposals.

Posts in this category should be structured as follows:

* **Header**: Includes the title, authors, and date of the post, and specifies the type as either ‘protocol’ or ‘ecosystem’.
* **Body**:
  * **Summary**: A concise overview of the post’s content.
  * **Rationale**: The reasoning behind the idea or question.
  * **Specification**: Detailed description of the proposal or idea.
  * **Disclaimer** (optional): Any necessary legal or contextual disclaimers related to the post.
  * **Next Steps** (optional): Suggested actions or considerations following the discussion.

Anyone can start a Proposal in the temp check category.

[<br>](https://docs.mangrove.exchange/general/governance/general-governance/governance-process/)


# Proposals

Proposals are formalized and posted by Councils in the [proposals](https://forum.mangrove.exchange/c/governance/proposals/10) category of the Mangrove DAO forum. These proposals may originate from community-submitted ideas discussed in the [temp check](https://forum.mangrove.exchange/c/governance/temp-check/9) category or from the Councils themselves.

The structure of proposals mirrors that of the discussions in section 3.2, with the addition of a unique identifier. Proposals should include:

* **Header**: A unique ID constructed as ‘MIP’ followed by a chronological number (e.g., MIP1, MIP2), title, authors, date, and type (protocol or ecosystem).
* **Body**: As outlined in section 3.2, including summary, rationale, specification, and optional disclaimer and next steps.

Proposals must be submitted on the forum for comments and deliberation at least 5 days before any voting occurs. This period is crucial for participatory deliberation, allowing proposals to be refined and improved based on community feedback. Authors are required to make all edits visible, either through tracked changes or by adding subsequent posts, ensuring that any modifications to the original proposal are easily identifiable.


# Voting

Voting is conducted on [Snapshot](https://snapshot.org/#/mangrove.eth). Votes can be initiated either by council members, or by token holders with at least 5% MGVs held/delegated. The following groups each represent one third of the total voting power in general governance:

* **MGV Token Holders**: Their voting weight is proportional to the number of held or vested tokens compared to the total circulating supply of MGVs.
* **Builders Group**: The voting power of Builders is based on an activity score reflecting their period of contribution and full-time engagement. Quadratic voting is applied to balance voting power discrepancies within the group.
* **Pods Group**: Comprising teams of strategists and developers, Pods initially have equal voting influence. Eventually, their voting power will be proportional to the economic value they generate for the protocol.

**Key voting parameters**

* Proposals must be posted in the [proposals](https://forum.mangrove.exchange/c/governance/proposals/10) category of the Mangrove DAO forum at least 5 days before voting on Snapshot.
* The voting duration should be a minimum of 5 days, include one weekend day, and not exceed 7 days.
* A quorum of 5% is required, calculated based on thrice the circulating supply of MGV tokens to equally empower Builders and Pods alongside MGV holders.
* Delegation is available to voters in every group.


# Execution

Councils are responsible for implementing strategies decided by the general governance.

The Protocol Council handles ‘protocol’ type proposals, while the Ecosystem Council manages ‘ecosystem’ proposals. On-chain executable proposals are processed by the relevant Council’s multisig.

Decisions that directly impact the Councils, particularly their member elections and budget allocation, are not managed by the Councils themselves to prevent conflicts of interest. Instead, these operations are executed by Guardians.


# Councils

Councils within Mangrove DAO are constituted, elected, and funded by the general governance, which also determines their mandates’ duration and composition.

While these Councils operate autonomously in managing day-to-day operations, they are accountable to the general governance, particularly for proposals exceeding their predefined mandates or for decisions requiring broader strategic alignment.

This structure ensures that the Councils act within the scope and strategy set by the general governance, while also maintaining the flexibility needed for effective operational management.


# Responsibilities

Mangrove DAO establishes two councils to address distinct areas requiring specialized skills:

* **Protocol Council**: Responsible for maintaining the Mangrove protocol, overseeing research, technical product management, devops, security operations, and the technical enforcement of governance decisions. It manages both on-chain and off-chain components, including extensions such as SDKs.
* **Ecosystem Council**: Takes on the economic and social aspects of Mangrove. Its responsibilities include the curation of public strategies, strategic roadmap development and management, attracting and supporting Pods, managing resources, implementing incentive programs, forming partnerships, and overseeing the DAO’s treasury.

The Councils focus on strategic oversight rather than direct task execution. They determine what needs to be accomplished within their areas of responsibility, delegate these tasks to suitable service providers, and monitor to ensure that all activities are completed timely, within budget, and according to specified standards.

Councils' responsibilities also include managing budgets, responding to community inputs, and preparing governance proposals as necessary.


# Elections

Mangrove DAO's general governance orchestrates the election of Council members for six-month terms, emphasizing a structured and transparent selection process.

**Candidacy Process**

Biannually, forum moderators initiate a new thread in the "[Councils/Membership](https://forum.mangrove.exchange/c/councils/membership)" category, inviting potential candidates to introduce themselves, their qualifications for the role, and their objectives for the term. This thread is made available at least one week before the election, allowing the community adequate time to evaluate each candidate. The requirements for candidates align with the distinct needs of each council:

* **Protocol Council** (5 seats): Candidates should possess knowledge in Mangrove technology, specifically smart contracts and SDKs, strategy development on Mangrove, Ethereum/EVM technology, and web/crypto security.
* **Ecosystem Council** (9 seats): Candidates are expected to have experience in DAO governance and operations, growth and incentive programs, crypto and traditional finance treasury management, marketing, and partnerships.

**Election Mechanics**

Elections are conducted on [Mangrove DAO's Snapshot space](https://snapshot.org/#/mangrove.eth), managed by the Ecosystem Council. This body oversees the inclusion of candidates and has the authority to exclude non-genuine applications, with all decisions transparently documented on the forum. The election comprises two separate votes: one for the Protocol Council and another for the Ecosystem Council, allowing voters to endorse multiple candidates up to the total number of seats available in each council. The voting period extends for a minimum of five days.

Upon conclusion of the voting period, the [Guardians](https://docs.mangrove.exchange/general/governance/general-governance/guardians) are tasked with updating the council compositions based on the election outcomes, adding newly elected members and removing those whose terms have expired.


# Budgets

Beyond electing members, the general governance also designates a budget for the Councils' term. This budget, crafted by the Ecosystem Council, equips the Councils with resources essential for their roles.

The budget proposal is presented for approval within a month following the election of new Council members, allowing for immediate financial readiness. Additionally, the Ecosystem Council has the option to propose a budget prior to their term's end, ensuring seamless financial continuity for incoming Councils.

Should the budget deplete before the term concludes, the Ecosystem Council may request additional funds from the general governance. Approved budgets are then transferred to the Ecosystem Council's multisig, facilitated by the Guardians.


# Guides and resources


# How to vote on a governance proposal

Active proposals active Mangrove DAO Snapshot are first published in the [Governance / Proposals](https://forum.mangrove.exchange/c/governance/proposals/10) category of Mangrove DAO forum. The forum topic includes a link to the Snapshot vote.

1. Head over to [Snapshot](https://snapshot.org/#/mangrove.eth)
2. Connect your wallet
3. Locate the proposal you want to vote for (or click the Snapshot link in the forum)
4. Cast your vote by following the prompts within Snapshot

Voters are either Token Holders, Builders, or Pods (or any combination):

* If you hold MGVs on your address, you're part of the Token Holder group. As such, your voting power in this group is equal to the number of your MGVs / total circulating supply of MGVs
* If you hold an active Mangrove Builder NFT, you are part of the Builder group. As such, your Activity Score is used to weigh your influence within this group, based on a quadratic voting formula
* If you hold an active Mangrove Pod NFT, you are part of the Pod group. As of now, all pods have the same weight within their group. As Pods' strategies take off and generate transaction fees on Mangrove, their on-chain economic contribution will be used to define their voting power

When you cast your vote, Snapshot displays your voting power across the 3 categories of stakeholders.


# How to delegate my voting power

If you don't have the time or resources to actively participate in Mangrove DAO's governance, you can still make your voice heard by delegating your voting power to anyone.

In order to do that, head over to Mangrove DAO Snapshot space, connect your wallet, and select the *Delegate* link in the sidebar, under *Proposals*:

<figure><img src="https://docs.mangrove.exchange/img/assets/dao-proposals-menu.png" alt="" width="260"><figcaption></figcaption></figure>

Snapshot's UI let you set the Ethereum address or ENS name you'll be delegating your voting power to:

<figure><img src="https://docs.mangrove.exchange/img/assets/dao-delegate.png" alt="" width="375"><figcaption></figcaption></figure>

When you delegate, all your voting power goes to the target address, regardless of its source: MGVs held or claimable, activity score as a Builder or as a Pod. You can undelegate or select another delegate at any time (but Snapshot takes into account the state of your delegation at the time of the start of voting period).


# How to access the Builders’ directory

Follow these steps to check the list of current [Builders](/governance/general-governance/key-stakeholders/builders):

* Access the Directory page on [https://directory.mangrove.exchange](https://directory.mangrove.exchange/)
* Click on the "Mangrove DAO Builders" tile
* The list of Builders is displayed. You can click on a row to view the Activity Score of each Builder:

<figure><img src="https://docs.mangrove.exchange/img/assets/dao-builders-directory.png" alt=""><figcaption></figcaption></figure>


# How to access the Pods’ directory

Follow these steps to check the list of current [Pods](/governance/general-governance/key-stakeholders/pods):

* Access the Directory page on [https://directory.mangrove.exchange](https://directory.mangrove.exchange/)
* Click on the "Mangrove DAO Pods" tile
* The list of Builders is displayed:

<figure><img src="https://docs.mangrove.exchange/img/assets/dao-pods-directory2.png" alt=""><figcaption></figcaption></figure>


# Snapshot configuration & membership

## Snapshot configuration

**Strategies configuration for multi-stakeholder voting**[**​**](https://docs.mangrove.exchange/general/governance/guides-and-resources/resources/snapshot-configuration#strategies-configuration-for-multi-stakeholder-voting)

**Strategies:**[**​**](https://docs.mangrove.exchange/general/governance/guides-and-resources/resources/snapshot-configuration#strategies)

We use three separate strategies so users can see in the UI what their voting weight is for each gov. group: Builders, Pods, and Token holders.

1. MGV token with delegation and including vested, claimable tokens
   * At the outer level, we use the [with-delegation](https://snapshot.org/#/strategy/with-delegation) strategy to allow delegation.
   * Inside that we use [erc20-balance-of](https://snapshot.org/#/strategy/erc20-balance-of) for owned MGV tokens and [dss-vest-unpaid](https://snapshot.org/#/strategy/dss-vest-unpaid) for vested but unpaid MGV tokens
   * Symbol: MGV
2. Builders Group Activity Score with delegation, quadratic-voting, and scaled to the circulating supply of MGV tokens
   * At the outer level, we use the [with-delegation](https://snapshot.org/#/strategy/with-delegation) strategy to allow delegation.
   * Inside that we use the [mangrove-station-qv-scaled-to-mgv](https://snapshot.org/#/strategy/mangrove-station-qv-scaled-to-mgv) which is built exactly for this
   * Symbol: vMGV-B
     * Rationale: reusing the symbol of the membership, adding "v" to signal that it's a voting token attached to the group, but not the same object.
3. Pods Group Activity Score with delegation, quadratic-voting, and scaled to the circulating supply of MGV tokens
   * At the outer level, we use the [with-delegation](https://snapshot.org/#/strategy/with-delegation) strategy to allow delegation.
   * Inside that we use the [mangrove-station-qv-scaled-to-mgv](https://snapshot.org/#/strategy/mangrove-station-qv-scaled-to-mgv) which is built exactly for this
   * Symbol: vMGV-P
     * Rationale: reusing the symbol of the membership, adding "v" to signal that it's a voting token attached to the group, but not the same object.

**Proposal configuration**[**​**](https://docs.mangrove.exchange/general/governance/guides-and-resources/resources/snapshot-configuration#proposal-configuration)

**Validation strategies:**

We use basic validation with a minimum score: Members with a voting power corresponding to more than 0.1% of the circulating supply can make proposals

* Snapshot requires an absolute number, so we calculated what 0.1% corresponds to as of 2024-01-08:
  * Circulating supply: 137,392,418.57352012 MGV
  * 0.1% of circulating supply: 137,392

**Voting configuration**[**​**](https://docs.mangrove.exchange/general/governance/guides-and-resources/resources/snapshot-configuration#voting-configuration)

**Quorum:**

We’d like to set the quorum to 15% of the total voting power. However, Snapshot requires an absolute number, so we’ve calculated what 15% corresponds to as of 2024-01-08:

* Circulating supply: 137,392,418.57352012 MGV
* Total voting power: 3 \* circulating supply = 412,177,255.72056036
* 15% of total voting power: 61,826,588

**Delegation**[**​**](https://docs.mangrove.exchange/general/governance/guides-and-resources/resources/snapshot-configuration#delegation)

The Delegation section is left unconfigured which (unintuitively) means that we use Snapshot’s built-in delegation system.\ <br>

## Membership

Membership of a governance group/Council is represented by ownership of an NFT (ERC-721). There is an NFT collection for each of the governance groups.

Each membership NFT controls a TBA (ERC-6551) and that TBA in turn is given tokens to represent the member’s attributes, such as their Activity Score (ERC-20, only relevant for Builders and Pods).

As we’d like members to be able to keep their membership NFTs after they leave Mangrove (it’s a nice memorabilia to have 🙂) we model active membership by giving the TBA an “Active Badge” token in a multi-token (ERC-1155) contract; When a member leaves a group, the active badge is burned.

The following diagram illustrates the setup:

<figure><img src="https://docs.mangrove.exchange/img/assets/dao-groupos-contracts.png" alt=""><figcaption></figcaption></figure>


# Links and adresses

## **Links**

<table data-header-hidden><thead><tr><th width="269"></th><th></th></tr></thead><tbody><tr><td>Snapshot Space:<br>General governance<br></td><td><a href="https://snapshot.org/#/mangrove.eth">https://snapshot.org/#/mangrove.eth</a></td></tr><tr><td>Membership directory</td><td><a href="https://directory.mangrove.exchange/">https://directory.mangrove.exchange/</a></td></tr><tr><td>Forum</td><td><a href="https://forum.mangrove.exchange/">https://forum.mangrove.exchange/</a></td></tr><tr><td>Safe:<br>Mangrove DAO MS<br></td><td><a href="https://app.safe.global/home?safe=eth:0xb4a0fEC6445ac7595D4068579753D2a3eF880De5">https://app.safe.global/home?safe=eth:0xb4a0fEC6445ac7595D4068579753D2a3eF880De5</a></td></tr><tr><td>Safe:<br>Ecosystem Council MS</td><td></td></tr><tr><td>Safe:<br>Protocol Council MS</td><td></td></tr><tr><td>Safe:<br>ADDMA MS<br></td><td><a href="https://app.safe.global/home?safe=eth:0x0813Ec5f3b54003197d8B40A36Ed570E803cfBF7">https://app.safe.global/home?safe=eth:0x0813Ec5f3b54003197d8B40A36Ed570E803cfBF7</a></td></tr></tbody></table>

## Adresses

<table data-header-hidden><thead><tr><th width="271"></th><th></th></tr></thead><tbody><tr><td>MGV token</td><td><code>0x7777f41a060377b3640f8b5e3bb78e37bd487777</code></td></tr><tr><td>DssVest for MGV</td><td><code>0x370F850180FDDCdc521Ed11900a7a27D08B2d402</code></td></tr><tr><td>ADDMA MS</td><td><code>0x0813Ec5f3b54003197d8B40A36Ed570E803cfBF7</code></td></tr><tr><td>Mangrove DAO MS</td><td><code>0xb4a0fEC6445ac7595D4068579753D2a3eF880De5</code></td></tr><tr><td>ADDMA Protocol MS</td><td></td></tr><tr><td>Protocol Council MS</td><td></td></tr><tr><td>Ecosystem Council MS</td><td></td></tr><tr><td>Builders Group ERC-721</td><td><code>0x33dbde2e093b7cf8446d9ac0de79220d42423501</code></td></tr><tr><td>Builders Group Badges ERC-1155</td><td><code>0xd1502a7659eaad60278ae3ef27edea849504f4da</code></td></tr><tr><td>Builders Group Activity Score ERC-20</td><td><code>0x5f120453dfd0c55f55370d1f718089ae0fcf6387</code></td></tr><tr><td>Pods Group ERC-721</td><td><code>0x9763a9d2b17756b6531ecbf6c7097f7225e22da7</code></td></tr><tr><td>Pods Group Badges ERC-1155</td><td><code>0xa2956d29d879ab7b9a1d16723e376d9e2be5c911</code></td></tr><tr><td>Pods Group Activity Score ERC-20</td><td><code>0xd0805e6b373223322e341018cb8c024c3baa98b0</code></td></tr><tr><td>Protocol Council ERC-721</td><td><code>0x760559c824db794a307f3c98e03a87d1b10c12db</code></td></tr><tr><td>Protocol Council Badges ERC-1155</td><td><code>0xcb42f61a0e42eacd0091b9ffc6a182cdcec7bd4a</code></td></tr><tr><td>Ecosystem Council ERC-721</td><td><code>0x93cf0a3b67962d475d9514d9955fe6621a26d42c</code></td></tr><tr><td>Ecosystem Council Badges ERC-1155</td><td><code>0x7c49ef1e6565af0e112f3727005f85208f81ba91</code></td></tr><tr><td>TBA ERC-6551 registry</td><td><code>0x000000006551c19487814612e58FE06813775758</code></td></tr><tr><td>TBA ERC-6551 implementation</td><td><code>0xee0b927f5065923d49dda69dce229ef467663310</code></td></tr></tbody></table>


# DEV DOC


# Contracts


# Getting started

The tutorials all rely on the [preparation](https://github.com/giry-dev/mangrove-docs/blob/main/mangrove-core/tutorials/preparation.md) step to be done.


# Guides


# Cleaning offers

Getting paid to clean Mangrove offer lists.

## Cleaning an offer

Offers on Mangrove may fail. This may be done [on purpose](/mangrove-core/explanations/taker-compensation), or be the result of unexpected conditions. Either way, callers are remunerated for their action by receiving a portion of the [bounty](https://github.com/giry-dev/mangrove-docs/blob/main/offer-maker/offer-provision.md) attached to the failing offer.

## Cleaning bots

Mangrove has been designed such that keeping offer lists clean of failing offers is incentive-compatible. Anyone can run a bot which repeatedly does the following:

1. Receive events from Mangrove to maintain an up-to-date view of the books.
2. Locally runs offers at regular intervals.
3. Detects failing offers and sends a transaction to make the offer fail on-chain, with a gas price set such that the offer's bounty compensates for the spent gas.

Mangrove provides a [cleaner contract ](https://github.com/giry-dev/mangrove-docs/blob/main/mangrove-core/how-to-guides/broken-reference/README.md)to help you. This contract provides the same interface as [snipes](/mangrove-core/technical-references/taking-and-making-offers/taker-order#offer-sniping) but will revert if any offer in the `targets` array successfully executes.

{% hint style="info" %}
**Example scenario**

1. Your bot has 900 DAI tokens, has given Mangrove an allowance to spend its DAI, and has given the cleaner contract an [allowance](/mangrove-core/technical-references/taking-and-making-offers/taker-order/delegate-takers) to use its DAI on Mangrove.
2. You detect that offer #708, which `wants` 800DAI and `gives` 800 USDC on the USDT-DAI offer list, fails on your local fork of mainnet, so you call the cleaner contract with `targets` [set to](/mangrove-core/technical-references/taking-and-making-offers/taker-order#offer-sniping) `[[708,type(uint96).max,0,type(uint).max]]`, and `fillWants` set to `false`.
3. Mangrove will use your DAI to execute offer #708 and revert after noticing that the offer fails. It will then transfer the offer bounty to you.
4. If the offer does not fail, the cleaner contract will revert.
   {% endhint %}

### Delegation

Cleaning can also use Mangrove's [delegation mechanism](/mangrove-core/technical-references/taking-and-making-offers/taker-order/delegate-takers), which means you only need Mangrove to have an allowance on any address that that has enough *inbound* tokens of the [offer list](https://github.com/giry-dev/mangrove-docs/blob/main/mangrove-core/how-to-guides/broken-reference/README.md) you are targeting. The cleaner contract will use those funds to execute the cleaning.

{% hint style="info" %}
**Example scenario**

1. The address `funder.eth` has 900 DAI tokens and given Mangrove an allowance to spend its DAI. Offer #708 is still failing.
2. You call the cleaner contract with the same `targets` as above, and `taker` set to `funder.eth`.
3. Mangrove will use `funder.eth`'s DAI to execute offer #708 and revert after noticing that the offer fails. It will then transfer the offer bounty to you.
4. If the offer succeeds, Mangrove will notice that you had no allowance to use `funder.eth`'s DAI on Mangrove and revert (if you did have a high enough allowance, and the sniping succeeds, the cleaner contract will revert anyway).
   {% endhint %}


# How to create a Direct contract

This section will go through a few different ways of how a Direct contract could be implemented. If you don't know what a Direct contract is, we recommend reading both [MangroveOffer](https://github.com/giry-dev/mangrove-docs/blob/main/mangrove-core/mangrover-offer.md) and [Direct](https://github.com/giry-dev/mangrove-docs/blob/main/mangrove-core/Direct.md) before continuing.

## Simple Direct implementation

When creating a Direct contract, the first thing you need is to import the necessary contracts needed for the constructor. Next is creating a constructor that calls the constructor of Direct. We set the gas requirement to 30.000, since we are not doing much in the posthook, it does not need anymore than that.

In the constructor we check if the deployer of the contract is the same as `msg.sender`, if not, it means that the sender is deploying the contract on behalf of another address and wants that address to be admin of the contract.

```solidity
pragma solidity ^0.8.10;

pragma abicoder v2;

import {Direct, AbstractRouter, IMangrove, IERC20} from "src/strategies/offer_maker/abstract/Direct.sol";
import {IMakerLogic} from "src/strategies/interfaces/IMakerLogic.sol";

contract OfferMaker is Direct {

  constructor(IMangrove mgv, AbstractRouter router_, address deployer) Direct(mgv, router_, 30_000) {
    // stores total gas requirement of this strat (depends on router gas requirements)
    // if contract is deployed with static address, then one must set admin to something else than msg.sender
    if (deployer != msg.sender) {
      setAdmin(deployer);
    }
  }
...
```

Technically Direct does not require anything else. But since the `_newOffer` function of Direct is an internal function, deploying the contract as-is, would not allow anyone to post an offer. Because of this we want to add one thing. We want to implement the `IMakerLogic`, which only says that the contract has to have a `newOffer` function with the correct parameters. You could choose to not use this interface, but it is a nice help, that enforces that the offer maker gives all the relevant information for posting a new offer. Using `IMakerLogic` also makes it compatible with the Mangrove SDK, which expects the `IMakerLogic` ABI. Since we only want the admin of the contract to be able to post offers, we add the modifier `onlyAdmin` to the function. This is a modifier Direct can use, because it is a `AccessControlled` contract.

When this is added, then the contract is ready to be [deployed](/mangrove-core/how-to-guides/howtodeploy). The contract can now post new offers, update offers and retract offers, using all the default behavior from a Direct contract.

The full code can be found in [here](https://github.com/mangrovedao/mangrove-core/blob/master/src/strategies/offer_maker/OfferMaker.sol).

```solidity
...

  function newOffer(
    IERC20 outbound_tkn,
    IERC20 inbound_tkn,
    uint wants,
    uint gives,
    uint gasreq,
    uint gasprice,
    uint pivotId
  ) public payable override onlyAdmin returns (uint offerId) {
    offerId = _newOffer(
      OfferArgs({
        outbound_tkn: outbound_tkn,
        inbound_tkn: inbound_tkn,
        wants: wants,
        gives: gives,
        gasreq: gasreq,
        gasprice: gasprice,
        pivotId: pivotId,
        fund: msg.value,
        noRevert: false,
        caller: msg.sender
      })
    );
  }
}
```

## Posting ghost liquidity with Direct

One option when using Direct/MangroveOffer is to not only post one offer but two or more. E.g. lets say you want to sell some WETH, but you do not care if you get USDC or DAI in return. That means you could post 2 equivalent offers, one WETH/USDC and one WETH/DAI. And when one of the offers was taken, you would like to retract the other offer. This means that you don't actually have enough WETH for both offers, but it doesn't matter since we're retracting the offer, as soon as it is taken. Doing this, makes the "retracted offer" a "Ghost" offer.

As before we start by creating a constructor, since we now want to post 2 offers, we need some information about what kind of offers the contract should post. The contract needs to know the `BASE` token, and what 2 kinds of stable coins to post (`STABLE1` & `STABLE2`). These are saved in public immutable variables. Besides knowing what kind of tokens that should be used for the offers, the contract needs to know the ids of the offers. This is needed to be able to retract the offers in posthook. We again call the Direct contract, but this time we set the gas requirement to 100.000, because our posthook will require more gas.

In the constructor for Ghost, we create a SimpleRouter and sets it as the router for the contract. It also binds the contract address to the router, allowing the contract to use the router and sets the admin of the router as the given admin. Direct does not require a router, but we use one in this example to show how to use one. The last thing is to set the admin of the contract, to the admin given to the constructor.

```solidity
pragma solidity ^0.8.10;

pragma abicoder v2;

import {Direct, IMangrove, IERC20 } from "src/strategies/offer_maker/abstract/Direct.sol";
import {SimpleRouter, AbstractRouter} from "src/strategies/routers/SimpleRouter.sol";
import {MgvLib, MgvStructs} from "src/MgvLib.sol";

contract Ghost is Direct {
  IERC20 public immutable BASE;
  IERC20 public immutable STABLE1;
  IERC20 public immutable STABLE2;

  uint offerId1; // id of the offer on stable 1
  uint offerId2; // id of the offer on stable 2

  constructor(IMangrove mgv, IERC20 base, IERC20 stable1, IERC20 stable2, address admin)
    Direct(mgv, NO_ROUTER, 100_000)
  {
    // SimpleRouter takes promised liquidity from admin's address (wallet)
    STABLE1 = stable1;
    STABLE2 = stable2;
    BASE = base;
    AbstractRouter router_ = new SimpleRouter();
    setRouter(router_);
    // adding `this` to the allowed makers of `router_` to pull/push liquidity
    // Note: `reserve(admin)` needs to approve `this.router()` for base token transfer
    router_.bind(address(this));
    router_.setAdmin(admin);
    setAdmin(admin);
  }
}
```

As before we need to create a way for the offer maker to post an offer. Before we used IMakerLogic, because it helped us using the correct parameters. But for ghost we already know some of the parameters beforehand, since we gave them in the constructor. We know the inbound and the outbound of both offers. Besides this we don't want the offer maker to specify the gas price and gas requirement, but just use the standard implementations. Because of this, we don't use IMakerLogic for this contract. If the gas price is left at zero, then Mangrove will use its own gas price. And for the gas requirement, we can use the function ´offerGasreq()´ which returns the gas requirement for the contract plus the gas requirement for the router. Because of this we only have to give the amount of `gives` which is the base token, amount of stable1 and stable2 (`wants1` & `wants2`) and the pivots for the to offers (`pivot1` & `pivot2`). As before, we only want the admin of the contract to able to post offers, so we add the modifier `onlyAdmin`.

This contract will only be able to handle 1 pair of offers, because of this we have to check if the 2 offers are already active when we try to post new offers. Mangrove offers a way to do this, by calling `MGV.isLive(offer)` and we can get the offer by calling `MGV.offers(outbound,inbound,offerId)`. This way we can require that both offers are inactive.

An offer is inactive if `gives` of the offer is zero. This means that there are different ways an offer can become inactive. One way is that the offer has never been posted before, but another way could be that the offer had been posted and the fully taken or retracted. If an offer is fully taken or retracted, then the offer still exist, but it is just inactive. The reason for this is, that Mangrove can reuse the offer, instead of posting a completely new offer. Updating an offer is cheaper in gas, than posting a new one. Because of this we need to handle if we should post new offers or update the offers.

We first setup all the arguments that is required for posting or updating an offer. The first offer uses everything relevant for offer1 and the second offer uses everything relevant for offer2. But one difference is that we choose to fund everything through the first offer and nothing through the second offer. Because Direct can only be used by one offer maker, then there is no bookkeeping on how much was funded foreach offer, since all offers a poster by the same offer maker.

To know if an offer already exist or not, we have to get more details from the offers. We do this using `MGV.offerDetails(outbound,inbound, offerId)`. This gives you a packed version of the details. From the this the maker of the offer can be retrieved. If the maker of the offer is empty, it means that the offer doesn't exist.

We now have all the necessary information to know if we should post a new offer or updated one. We then create a function `postOrUpdateOffer` that checks whether the maker is empty and then either posts a new offer or updates the existing one. If it is post a new offer, it will return the new offer id else it will return the old offer id. We use this function for both offers, save the offer ids and return the ids.

Our contract can now post new offers and update them if they are inactive.

```solidity
  function newGhostOffers(
    // this function posts two asks
    uint gives,
    uint wants1,
    uint wants2,
    uint pivot1,
    uint pivot2
  ) external payable onlyAdmin returns (uint, uint) {

    MgvStructs.OfferPacked offer1 = MGV.offers(address(BASE), address(STABLE1), offerId1);
    MgvStructs.OfferPacked offer2 = MGV.offers(address(BASE), address(STABLE2), offerId2);

    require(!MGV.isLive(offer1), "Ghost/offer1AlreadyActive");
    require(!MGV.isLive(offer2), "Ghost/offer2AlreadyActive");

    OfferArgs memory offerArgs1 = OfferArgs({
      outbound_tkn: BASE,
      inbound_tkn: STABLE1,
      wants: wants1,
      gives: gives,
      gasreq: offerGasreq(),
      gasprice: 0,
      pivotId: pivot1,
      fund: msg.value,
      noRevert: false,
      owner: msg.sender
    });

    OfferArgs memory offerArgs2 = OfferArgs({
      outbound_tkn: BASE,
      inbound_tkn: STABLE2,
      wants: wants2,
      gives: gives,
      gasreq: offerGasreq(),
      gasprice: 0,
      pivotId: pivot2,
      fund: 0, // no need to fund this second call for provision since the above call should be enough
      noRevert: false,
      owner: msg.sender
    });

    MgvStructs.OfferDetailPacked offerDetails1 = MGV.offerDetails(address(BASE), address(STABLE1), offerId1);
    MgvStructs.OfferDetailPacked offerDetails2 = MGV.offerDetails(address(BASE), address(STABLE2), offerId2);

    offerId1 = postOrUpdateOffer(offerArgs1, offerDetails1, offerId1);
    offerId2 = postOrUpdateOffer(offerArgs2, offerDetails2, offerId2);
    return (offerId1, offerId2);
  }

  function postOrUpdateOffer(OfferArgs memory offerArgs, MgvStructs.OfferDetailPacked offerDetails, uint offerId)
    internal
    returns (uint)
  {
    if (offerDetails.maker() == address(0)) {
      return _newOffer(offerArgs);
    } else {
      _updateOffer(offerArgs, offerId);
      return offerId;
    }
  }
```

Since we now can post new offers, these offer will get taken at some point. And if one of the offers was taken, we wanted to retract the other offer, since we no longer have the funds for that offer. To do this we use the hook `posthookSuccess`. This hook gets called if the offer was successfully taken.

The first thing we want to do is use Directs own implementation of `posthookSuccess`. This makes sure to repost the offer if it was only partially taken. Next we need to figure out which of the two offers was taken. In `SingleOrder`we can get what the inbound token was for the taken offer. Using this we can figure out if it was `STABLE1` or `STABLE2`, and thereby also the offer id.

Next we need to know whether the Directs `posthookSuccess` reposted the offer or not. Posthooks returns values that the offer maker can use, to know what the hook did and if the was a success. In this case, if the posthook returns `posthook/reposted` it means that the posthook successfully reposted the offer. Knowing that the offers was reposted, we now know that the other offer also needs to be updated, to use the correct gives and wants.

To do this we need information about the remaining `gives` of the offer, so we use `residualGives`, which calculates the remaining `gives`. And we again use `MGV.offers()` and `MGV.offerDetails` to get information about the other offer. With this information we now know what the old `wants` was for the offer and the old and new `gives` for the offer. Using this we can calculate what the new `wants` should be.

With this we can now use Directs own `updateOffer` (you should always use the contracts own newOffer, updateOffer or retractOffer, and never call Mangrove directly, since Direct/Forwarder/MangroveOffer might do some extra bookkeeping). We use the same gas requirement as the old offer, since it still requires the same amount of gas. We use a pivot id right next to the old, since this offer basically the same price as the old one. If we use zero as pivot id, it might be very gas costly the find the right position for the offer. When the offer is updated, we return a value that indicates that this hook successfully reposted both offers.

We can now handle if the offer was partially taken and the other offer needed to be updated. But we still need to handle if the offer was fully taken or the posthook failed. In the case where the offer was fully taken, we want only want to retract the other offer, but if the posthook failed, we want to retract both offers. If `posthookSuccess` failed, then we don't know why and the safest is to retract both offers. We can use the returned value from `posthookSuccess` to check if the offer was fully taken (`posthook/filled`) or failed (any other value). When we retract the offers, we don't want to deprovision. Since deprovisioning is gas costly, it is better to leave the funds, this way the provision can be used to post a new offer, without having to fully fund the new offer. Lastly we return a value that indicates that both offers have been retracted.

The `posthookSuccess`is now done and we can handle the different scenarios that might be triggered.

```solidity
function __posthookSuccess__(MgvLib.SingleOrder calldata order, bytes32 makerData)
    internal
    override
    returns (bytes32)
  {
    bytes32 repost_status = super.__posthookSuccess__(order, makerData);
    (IERC20 alt_stable, uint alt_offerId) =
      IERC20(order.inbound_tkn) == STABLE1 ? (STABLE2, offerId2) : (STABLE1, offerId1);

    if (repost_status == "posthook/reposted") {
      uint new_alt_gives = __residualGives__(order); // in base units
      MgvStructs.OfferPacked alt_offer = MGV.offers(order.outbound_tkn, address(alt_stable), alt_offerId);
      MgvStructs.OfferDetailPacked alt_detail = MGV.offerDetails(order.outbound_tkn, address(alt_stable), alt_offerId);

      uint old_alt_wants = alt_offer.wants();
      uint old_alt_gives = order.offer.gives();
      uint new_alt_wants;
      unchecked {
        new_alt_wants = (old_alt_wants * new_alt_gives) / old_alt_gives;
      }
      // the call below might throw
      updateOffer({
        outbound_tkn: IERC20(order.outbound_tkn),
        inbound_tkn: IERC20(alt_stable),
        gives: new_alt_gives,
        wants: new_alt_wants,
        offerId: alt_offerId,
        gasreq: alt_detail.gasreq(),
        pivotId: alt_offer.next(),
        gasprice: 0
      });
      return "posthook/bothOfferReposted";
    } else {
      // repost failed or offer was entirely taken
      if (repost_status != "posthook/filled") {
        retractOffer({
          outbound_tkn: IERC20(order.outbound_tkn),
          inbound_tkn: IERC20(order.inbound_tkn),
          offerId: order.offerId,
          deprovision: false
        });
      }
      retractOffer({
        outbound_tkn: IERC20(order.outbound_tkn),
        inbound_tkn: IERC20(alt_stable),
        offerId: alt_offerId,
        deprovision: false
      });
      return "posthook/bothRetracted";
    }
  }
```

When writing posthooks, you want to consider all outcomes. The first outcome was that the offer was successfully, but i might be that the offer failed when it was taken. This now means that the offer that was unsuccessfully taken, is now inactive, but the other offer, would probably also fail, if the first offer failed. For this reason we want to write a `posthookFallback` that makes sure to retract the other offer.

Just as we did in the `posthookSuccess`, we find the inbound token and offer id, by looking at the inbound token of the offer that failed. This way we now know which offer we want to retract. When retracting the offer, we again choose to not deprovision, for the same reason as in `posthookSuccess`. Lastly we return a value that indicates that both offers failed.

The `posthookFallback` is now done and we can handle if the offer was unsuccessfully taken.

```solidity
  function __posthookFallback__(MgvLib.SingleOrder calldata order, MgvLib.OrderResult calldata)
    internal
    override
    returns (bytes32)
  {
    // if we reach this code, trade has failed for lack of base token
    (IERC20 alt_stable, uint alt_offerId) =
      IERC20(order.inbound_tkn) == STABLE1 ? (STABLE2, offerId2) : (STABLE1, offerId1);
    retractOffer({
      outbound_tkn: IERC20(order.outbound_tkn),
      inbound_tkn: IERC20(alt_stable),
      offerId: alt_offerId,
      deprovision: false
    });
    return "posthook/bothFailing";
  }
```

The contract is almost done. One last thing that we should offer to the offer maker, is to offer a way to get the provision back. This could simply be because the offer maker wants the pull their offers or that the offers had been retracted doing `posthookSuccess` or `posthookFallback` but not deprovisioned (as explained earlier). Since Direct has its own implementation of retracting a offer, the offer maker would technically be able to retract them themselves, but that would require that the offer maker had stored the offer ids themselves, otherwise they would not know what offers to retract. One way of fixing this would be to make the offer ids of the Ghost contract public, this way the offer maker would be able to retrieve the offer ids themselves and then retract the offers, but another way would be to create a function that would retract both offers. In this example we choose to make a retract function that retracts both offers.

Since we know everything about the two offers, retracting them is simple calling Directs own retractOffer function on both offers. The offer maker might just want to retract the offers, without deprovisioning them, because of this we add a parameter to the function, that tells if the offers should be deprovisioned.

The offer maker can now post new offer, where all posthooks are handled and they can retract their offers again. The contract is now done. The next thing would be to test that the contract works as planned. This can be found in this [section](/mangrove-core/how-to-guides/howtotest).

The full code for the contract can be found [here](https://github.com/mangrovedao/mangrove-core/blob/master/src/toy_strategies/offer_maker/Ghost.sol)

```solidity
  function retractOffers(bool deprovision) public {
    retractOffer({outbound_tkn: BASE, inbound_tkn: STABLE1, offerId: offerId1, deprovision: deprovision});
    retractOffer({outbound_tkn: BASE, inbound_tkn: STABLE2, offerId: offerId2, deprovision: deprovision});
  }
```


# How to test your contract

You have now created your contract and would like to test it. Mangrove offers a helper contract, that can help setup everything needed for writing a test using the Mangrove core protocol.

When we write test we are going to be using the framework [Foundry](https://book.getfoundry.sh/). Foundry is a smart contract development toolchain.

When explaining "how to test" we are going to use the Ghost contract, created in [How to create a Direct contract](/mangrove-core/how-to-guides/directhowto).

When creating your test, remember to use the naming convention `<name>.t.sol`, this way Foundry knows what files are test. The first thing to do is to import the relevant contracts. We are going to use `MangroveTest` which is a helper to setup the Mangrove protocol. This way you do not need to fork a existing chain, it can just deploy the Mangrove protocol for you before running your tests. It has many other helpers. We import `Polygon` which is a helper to fork the polygon chain, we do this because we want to use the real address for WETH, USDC and DAI. This is not necessary, one could just create some test tokens an use them. We import the Ghost contract, because that is the contract we want to test. The last thing is `MgvStructs`, this helps with getting information about offers, which we need later in the test.

The console import is not needed, but can be very useful, if you want to log something during your test. Debugging solidity code is not that easy, so using console logs is sometimes faster.

Then we create a contract called GhostTest that inherence from MangroveTest. Making the contract a MangroveTest makes it possible to use all its helper functions. There is a few variable we know we are going to need, in order to test Ghost, we need 3 tokens, the fork the test should run on, a taker address and the Ghost contract.

The receive function is defined in order for the test contract to be able to receive funds. In this test we are going to use the test contract as a offer maker, this means that it should be able to receive funds. A contract i solidity that does not have the receive function defined, will not be able to receive any funds.

Before we run any tests, we want to create a setUp function that gets called before the actual test gets called. In Foundry creating a function called setUp will automatically make it run before the tests. In this case MangroveTest already has a setUp function, because of this we override it, since we only want to do part of the default setup.

In the setup function we start by creating a fork from the polygon chain and run its setup function. Next we need to setup Mangrove using the helper function from MangroveTest. We then get the 3 tokens from the polygon chain, all the addresses can be found in the `polygon.json` file where some standard addresses are saved.

The Ghost contract is using two markets, it is there for necessary to setup the 2 markets, in this case we are using DAI/WETH and USDC/WETH market. The last thing is creating the taker address, giving it some native tokens (to pay for gas), some DAI and USDC (to be able to take the offers) and approving Mangrove to take the funds. I order to approve Mangrove the taker has to call the approve function on each token, giving the address for Mangrove. Here we are using 3 helper functions `startPrank(<address>)`, `stopPrank(<address>` and `$`. The start and stop prank, are cheatcodes offered by Foundry, they make it possible to impersonate an address as if it was that address calling. This is makes it possible for us to call as the taker and approve Mangrove. This is only possible because we are in a test, using Foundry and not on any real chain, otherwise this would not be possible. The last helper function is `$`, this MangroveTest offer a shorthand for writing `address()` and casting the contract to its address.

The setup is done, at we are now ready to write the first test.

```solidity
import {MangroveTest} from "mgv_test/lib/MangroveTest.sol";
import {PolygonFork, PinnedPolygonFork} from "mgv_test/lib/forks/Polygon.sol";
import {Ghost, IMangrove, IERC20} from "src/toy_strategies/offer_maker/Ghost.sol";
import {MgvStructs} from "src/MgvLib.sol";
import {MgvReader} from "src/periphery/MgvReader.sol";

import {console} from "lib/forge-std-vendored/src/console.sol";

contract GhostTest is MangroveTest {
  IERC20 weth;
  IERC20 dai;
  IERC20 usdc;

  PolygonFork fork;

  address payable taker;
  Ghost strat;

  receive() external payable virtual {} // Needed if the contract should receive funds

  function setUp() public override {
    // use the pinned Polygon fork
    fork = new PinnedPolygonFork(); // use polygon fork to use dai, usdc and weth addresses
    fork.setUp();

    // use convenience helpers to setup Mangrove
    mgv = setupMangrove();

    // setup tokens, markets and approve them
    dai = IERC20(fork.get("DAI"));
    weth = IERC20(fork.get("WETH"));
    usdc = IERC20(fork.get("USDC"));

    setupMarket(dai, weth);
    setupMarket(usdc, weth);

    // setup separate taker and give some native token (for gas) + USDC and DAI
    taker = freshAddress("taker");
    deal(taker, 10_000_000);

    deal($(usdc), taker, cash(usdc, 10_000));
    deal($(dai), taker, cash(dai, 10_000));

    // approve DAI and USDC on Mangrove for taker
    vm.startPrank(taker);
    dai.approve($(mgv), type(uint).max);
    usdc.approve($(mgv), type(uint).max);
    vm.stopPrank();
  }
...
```

When creating test using Foundry, you have to name the function that runs the test `test<the name>`. This way Foundry knows what functions are tests. I our first test we want to test that when the offer is fully taken, we therefore call the test `test_success_fill`.

The first thing we need to do in our test is to deploy the Ghost contract on our local chain. Since we know that this is going to be necessary for all the test, we write how to deploy the test on the local chain in its own function.

Deploying a contract locally is just calling its constructor of the contract. We are setting address of the testing contract(`$(this)`), as admin of the Ghost contract, this way we can use the testing contract as maker. When the contract is deployed, we then need to activate it. We know which tokens we are going to use, so we first create an array with the 3 tokens, next we call Ghost to check if any of the tokens have the correct approvals. Since we haven't activated Ghost, we then expect it to revert with a specific message. Foundry has a cheatcode to catch excepted reverts called `expectRevert(<message>)`. This way we can call the checklist and see if the get the expected revert. The last thing we do in our deploy function, is activating Ghost for the tokens we need.

```solidity
  function test_success_fill() public {
    deployStrat();

    execTraderStratWithFillSuccess();
  }

  function deployStrat() public {
    strat = new Ghost({
      mgv: IMangrove($(mgv)),
      base: weth,
      stable1: usdc, 
      stable2: dai,
      admin: $(this) 
      });

    IERC20[] memory tokens = new IERC20[](3);
    tokens[0] = dai;
    tokens[1] = usdc;
    tokens[2] = weth;

    vm.expectRevert("mgvOffer/LogicMustApproveMangrove");
    strat.checkList(tokens);

    // and now activate them
    strat.activate(tokens);
  }
```

We now have a function that can deploy a new Ghost contract on our local chain. Next is writing the actual test. In the first test we want to create a new offer using Ghost, sniping one of the offer and then checking that the maker and taker got what they were promised and that both offers now are inactive.

First we save what amounts we want to use for the 2 offers. For the amount of WETH, we use the solidity shorthand `ether`. This is a way of multiplying a number with 10^18, which is the number of decimals ether has and because we are using WETH, it as the same amount of decimals. For both DAI and USDC we use the function `cash(token, amount)`. This is a helper function by MangroveTest, it makes sure to multiply the amount with the correct amount of decimals that the token is using. This way we now have the correct amounts of all tokens, using the correct decimals for each token.

Next we need to approve the router of Ghost the use the WETH of the tester contract. This is needed because we are using the tester contract as the reserve for Ghost. We then need to give the tester contract som WETH in order to be able to complete the offers. Foundry has a cheatcode to give an address an amount of a token. This function is called `deal(address_of_token, address_to_receive_token, amount)`. We again use weth in order to use the correct amount of decimals.

```solidity
  function execTraderStratWithFillSuccess() public {
    uint makerGivesAmount = 0.15 ether;
    uint makerWantsAmountDAI = cash(dai, 300);
    uint makerWantsAmountUSDC = cash(usdc, 300);

    weth.approve($(strat.router()), type(uint).max);

    deal($(weth), $(this), cash(weth, 10));

    (uint offerId1, uint offerId2) = postAndFundOffers(makerGivesAmount, makerWantsAmountDAI, makerWantsAmountUSDC);

    (uint takerGot, uint takerGave,) = takeOffer(makerGivesAmount, makerWantsAmountDAI, dai, offerId1);

    // assert that
    assertEq(takerGot, minusFee($(dai), $(weth), makerGivesAmount), "taker got wrong amount");
    assertEq(takerGave, makerWantsAmountDAI, "taker gave wrong amount");

    // assert that neither offer posted by Ghost are live (= have been retracted)
    MgvStructs.OfferPacked offer_on_dai = mgv.offers($(weth), $(dai), offerId1);
    MgvStructs.OfferPacked offer_on_usdc = mgv.offers($(weth), $(usdc), offerId2);
    assertTrue(!mgv.isLive(offer_on_dai), "weth->dai offer should have been retracted");
    assertTrue(!mgv.isLive(offer_on_usdc), "weth->usdc offer should have been retracted");
  }
```

We are now ready to post the offers using Ghost and take one of the offers. Posting new offers and taken an offer, is something all the test are going to do, so we implement a function for each thing. This way we make it easier to write the next test.

When posting offers using ghost, we need to fund it, in order to cover gas and provision, giving 1 ether is more than enough to cover the gas. For the pivot ids, we just give 0, since we know that there are no other offers on those markets.

When taking an offer, we need to know what offer to take. Because of this we need the inbound token, in order to snipe the correct offer. We again use a cheatcode by Foundry `prank(address)`, this works like `startPrank`but only for the next call, where `startPrank` works for all calls, until `stopPrank` is called. When using `prank`one should be aware of nested calls, e.g. had we used a call to figure out the pivot1 and just called it inline like this `pivot1: strat.getPivot1()` then it would be that called that gets pranked and not the snipe call.

```solidity
  function postAndFundOffers(uint makerGivesAmount, uint makerWantsAmountDAI, uint makerWantsAmountUSDC)
    public
    returns (uint offerId1, uint offerId2)
  {
    (offerId1, offerId2) = strat.newGhostOffers{value: 1 ether}({
      gives: makerGivesAmount, // WETH
      wants1: makerWantsAmountUSDC, // USDC
      wants2: makerWantsAmountDAI, // DAI
      pivot1: 0,
      pivot2: 0
    });
  }

  function takeOffer(uint makerGivesAmount, uint makerWantsAmount, IERC20 makerWantsToken, uint offerId)
    public
    returns (uint takerGot, uint takerGave, uint bounty)
  {
    // try to snipe one of the offers (using the separate taker account)
    vm.prank(taker);
    (, takerGot, takerGave, bounty,) = mgv.snipes({
      outbound_tkn: $(weth),
      inbound_tkn: $(makerWantsToken),
      targets: wrap_dynamic([offerId, makerGivesAmount, makerWantsAmount, type(uint).max]),
      fillWants: true
    });
  }
```

After having posted and taken one of the offers, we can now check whether everything happen as excepted. We use `assertEq` and ´assertTrue´ which are Foundry methods for asserting. The first thing we want to check, is whether the taker got the expected amount of WETH minus the fees taken by Mangrove. MangroveTest has a function ´minusFee(address\_outbound,address\_inbound, price)´, that will calculate the fee for a given market and price. The next thing is if the taker gave the correct amount of DAI.

Having tested that the taker got and gave the correct amounts, we then want to check whether the offers are no longer live on Mangrove. To do this we use Mangrove to get the packed offers and then using Mangroves `isLive` function to check if an offer is live. In this case we except that both offers are inactive.

```solidity
...
    (uint offerId1, uint offerId2) = postAndFundOffers(makerGivesAmount, makerWantsAmountDAI, makerWantsAmountUSDC);

    (uint takerGot, uint takerGave,) = takeOffer(makerGivesAmount, makerWantsAmountDAI, dai, offerId1);

    // assert that
    assertEq(takerGot, minusFee($(dai), $(weth), makerGivesAmount), "taker got wrong amount");
    assertEq(takerGave, makerWantsAmountDAI, "taker gave wrong amount");

    // assert that neither offer posted by Ghost are live (= have been retracted)
    MgvStructs.OfferPacked offer_on_dai = mgv.offers($(weth), $(dai), offerId1);
    MgvStructs.OfferPacked offer_on_usdc = mgv.offers($(weth), $(usdc), offerId2);
    assertTrue(!mgv.isLive(offer_on_dai), "weth->dai offer should have been retracted");
    assertTrue(!mgv.isLive(offer_on_usdc), "weth->usdc offer should have been retracted");
...
```

We have now written our first test. In Foundry you can run all your tests by running `forge test`, if you want to run only for one specific contract you can add `--match-contract <name_of_contract>` and if you only want to run one test on that contract, you can add `--match-test <name_of_test>`. In our case we would run `forge test --match-contract GhostTest --match-test test_success_fill`. You can get full stacktraces by uses `-vvv`, you can read more about how `--verbose` works on [Foundry](https://book.getfoundry.sh/)'s own website.

Writing your next test is now a lot easier since have create all the helper functions. E.g. writing a test for a on only being partially taken, would look like this:

```solidity
  function test_success_partialFill() public {
    deployStrat();

    execTraderStratWithPartialFillSuccess();
  }

  function execTraderStratWithPartialFillSuccess() public {
    uint makerGivesAmount = 0.15 ether;
    uint makerWantsAmountDAI = cash(dai, 300);
    uint makerWantsAmountUSDC = cash(usdc, 300);

    weth.approve($(strat.router()), type(uint).max);

    deal($(weth), $(this), cash(weth, 5));

    // post offers with Ghost liquidity
    (uint offerId1, uint offerId2) = postAndFundOffers(makerGivesAmount, makerWantsAmountDAI, makerWantsAmountUSDC);

    //only take half of the offer
    (uint takerGot, uint takerGave,) = takeOffer(makerGivesAmount / 2, makerWantsAmountDAI / 2, dai, offerId1);

    // assert that
    assertEq(takerGot, minusFee($(dai), $(weth), makerGivesAmount / 2), "taker got wrong amount");
    assertEq(takerGave, makerWantsAmountDAI / 2, "taker gave wrong amount");

    // assert that neither offer posted by Ghost are live (= have been retracted)
    MgvStructs.OfferPacked offer_on_dai = mgv.offers($(weth), $(dai), offerId1);
    MgvStructs.OfferPacked offer_on_usdc = mgv.offers($(weth), $(usdc), offerId2);
    assertTrue(mgv.isLive(offer_on_dai), "weth->dai offer should not have been retracted");
    assertTrue(mgv.isLive(offer_on_usdc), "weth->usdc offer should not have been retracted");
  }
```

A full test of the contract can be found [here](https://github.com/mangrovedao/mangrove-core/blob/master/test/toy_strategies/Ghost.t.sol).

When you have create all your tests, you may want to deploy your contract to a real chain. Read more about how to deploy [here](/mangrove-core/how-to-guides/howtodeploy).


# How to deploy your contract

After you have created and tested your contract, you might want to deploy it on chain. Deploying a contract is easy with the use of [Foundry](https://book.getfoundry.sh/) and a helper from our Deployer contract.

We start by creating a contract that inherits from Deployer, when creating your script, remember to use the naming convention, `<name>.s.sol`, this way Foundry knows it is a script file. The Deployer contract is meant as an ease of life the user, when they want to deploy a contract. It keeps track of what chain you want to deploy on and saving the addresses for the deployed contracts. If you want to know more of how it works, you can read about it here.

For this guide we will not go into to much detail, the important part is that the deployer keeps track of the chain you want to deploy on. In this example we are going to deploy the contract Ghost, that we created in the [How to create a Direct contract](/mangrove-core/how-to-guides/directhowto).

When creating a script you always need a `run()` function, this is the function that Foundry is going to call when running the script. In this script we need to know who the admin of the contract is. Since you never want to write address directly in your code/script, we use [dotenv](https://www.npmjs.com/package/dotenv), to hide all our secrets in a `.env` file. This way we can use the Foundry cheatcode `envAddress(<name>)` to access the secret addresses we need. In this case the admin address is a public address, so we could write it directly in the code, but if you want to deploy the script again with a different address, it is better to keep the address in a different file. Next we get the addresses for WETH, USDC and DAI, we get the addresses by using `fork.get(<name>)`, this only works because we have a json file with addresses for these tokens `polygon.json` and we know we are going to deploy on a polygon chain. If you want to deploy to a different chain, you would have to have a similar json file with the addresses for that chain.

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Script, console} from "forge-std/Script.sol";
import {Ghost, AbstractRouter, IERC20, IMangrove} from "mgv_src/toy_strategies/offer_maker/Ghost.sol";
import {Deployer} from "./lib/Deployer.sol";

/*  Deploys a Ghost instance
    First test:
 ADMIN=$MUMBAI_PUBLIC_KEY forge script --fork-url mumbai GhostDeployer -vvv
    Then broadcast and verify:
 ADMIN=$MUMBAI_PUBLIC_KEY WRITE_DEPLOY=true forge script --fork-url mumbai GhostDeployer -vvv --broadcast --verify
    Remember to activate it using Activate
*/
contract GhostDeployer is Deployer {
  function run() public {
    innerRun({
      admin: vm.envAddress("ADMIN"),
      base: fork.get("WETH"),
      stable1: fork.get("USDC"),
      stable2: fork.get("DAI")
    });
  }
...
```

Next we create an `innerRun` function, that does the actual deployment. We get the current Mangrove instance on chain, again by using `fork.get()`. When you deploy a new contract it is always good to consider that you maybe already have a instance of the contract deployed. In this case we would like to see if we have an address for "Ghost" saved already and if so we would like to withdraw everything from Mangrove and retract all offers. This way we know that Ghost no longer has any funds or offers and we can just leave it. The reason we do `try fork.get("Ghost")` is that, if it can't find any address for Ghost, then it will throw an exception. When writing your deployment script using Foundry, there is one command that is essential, which is `broadcast()`. Everything done in the script is just simulation, expect if you use broadcast right before a call, then that specific call is broadcasted to the actual chain. This way you can do many calls, to e.g. figure out the admin of a contract, without you actually having to use any gas on it. And only broadcast the actual thing you want done on chain.

The broadcast used here is actually a helper function that our Deployer contract has. What it does, is it goes out to find your `.env` and looks for a private key with the lookup value of `<nameOfChain>_PRIVATE_KEY`, e.g. if you want to deploy on Mumbai, it looks for a value called `MUMBAI_PRIVATE_KEY`. This is the private key of the address you would like to use for the broadcast. This means that you need this key in your `.env` in order to be able to actually deploy the contract.

As explained we want to withdraw from Mangrove if the Ghost contract has any free native tokens on Mangrove. We first check by using `mgv.balanceOf(<address>)`, notice that we don't use the command broadcast before this call, since we don't want to actually do it on chain. If the balance is positive, the we try to withdraw the funds from Mangrove, notice we use broadcast, because we want this called to be on chain. Be aware that when withdrawing from Mangrove using ghost, then it has to be the admin of the contract that preforms the call. This means, that in this case, the address in the `.env` file has to be the admin of the Ghost contract, otherwise this will not be allowed. After having withdrawn the free tokens form Mangrove, we now retract the offers and deprovisioning them, this returns any provision left on the offers, back to the admin. We do some console logging to check the balances of the admin contract after doing all this. This way it is easy to see if the expected amounts was withdrawn. All this could have been put in its own function, that handles closing a Ghost contract.

```solidity
...
  /**
   * @param admin address of the admin on Ghost after deployment
   * @param base address of the base on Ghost after deployment
   * @param stable1 address of the first stable coin on Ghost after deployment
   * @param stable2 address of the second stable coin on Ghost after deployment
   */
  function innerRun(address admin, address base, address stable1, address stable2) public {
    IMangrove mgv = IMangrove(fork.get("Mangrove"));

    try fork.get("Ghost") returns (address payable old_ghost_address) {
      Ghost old_ghost = Ghost(old_ghost_address);
      uint bal = mgv.balanceOf(old_ghost_address);
      if (bal > 0) {
        broadcast();
        old_ghost.withdrawFromMangrove(bal, payable(admin));
      }
      uint old_balance = old_ghost.admin().balance;
      broadcast();
      old_ghost.retractOffers(true);
      uint new_balance = old_ghost.admin().balance;
      console.log("Retrieved ", new_balance - old_balance + bal, "WEIs from old deployment", address(old_ghost));
    } catch {
      console.log("No existing Ghost in ToyENS");
    }
...
```

After having closed down the old Ghost contract, we now what to deploy a new one. This is very easy, we again use broadcast, when we create the Ghost contract and the Ghost contract is now deployed. After having deployed your contract, you should always think about if there are extra things need, in order to make the contract work. I our case there are multiple things we would like to do after deployment. First we save the new address for the Ghost contract using `fork.set(<address>)`. We then do a simple smoke test, to se if Ghost is actually deployed, we just try to see if Mangrove matches the one we used to deploy it.

Next we do `outputDeployment()`, this is a helper function created by the Deployer contract. This is meant as a simple way to update the json file, containing the addresses. If the flag `WRITE_DEPLOY` is set to true, the default value is false, it writes a new addresses.json file in the deployment folder. You can set the flag in the `.env` or when you run the script.

After having saved all the new addresses, we then need to activate the Ghost contract, so that it is able to trade on the tokens we use to created it. We create an array with the 3 tokens and call activate on the Ghost contract. This is again done with broadcast. The last thing we need is, as admin, to approve the router of Ghost to use the base token. Be aware that we get the router before doing the broadcast, this is because, if you inline it like this `IERC20(base).approve(address(ghost.router()), type(uint).max)`, where we both approve and get the router on the same line, then it would be the call that gets the router, that gets broadcasted. Since it is only the first call after broadcast that will get broadcasted.

Everything is now approve correctly and we check that by calling the checklist function on Ghost. Notice we use `prank`, because we want to call the function, as if we were calling from the ghost contract. We don't use broadcast here, because we do not need the call to be on chain. Had we done the call without `prank` or `broadcast` we would be calling as the `this` which is the script contract, the checklist we then check if the script had the right approvals, but that is not what we wanted to check.

```solidity
...
    console.log("Deploying Ghost...");
    broadcast();
    Ghost ghost = new Ghost(mgv, IERC20(base), IERC20(stable1), IERC20(stable2), admin );
    fork.set("Ghost", address(ghost));
    require(ghost.MGV() == mgv, "Smoke test failed.");
    outputDeployment();
    console.log("Deployed!", address(ghost));
    console.log("Activating Ghost");
    IERC20[] memory tokens = new IERC20[](3);
    tokens[0] = IERC20(base);
    tokens[1] = IERC20(stable1);
    tokens[2] = IERC20(stable2);
    broadcast();
    ghost.activate(tokens);
    AbstractRouter router = ghost.router();
    broadcast();
    IERC20(base).approve(address(router), type(uint).max);
    IERC20[] memory tokens2 = new IERC20[](1);
    tokens2[0] = IERC20(base);
    vm.prank(ghost.admin());
    ghost.checkList(tokens2);
  }
```

The full version of the deployer contract can be found [here](https://github.com/mangrovedao/mangrove-core/blob/master/script/toy/GhostDeployer.s.sol).

The deployment script is now ready, so lets try and deploy it to a local fork of mumbai. The first thing you need to do, is to start an anvil node, running on a fork of mumbai. This can be done like this `anvil --port 8545 --fork-url $MUMBAI_NODE_URL --silent`. Notice at the `MUMBAI_NODE_URL` is fetch of the `.env`file. If you don't have URL, polygon offers one [here](https://wiki.polygon.technology/docs/develop/network-details/network/). When running this the `.env` file might not have been sourced, so you might need to run `source .env`in order for it to find the `MUMBAI_NODE_URL`. The silent flag is not necessary, it is simply a way of starting the node without writing the setup for the fork. This can include secrets that you may not want to share.

When your anvil node is up and running, we can now do the actual deployment. Now at first want to try a deploy Ghost without broadcasting it, this way we can test if it works. This is done my running this in a different terminal, than where the anvil is running. `ADMIN=$MUMBAI_PUBLIC_KEY forge script --fork-url http://127.0.0.1:8545 GhostDeployer -vvv` (Remember that you might have to source your `.env` again in the new terminal). The first thing we do is setting the ADMIN to be the `MUMBAI_PUBLIC_KEY` that you wrote in your `.env` file. This will be the address that the Ghost contract will be deployed with. Next we say that we are using a fork url, that is a localhost of <http://127.0.0.1:8545>. We then write the name of our script and choose to use the verbosity level of `-vvv`. When running this you should see, in the terminal that runs the anvil node, a bunch of view functions being called, like `eth_xxxxx`, but no actual transactions.

If the script successfully ran, then you know that your script works. Not that you know that your script works, we run it again, but this time with the flag `--broadcast`, `ADMIN=$MUMBAI_PUBLIC_KEY forge script --fork-url http://127.0.0.1:8545 GhostDeployer -vvv --broadcast`. This runs the script again, but this time it actually broadcast the transactions you wanted. In the anvil terminal, you will again see the many view functions, but there should now also be actual transactions.

Your contract is now deployed on the chain you specified. In this case we used a local fork of mumbai, but you can easily do the same on a live chain.


# Technical references


# Taking and making offers

Offers on Mangrove leave of [Offer Lists](/mangrove-core/technical-references/taking-and-making-offers/market). Offers can be taken using market orders or snipped individually. Creating offers requires interacting with an onchain [logic](/mangrove-core/technical-references/taking-and-making-offers/reactive-offer/maker-contract#offer-logic) (a smart contract) able to [post](/mangrove-core/technical-references/taking-and-making-offers/reactive-offer#posting-a-new-offer), [update](/mangrove-core/technical-references/taking-and-making-offers/reactive-offer#updating-an-existing-offer) and [execute](/mangrove-core/technical-references/taking-and-making-offers/reactive-offer/maker-contract) offers.


# Offer Lists

Introducing Mangrove's Offer Lists a low level representation of (half) an order book.

## General structure

{% hint style="info" %}
The offer list is the basic Mangrove data structure. It contains offers (created by offer makers) that promise an **outbound token**, and request an **inbound token** in return (offer takers execute these offers by providing the **inbound token**, and receive **outbound tokens** in return).

For example in a DAI-wETH offer list, DAI is the outbound token (i.e. sent or given by the offer) and wETH the inbound token (i.e. received or wanted by the offer).

Relationship to markets: a full market will always feature two offer lists. For instance, a wETH/DAI **market** has one DAI-wETH offer list (where wETH is requested and DAI is offered), and a wETH-DAI offer list (where DAI is requested and wETH is offered).\
\
[Mangrove's API ](/mangrove-core/explanations/around-the-mangrove/mangrove-api)offers Market abstractions that allows liquidity providers and takers to interact with Mangrove using standard **base &** **quote** denominations.
{% endhint %}

Here's a sample DAI-wETH offer list with two offers. Only the main characteristics of the offers are shown (see the [offer data structure](/mangrove-core/technical-references/taking-and-making-offers/reactive-offer/offer-data-structures#mgvlib-offer)).

{% hint style="warning" %}
**Decimals**

We display human-readable values in the examples, but Mangrove stores raw token values and never uses the `decimals` field of a token.
{% endhint %}

| Rank | Offer ID | Wants (wETH) | Gives (DAI) | Gas required | Maker Contract | Offer Gas Price |
| ---- | -------- | ------------ | ----------- | ------------ | -------------- | --------------- |
| #1   | 77       | 1            | 2 925.26    | 250,000      | 0x5678def      | 150             |
| #2   | 42       | 0.3          | 871.764     | 300,000      | 0x1234abc      | 200             |

## Some terminology

### Offer rank

Offers are ordered from best to worst. Offers are compared based on *price*, and then on *gas required* (see below) if they have the same price.

{% hint style="info" %}
**Example**

The price of offer #42 is 0.0003441298 wETH per DAI while the price of offer #77 is 0.00034185 wETH per DAI. Offer #77 is therefore the best offer (lowest price) of this offer list, and is ranked first.
{% endhint %}

### Offer ID

The identifier of the offer in the offer list.

{% hint style="danger" %}
**Important**

Two offers may have the same ID as long as they belong to different offer lists. For instance, there may be an offer #42 on the wETH-DAI offer list with different volumes, gas required, maker contract, etc. than offer #42 in the DAI-wETH offer list shown above.
{% endhint %}

### Wants, gives and entailed price

Taken together, the **wants** and **gives** values define 1) a max volume, 2) a price. The **entailed price** is p=**wants**/**gives**, and an offer promises delivery of up to **gives** outbound tokens at a price of p tokens delivered per inbound token received.

{% hint style="info" %}
**Examples**

* Offer #42 *wants* 0.3 wETH to deliver its promised 871.764 DAI.
* If offer #77 is executed and receives 0.5 wETH, it must send back 1462.63 DAI.
  {% endhint %}

### Gas required

The maximum amount of gas the [Maker Contract](/mangrove-core/technical-references/taking-and-making-offers/reactive-offer/maker-contract) managing the offer will be allowed to spend if called by the Mangrove.

{% hint style="info" %}
**Example**

Offer #77 may consume up to 250K gas units.
{% endhint %}

### Maker Contract

The address of the [offer logic](/mangrove-core/technical-references/taking-and-making-offers/reactive-offer/maker-contract#offer-logic) managing the offer. The `makerExecute` function of this contract will be called when one of its offers is executed.

### Gas Price

Gas price that was used to compute the [offer provision](/mangrove-core/technical-references/taking-and-making-offers/reactive-offer/offer-provision). If the offer fails to deliver the promised **outbound tokens**, it will be charged in ETH based on this gasprice.

## Offer list configuration

Several [configuration](/mangrove-core/technical-references/governance-parameters/mangrove-configuration) parameters determine how new offers are inserted. Some are [global](https://docs.mangrove.exchange/mangrove-core/technical-references/taking-and-making-offers/pages/pF6T9izqF21UiijXXJft#mgvlib.global) to Mangrove, some are [offer list specifics.](https://docs.mangrove.exchange/mangrove-core/technical-references/taking-and-making-offers/pages/pF6T9izqF21UiijXXJft#mgvlib.local) See [Governance](/mangrove-core/technical-references/governance-parameters) section for details.




---

[Next Page](/llms-full.txt/1)

