# Introducing Maverick

![](/files/2NYqg2NVu6A7BFLl7jD9)

Maverick Protocol offers a new infrastructure for decentralized finance, built to facilitate the most liquid markets for traders, liquidity providers, DAO treasuries, and developers, powered by a revolutionary [**Automated Market Maker (AMM)**](/further-information/glossary#amm).

Maverick AMM helps its users maximize capital efficiency by automating the concentration of liquidity as price moves. Higher capital efficiency leads to more liquid markets, which means better prices for traders and more fees for liquidity providers. This built-in feature also helps LPs to eliminate the high gas fees that come from adjusting positions around price themselves.

Liquidity providers can also now choose to follow the price of an asset in a single direction, effectively making a bet on the price trajectory of a specific token. These directional bets are similar to single-sided liquidity strategies, in that the liquidity provider will be mostly or entirely exposed to a single asset in a given pool.

Together, these technological innovations represent a paradigm shift in the way smart contracts manage liquidity. Maverick is the first **Dynamic Distribution AMM**, capable of automating liquidity strategies that before now have required daily maintenance or the use of metaprotocols.

[**You can learn more about Maverick by reading our Litepaper!**](https://medium.com/maverick-protocol/introducing-maverick-a-protocol-for-decentralized-permissionless-trading-and-staking-of-any-asset-40b2a8bb1d54)

### The Maverick dApp

![Maverick's dApp UI.](/files/IQjYYqdFcwnOqyqot72A)

The [Maverick dApp](http://app.mav.xyz) is live on Ethereum and zkSync Era. Users can connect their wallets to trade and provide liquidity on Maverick AMM. These docs explain all the features of the Maverick app, and provide straightforward walkthroughs on how to use it.

The app consists of three pages:

* **Swap** - the trading interface for executing spot swaps on Maverick AMM
* **Pools** - the liquidity provider interface, where LPs can add liquidity to Maverick AMM pools
* **Portfolio** - once you have added liquidity, your liquidity position(s) will appear here

Maverick operates like most spot swap DEXs: LPs deposit tokens into Pools, where traders can go to swap them at prices set by the AMM. In the guides linked below, we go into more detail about each element of this process.

### How To Use Maverick

Follow our handy guides to get started using Maverick as quickly as possible:

{% content-ref url="/pages/YZh9A1Mc6DBQqq0VSPVx" %}
[Connect a Wallet](/getting-started/connect-a-wallet)
{% endcontent-ref %}

If you're new to DeFi and don't yet have a cryptocurrency wallet, this guide will help you install and connect a wallet to Maverick's dApp.

{% content-ref url="/pages/Xz7PtqNQXXgBhrKADlRY" %}
[Traders](/guides/traders)
{% endcontent-ref %}

If you've already got a wallet and are ready to dive into Maverick, this section will walk you through the Swap interface.

{% content-ref url="/pages/nCQsdRf8WS0S5ApZ1YER" %}
[Liquidity Providers](/guides/liquidity-providers)
{% endcontent-ref %}

Similarly, if you're familiar with DeFi and have your wallet already set up, this section explains how to use Pools interface to add and manage liquidity.


# The Maverick V2 UI

Whether you're brand new to Maverick or more familiar with the Maverick V1 UI, this page is intended to help you navigate the V2 UI and find all of the available features.

<figure><img src="/files/XqHCrVi8fSeLykKmW3kv" alt=""><figcaption><p>The Maverick V2 UI with Add Liquidity page selected.</p></figcaption></figure>

All of the features in Maverick V2 can be accessed using the menu at the top of every page. Some of the pages linked in this menu have multiple tabs. This page provides an overview of each page, tab, and feature, with links to more information on each elsewhere in the documentation.

* **Swap** - Provides the interface for swapping tokens with Maverick pools. [Learn more](/guides/traders/how-to-make-a-swap).
* **Add Liquidity** - The hub for users who want to provide liquidity on Maverick. [Learn more](/guides/liquidity-providers/understanding-liquidity-provision).
  * **Boosted Positions** - Incentivized, pre-configured positions within Maverick pools. Users can supply liquidity to Boosted Positions and earn extra token rewards. [Learn more](/guides/incentives/understanding-boosted-positions).
  * **Pools** - Regular token pools without incentives. Users can add liquidity to these pools if they want to configure their own liquidity positions. [Learn more](/guides/liquidity-providers/how-to-add-liquidity).
* **Vote** - The hub for veMAV holders to vote which Boosted Positions should receive additional incentives from the veFlywheel. [Learn more](/guides/veflywheel/veflywheel-basics).
  * **Voting** - veMAV holders use this tab to direct their voting power to Boosted Positions. [Learn more](/guides/veflywheel/how-to-vote-to-direct-emissions).
  * **Manage Voting Power** - Provides the interface for staking MAV tokens to receive veMAV, used to vote on Boosted Positions. Also used for unstaking MAV, extending stakes, and delegating veMAV voting power. [Learn more](/mav-token/vemav-and-mav-staking).
* **Portfolio** - Presents a summary of all of a user's liquidity positions on Maverick V2. Liquidity providers use this page to manage their liquidity and claim any rewards earned from Boosted Positions. [Learn more](/guides/liquidity-providers/how-to-manage-liquidity-in-a-pool).

## Advanced Features

Some advanced features can be accessed through the More Tools menu, accessed by clicking the **...** symbol in the top menu. These features are intended for advanced users, i.e., token projects and market makers. Many of these features involve giving away tokens in the form of liquidity incentives. Please be sure you understand what you are doing before using these advanced features.

<figure><img src="/files/qPE1o9DlCfu8IaUatO9X" alt=""><figcaption><p>The V2 UI, showing the Voting tab with the More Tools menu deployed.</p></figcaption></figure>

The features available from this menu are:

* **Create a New Pool** - Used to deploy a new pool on Maverick V2, either with a new token pair or with a new set of fee and width parameters. [Learn more](/guides/liquidity-providers/how-to-deploy-a-new-pool).
* Manage Incentives - The hub for adding and matching incentives for Boosted Positions. [Learn more](/guides/incentives/understanding-boosted-positions).
  * **Add Incentives** - Used to add incentives to existing Boosted Positions or to open a new Boosted Position. [Learn more](/guides/incentives/understanding-incentives).
  * **Match Incentives** - Used to add matching incentives to be distributed as part of the Maverick veFlywheel. [Learn more](/guides/veflywheel/veflywheel-basics).
* **Docs** - Links to this documentation.


# Connect a Wallet

In order to trade or add liquidity on Maverick, you will first need a software cryptocurrency wallet. These are available as an extension for popular browsers or as apps for your smartphone.

Maverick supports several wallets, including:

* [Metamask](https://metamask.io/)
* [Ledger](https://www.ledger.com/)
* [Coinbase Wallet](https://www.coinbase.com/wallet)
* [Trust Wallet](https://trustwallet.com/)
* [WalletConnect](https://walletconnect.com/)

Click on any of the above links to find more information about each wallet, and instructions on how to install them on your browser or device.&#x20;

Once you have installed a wallet, it’s time to connect it to Maverick.

![Choose Connect Wallet in the top right of your browser window](/files/h5WxoNuB7pvuFilygw4d)

When you first navigate to Maverick's dApp, you will see a button in the top right of your browser window that says **Connect Wallet**.&#x20;

<figure><img src="/files/tMUbuXftY6KSnsLlGGC4" alt=""><figcaption><p>Choose your wallet from within the Wallet modal. </p></figcaption></figure>

Click on this button and a modal will appear asking you to select a wallet. Choose the wallet you installed in the previous step.

At this point, the software wallet will take over and ask you to confirm the connection to Maverick. It may also ask you to switch to the network you currently have selected in the UI, if it was not already connected to that network. Confirm the connection and network switch (if required).

Your wallet is now connected to Maverick. You can now look at our guides for [traders ](/guides/traders)or [liquidity providers](/guides/liquidity-providers) for further instructions on using the dApp.

{% hint style="info" %}
If at any point you wish to disconnect your wallet from the testnet, you can do so by clicking your wallet address in the top right of your screen.
{% endhint %}


# Choose a Network

This page explains how to switch between networks in Maverick's dApp.

<figure><img src="/files/7VtBmeEdgbVJvEy021CQ" alt=""><figcaption><p>Click the network name in the top right to change networks.</p></figcaption></figure>

The Maverick dApp is live on Ethereum Mainnet, zkSync Era, Base, Arbitrum, and BNB Smart Chain. Switching between these networks is as simple as clicking the network icon in the top right of your screen and selecting another network from the drop-down menu. Confirm the network change in your wallet app and you're ready to go!

{% hint style="info" %}
In Maverick V2, you can see all pools and positions across all chains in the same UI without switching network. This means it is possible to browse all the Maverick pools in one place, and you won't be asked to change network unless you select a pool that is on a different network than the one to which you are currently connected. Some wallets even make this network switching seamless!
{% endhint %}


# Approving Tokens

The first time you use a token on Maverick, you will be asked to approve it in your wallet. Approving tokens is a normal security feature in cryptocurrency wallets, and requires you to approve the use of each token you hold in the wallet by the smart contract you're interacting with. You will need to approve each token individually before you can use it.

<figure><img src="/files/IORgsg0USMNYwDTeIIUw" alt=""><figcaption><p>The Confirm Swap button displays as Approve SAND because SAND is required for this transaction and has not yet been approved by the user.</p></figcaption></figure>

Action buttons like **Swap** and **Confirm** will display as **Approve \[token]** if any token(s) need to be approved before the action can be taken.

### Approval limits in Metamask

In March 2023, the Metamask software wallet changed how it handled approval requests. Metamask now requires users themselves to specify exactly how much of a given token they want to approve for use on each smart contract. In the Metamask wallet, this is called an **allowance**. Previously, a dApp could send a precise request for the amount required, or even just request an unlimited approval on a token. For more information on the update to Metamask, [click here](https://support.metamask.io/hc/en-us/articles/6055177143579-How-to-customize-token-approvals-with-a-spending-cap).

This now means that users may experience transaction failure on Maverick if their token spend request exceeds the approval they previously set in Metamask. For example, if a user previously set the Metamask allowance to 1 ETH and they try to swap 1.1 ETH, their transaction will fail because the token spend exceeds the approval they set.

Because Metamask does not allow Maverick's dApp to pass precise requests to it, you will need to set allowances yourself when approving tokens in Metamask. Maverick has done it's best to simplify this process by indicating in the UI how much you need to approve in Metamask.

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

In the screenshot above, right beneath the **Approve SAND** button we can see two information fields: **Current Allowance** and **Minimum Allowance**:

* **Current Allowance** indicates the amount of the token (here, SAND) that you currently have approved in Metamask
* **Minimum Allowance** indicates the minimum amount you need to approve in order for this transaction to succeed

The Maverick dApp automatically includes a 1% buffer in the Minimum Allowance figure in order to ensure your transaction will go through. It is highly recommend that you approve at least the Minimum Allowance if you want to ensure your transaction is successful.

{% hint style="info" %}
Metamask is currently iterating how they handle spending limits in their UI. While Maverick is doing its best to keep up to date with updates to the Metamask UI, the screenshots below may not always reflect the current Metamask UI for this workflow.
{% endhint %}

<figure><img src="/files/3fhHv6sRZwsXW5F9fUVP" alt=""><figcaption><p>Metamask asking for approval to use SAND on Maverick.</p></figcaption></figure>

When you click the **Approve** button, Metamask will open with an approval request like the one pictured above. As we can see, Metamask is asking us to define a custom spending cap. By default, the Maverick dApp will try to fill this field with the maximum possible approval, so that you won't encounter issues with spending caps. If you prefer, you can manually set the cap lower, but please make sure you use at least the minimum recommended in the UI.

<figure><img src="/files/sXuOjMMt6S3LfK43990B" alt=""><figcaption><p>Entering the minimum allowance specified by Maverick's UI.</p></figcaption></figure>

Once you've specified the custom spend limit, you can click **Next** and then confirm the approval in Metamask. At this point, we can confirm our swap and it should execute as expected.

### Resetting approvals in Metamask

If you have previously set an approval limit in Metamask and are trying to make a new transaction that will exceed that limit, you may need to reset your approval in Metamask. In order to do this, you will need to revoke the original approval. This can be accomplished using a tool like [Revoke](https://revoke.cash/), which will show you all of the approvals on a connected wallet and let you revoke them one by one. Then you can re-approve the token on Maverick using a different limit.


# Traders

Here you can find everything you need to know about how to trade on Maverick.

{% hint style="info" %}
**All traders on Maverick will need to install and connect a software cryptocurrency wallet like Metamask.** More instructions can be found in [this guide](/getting-started/connect-a-wallet).
{% endhint %}

{% content-ref url="/pages/IXFOuUH4XmbwHcx9GCgY" %}
[How to Make a Swap](/guides/traders/how-to-make-a-swap)
{% endcontent-ref %}

This section presents step-by-step instructions for executing a swap on Maverick.


# How to Make a Swap

Here you can find step-by-step instructions on how to execute a swap on Maverick.

As the word "Swap" suggests, all trading on Maverick involves the swapping of one token for another. As a trader, you specify the token you want to give and the token you want to receive in return. Obviously, in order to make a swap you will need to have some tokens already in your wallet.

<figure><img src="/files/g06jlTO8wX754w5EtQkm" alt=""><figcaption><p>The Swap Page.</p></figcaption></figure>

The Maverick dApp loads the Swap page by default, but you can also navigate to it at any time using the menu at the top of the screen. When you arrive at the Swap Page, you will see a window with two token inputs. The top one is used to indicate the token you want to trade on Maverick; the bottom one is used to indicate the token you want to receive in return.

<figure><img src="/files/U4IQKgPJxT8OofKVkV4u" alt=""><figcaption><p>Close-up of the Swap window.</p></figcaption></figure>

Use the drop-down menus **(1)** to choose a token pair for your swap. Once you have one token selected, the other drop-down menu will present a list of tokens available for swapping with that token. You can also use the arrow button **(2)** between the tokens to switch the direction of your swap quickly. The tokens available for swapping are limited by the pools currently deployed on Maverick.

You can use the numeric input **(3)** in the token inputs to choose the amount of tokens you want to swap. You can edit the input or the output value, and the AMM will update the other value to the corresponding amount based on the current price of the tokens. If you want to swap all of the token you hold, you can click the Max button **(4)** to choose the maximum amount you have available in your connected wallet. You will also be able to see the current balance **(5)** of each token that is currently in your wallet.

Once you have chosen your tokens and token amounts, the button will update to say **Swap \[input token] to \[output token] (6)** (so long as your wallet balance is sufficient to make the swap and the tokens have both been approved).

{% hint style="info" %}
Please note, the first time you use any token on Maverick, you will be asked to Approve that particular token. UI buttons like Swap/Deposit will show as **Approve \[Token]** until that token has been approved. Approving a token requires you to confirm the choice in a Metamask wallet pop-up. You may also need to set an appropriate spending allowance. Read more [here](/getting-started/approving-tokens).
{% endhint %}

Below the Swap button, you can find a summary of the details of your swap:

* The price you are paying for your swap, expressed as how much output token you are getting for each input token
* The [price impact](/further-information/glossary#price-impact) of your swap on the pool
* The minimum amount of the output token you are guaranteed to receive in the swap

The AMM guarantees a minimum amount because there can still be fluctuations in the pool before you click the Swap button and send your transaction to the blockchain. But you can be certain you will receive the minimum amount if you choose to execute the transaction.

{% hint style="info" %}
In the screenshot, we can note that the previewed output is around 9.995706278 USDT. This may seem a little strange, given that USDC and USDT theoretically share an equal value. The difference in Input and Output is caused by something called **slippage**, which is explained at greater length in [our FAQ](/further-information/glossary#slippage).&#x20;
{% endhint %}

If you want to fine-tune the parameters of your swap, you can use the controls icon **(7)** in the top right of the window. This will allow you to select your slippage tolerance (i.e., how much drift from the quoted price you are comfortable with) and indicate how long you are willing to wait for the transaction to confirm before abandoning it. For more information on slippage, see our [FAQ section](/further-information/glossary#slippage)!

If you are happy with the details of your swap, click **Swap \[input token] to \[output token]**. The UI will now ask you to review and confirm your swap.

<figure><img src="/files/Fk9AXr91mr32DWdcbdFW" alt=""><figcaption><p>The Swap page asking for confirmation.</p></figcaption></figure>

Clicking **Confirm Swap** will send a transaction authorization to your wallet. At this point, a pop-up window should appear asking you to confirm the transaction in your wallet. Click **Confirm** in this window, and it will close. After a short wait, you will see a green pop-up that reads "Swap Successful."

Congratulations--you have completed your first swap on the Maverick!


# Liquidity Providers

Here you can find step-by-step guides on depositing liquidity and deploying pools on Maverick. In other words, everything you need to know about acting as a liquidity provider.

{% hint style="info" %}
**Liquidity Providers will need to connect a cryptocurrency software wallet to use Maverick.** If you need help with this, please follow [these instructions](/getting-started/connect-a-wallet).
{% endhint %}

{% content-ref url="/pages/pXnNNLl5jAWzoyX6yAvN" %}
[Understanding Liquidity Provision](/guides/liquidity-providers/understanding-liquidity-provision)
{% endcontent-ref %}

This page explains the fundamental ideas behind liquidity provision in Maverick AMM.

{% content-ref url="/pages/s43VXfwwcyiiAxDHnp6e" %}
[Understanding Modes](/guides/liquidity-providers/understanding-modes)
{% endcontent-ref %}

This page explains the four Pool Modes available to LPs in Maverick AMM.

{% content-ref url="/pages/rB9tGI2FqzfMPI3uKIHm" %}
[How to Add Liquidity](/guides/liquidity-providers/how-to-add-liquidity)
{% endcontent-ref %}

This page offers step-by-step instructions on how to provide liquidity to a Maverick Pool.

{% content-ref url="/pages/bawypGSGtwy4Oa0OD0Ts" %}
[How to Deploy a New Pool](/guides/liquidity-providers/how-to-deploy-a-new-pool)
{% endcontent-ref %}

This section will walk you through the additional steps required to deploy a new pool.

{% content-ref url="/pages/p995nz7PeBU2F0QwpXbc" %}
[How to Manage Liquidity in a Pool](/guides/liquidity-providers/how-to-manage-liquidity-in-a-pool)
{% endcontent-ref %}

This page explains how to add or remove liquidity to or from an existing position in a Maverick Pool, including how to close your position entirely.

{% content-ref url="/pages/tfSIUl63ZQhn0ydsfeEt" %}
[Liquidity Strategies](/guides/liquidity-providers/liquidity-strategies)
{% endcontent-ref %}

This page explores some of the ways an LP might use Maverick.


# Understanding Liquidity Provision

This page explains the fundamental ideas behind liquidity provision in Maverick AMM.

Liquidity Providers (LPs) supply liquidity to a pool on Maverick for traders to swap against. This means the LP's tokens are used for swaps; i.e., by providing liquidity, the LP agrees to let the AMM sell their tokens to traders. In return, the LP receives trading fees charged to traders for each of their swaps.

Each pool consists of two tokens. In general, an LP supplies quantities of both tokens, although in some cases they may provide only one (sometimes called “single-sided liquidity”) and the actual ratio of the tokens depends on the distribution the LP selects (more on that below!).

An LP’s liquidity is distributed using a series of bins that correspond to different price ranges in a pool. Prices in a pool are a reflection of the ratio between the two tokens in that pool. The widths of the bins vary from pool to pool, and are set by the LP who initially deploys the pool. LPs add liquidity to particular bins in order to execute a particular liquidity strategy.

<figure><img src="/files/raqe7fcdGsMowdKFhNo6" alt=""><figcaption><p>Example of liquidity distributed across bins, with each bin corresponding to a price range for the token pair. The price line shows that currently the central bin is active, which means this is the only bin where liquidity is collecting fees.</p></figcaption></figure>

At any one time, only one bin in a pool is active. This means that swaps are actively occurring at that price point using the liquidity in that bin. As the ratio in the pool changes, the price will move to a new bin, making that the active bin. LPs only collect fees when they own liquidity in the currently active bin.

When a pool is first deployed on Maverick, the deploying LP chooses a [fee tier](/further-information/frequently-asked-questions#how-do-transaction-fees-work-on-maverick) in addition to bin width. The fee tier determines what percentage of the value of their swap a trader will be charged for swapping with the pool.

From an LP perspective, it is possible for multiple pools with different fee tiers and widths to be deployed for the same pair. Traders, however, do not choose between pools: they decide how much they want to swap, and the AMM intelligently routes their swap to the pool which will give them the best value at any given moment. Sometimes this means they will pay a higher fee in return for getting a better price. Ultimately, the market will decide what is the optimal fee tier and width for each token pair.

An LP collects fees based on their pro rata share of the current active bin. Any fees earned are auto-compounded back into the pool, and so the LP’s position in the pool grows proportionally. When an LP exits their position, they redeem their proportional share from the bins in which they are staked.

### Pools vs. Positions

Positions are the foundation of Maverick’s uniquely flexible market making, which allows LPs to enjoy greater capital control and maximize their capital efficiency.

When a user deposits liquidity into a Maverick pool, they select from several options to open a specific position in that pool. Between the token pair, fee tier, bin width, liquidity mode, and liquidity distribution, each user’s position can be heavily parameterized and therefore very different from all other liquidity providers on Maverick. Even within the same pool, users might have their liquidity staked at different price points under different liquidity movement modes. All of these variables make up a user’s position in a pool, which is highly customizable and specific to them.

## Risks

Before engaging in Liquidity Provision, it is important to familiarize yourself with the risks involved. Outlined below are some of the principal risks that all Maverick LPs should be aware of.

### Impermanent Loss

**Impermanent Loss** **or IL** is a concept somewhat unique to DeFi, which is perhaps most simply understood as "loss versus holding." It has become a common metric used in estimating the profitability of providing liquidity to AMMs and is a general risk that comes with LPing using any protocol.

When a user provides liquidity to an AMM, they implicitly agree to accept any trades. This means that the balance of assets they supplied to the AMM is likely to change over time. For example, if an LP's initial position consisted of a 50-50 split between USDC and ETH, trading activity is likely to change that ratio.

IL is calculated by comparing the value of an LP's real-time position in the AMM to the value of their initial deposit if they had just held it. If the market value of ETH goes up, it is likely that traders will come to a USDC-ETH pool and buy ETH for USDC, changing the balance of our LP's 50-50 position (e.g., to 60-40 USDC/ETH). At this moment in time, they are subject to loss versus holding (i.e., IL), since a 50-50 position held outside the AMM would have retained more value during the ETH pump.

Of course, this loss is called "impermanent" for a good reason: as assets change in value, it is possible that the value of the LP's position will return to where it started, at which point they will essentially be back to zero loss versus holding. The loss doesn't become real until the LP removes their liquidity from the AMM, at which point any actual net loss versus holding can be calculated.

For more information on IL, see our [Maverick 101 blog post](https://medium.com/maverick-protocol/maverick-101-impermanent-loss-1659b9d1db0d).

### Permanent Loss

Maverick uses **Permanent Loss or PL** to describe a kind of risk specific to [Mode Both](/guides/liquidity-providers/understanding-modes#mode-both) positions. It is different from Impermanent Loss in that it represents a real and immediate loss to LP's reserves, not a theoretical loss pending withdrawal.

PL can occur in Mode Both positions because the LP is agreeing to buy high and sell low as the liquidity is repositioned. If the price in a pool swings back and forth, the LP can end up buying high and then selling back low, thereby leaking value from their liquidity position. For pools with very wide bins, the risk is mitigated because it will take large price swings before PL becomes a factor.&#x20;

PL is a by-product of Mode Both's high capital efficiency, as the Mode is designed to keep an LP's liquidity as close to price as possible. Mode Both should be used with caution because of the PL risk.

These docs include a [detailed explanation of permanent loss](/guides/liquidity-providers/understanding-permanent-loss).

### Unwanted Movement Risk

In a well-functioning pool, there is a substantial amount of static liquidity that [facilitates the movement of directional liquidity bins](/further-information/frequently-asked-questions#why-isnt-my-liquidity-moving) and makes arbitrage straightforward. This protects LPs in [movement modes](/guides/liquidity-providers/understanding-modes) from bad actors who might otherwise try to manipulate the TWAP that governs liquidity movement in Maverick AMM. Simply put, with sufficient static liquidity it is very difficult to exploit the TWAP, as arbitrage should counteract any wild swings in the pool price. This is partly why Maverick requires users always start with static liquidity when [deploying a new pool](/guides/liquidity-providers/how-to-deploy-a-new-pool).

If a pool doesn’t have enough static liquidity, this can expose movement mode LPs to **unwanted movement risk**, which can lead to Permanent or Impermanent Loss. As an example, a malicious user could create a Mode Both Boosted Position in a pool without static liquidity, use incentives to attract users to that Boosted Position, and then manipulate the TWAP to enable them to purchase LPs’ liquidity at a discount. Without arbitrage to counteract this manipulation, they would only have to wait 3 hours for the TWAP to update and then be able to exploit the movement of the Boosted Position’s liquidity. This unwanted movement risk scales with bin width (i.e., the larger the bin width in the pool, the more risk of unwanted movement).

The best way for an LP to protect against this type of risk is to ensure there is sufficient static liquidity in the pool to which you are adding liquidity. So long as arbitrage can operate properly, it will be very difficult for anyone to manipulate the TWAP. The safest way to do this would be to [add your own static liquidity to the pool](/guides/liquidity-providers/how-to-add-liquidity) before adding in a movement mode, since only you will be able to remove that static liquidity and you will effectively control your own security in the pool.

#### How to Mitigate Unwanted Movement Risk When Deploying a Pool

This section offers some basic guidance on how to ensure there is sufficient static liquidity in a pool to  mitigate unwanted movement risk. This should not be understood as a guarantee that unwanted movement risk will not occur if these instructions are followed. While unwanted movement risk is less of a concern in Maverick V2, all LPs accept a measure of risk when they provide assets to an AMM smart contract.

As explained above, under optimal conditions arbitrage will protect a pool against manipulation of the TWAP. Therefore, the principle that should be followed when using static liquidity to mitigate unwanted movement risk is to make sure that the pool retains a sufficient arbitrage opportunity to outweigh the gas cost in swapping the price back to where it should be.

In order to ensure this arbitrage opportunity, the static liquidity should comprise a range of bins around the current active bin that contain enough liquidity to make swapping the price back more valuable than the cost of making the swap. The amount of liquidity required can be calculated using the equation *absolute gas cost per swap in USD / bin width in the pool*. So, if we assume a swap gas cost of $40 on Ethereum mainnet, for a pool with 0.1% bin width (equivalent to 10 bps) we would need $40,000 (40 / 0.001) of liquidity per bin to ensure an arbitrage opportunity.\
\
In Maverick V2, three bins of the required liquidity (the active bin and the bins to either side) should be sufficient to mitigate unwanted movement risk. Because of how the TWAP behaves in V1, there it would be safer to have ten bins of the required liquidity (the active bin and five bins to either side).


# Understanding Modes

This page explains the four Pool Modes available to LPs in Maverick AMM.

Maverick AMM comes with four out-of-the box liquidity modes for you to choose from:

* [Mode Right](#mode-right)
* [Mode Left](#mode-left)
* [Mode Both](#mode-both)
* [Mode Static](#mode-static-understanding-distributions)

Each of these modes is designed to facilitate a particular kind of liquidity strategy, with the first three all relying on Maverick AMM’s intelligent liquidity-shifting technology to keep your liquidity active according to certain parameters.&#x20;

All liquidity-shifting is performed natively by the Maverick AMM smart contract, which means that LPs using a movement mode never pay gas to move their liquidity.

Liquidity is moved based on the **Time Weighted Average Price (TWAP)** in a pool, which may be different from the current price in a pool. In order to keep things simpler, the explanations below do not make a distinction between TWAP and pool price. If you would like to learn more about how the TWAP works, please refer to the FAQ or the [Whitepaper](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaD2baZPIivxeaMVPT33w%2Fuploads%2F1zoNyAv0LePkAegpa5nU%2FMaverick_Directional_AMM_v1_0.pdf?alt=media\&token=3f590c8b-24e0-4df6-ad74-acbf93e3518c).

Let’s take a closer look at each of the modes in turn.

### Mode Right

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

**Mode Right** functions as a kind of dynamic range order that follows the price in a pool if and when it moves to the right on the liquidity graph. A movement to the right would correspond to an increase in the price of one of the two assets in the pool (in this case, the "base" asset) as their ratio is changed by trading activity. One would expect this to happen if there was an increased demand for that asset, leading to more people coming to the pool to swap it out for the other asset.

> For example, let’s imagine a ABC-XYZ pool, with XYZ being the asset on the right of the liquidity graph (i.e., the "base" asset) and ABC being the asset on the left (i.e., the "quote" asset). In a market where XYZ was performing well, we would expect more traders to be interested in swapping ANC for XYZ. As they visit the pool and make their swaps, the ratio between XYZ and ABC will change, since they will remove XYZ and replace it with ABC. This will cause the price line to move right on the chart, as the AMM accounts for the change in ratio by raising the price of XYZ (i.e., by increasing the amount of ABC required to obtain 1 XYZ).

Mode Right is designed to follow price movement in a single direction, allowing LPs to execute an active liquidity strategy that takes advantage of upward price trajectories. Mode Right allows an LP to add liquidity to the bin directly to the left of the current active bin (they can also add liquidity to the active bin if they want, although this will increase the risk of impermanent loss). If and when the price moves to the right and leaves the current active bin–basically swapping through all of the right asset in that bin–the LP’s liquidity is automatically moved one bin to the right to keep up with the overall movement.

**TL;DR - a Mode Right LP uses the left/quote asset to profit from upward price movement of the right/base asset. The Mode Right LP wants to keep a bin of quote asset directly to the left of price as it moves right in the pool, ready to capture fee whenever price dips left again.**

> For example, let’s return to our ABC-XYZ pool and imagine an LP has opened a Mode Right consisting entirely of ABC, concentrated in the bin to the left of the current active bin. Suppose there is a bull run on XYZ. Traders come to our pool and swap ABC to receive XYZ. Eventually, they will empty the current active bin of all of its XYZ and the price will move right into the next bin, which at this point is composed entirely of XYZ .
>
> In response to this, the AMM reconcentrates all of the LP’s liquidity one bin to the right—into what formerly was the active bin. Since that bin is now completely ABC, it can be freely mixed with the LP's ABC. Now the LP is once more concentrated in the bin to the left of the active bin.

The goal of this strategy is to generate fees for the LP without incurring much impermanent loss. Essentially, an LP uses Mode Right to make a bet on the value of one asset increasing against another. If their bet is correct, they can follow the price to the right and capture fees as it moves.

To be effective, this strategy relies on the fact that price movement is rarely linear. Instead, the price of a token pair experiences a range of micro-adjustments even as it moves in a discernible direction, thanks to the realities of markets and arbitrage. Even if the overall trend is to the right, the price line should frequently dip back to the left due to market corrections or arbitrage opportunities. All of this right-left movement generates trading fees for the LP, and since they are primarily exposed to only one asset in the pair their impermanent loss will be limited.

> To continue our example, the LP’s position has now been reconcentrated into the bin to the immediate left of the current active bin. Although the price is trending to the right, the realities of arbitrage mean that we can expect traders will continue to sell XYZ to the pool any time its price moves out of step with the broader market. Any incoming XYZ will need to be swapped for ABC, which will be supplied from the LP’s bin, thus generating fees. The new XYZ in the LP’s bin will be the first to be sold back to traders, creating more fees for the LP.

It should be emphasized that Mode Right is not a guaranteed return: it is merely a tool designed to automate a particular active liquidity strategy for LPs. LPs should do their own research and will ultimately make their own decision about how the market will move. But an LP with good reason to feel bullish about a particular token can use this mode to generate fees without needing to monitor their liquidity position actively.

{% hint style="warning" %}
It is important to note that Mode Right only follows the price in one direction. Should market trends cause the price in the pool to move to the left instead, the AMM will leave the LP’s bins where they are. This could cause the LP to be swapped completely for the under-performing asset (i.e., the asset on the right/the quote asset) and expose them to [impermanent loss](/further-information/glossary#impermanent-loss).
{% endhint %}

### Mode Left

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

**Mode Left** functions as a kind of dynamic range order that follows the price in a pool if and when it moves to the left on the liquidity graph. A movement to the left would correspond to an decrease in the price of one of the two assets in the pool (in this case, the "base" asset) as their ratio is changed by trading activity. One would expect this to happen if there was an decreased demand for that asset, leading to more people coming to the pool to swap it out for the other asset.

Mode Left essentially functions like Mode Right but in reverse: an LP can add liquidity to the bin immediately to the right of the current active bin (and also the active bin, if they are comfortable with the increased risk of impermanent loss). This is useful if they expect the right (or "base") asset to decrease in value compared to the left (or "quote") asset, resulting in a general trend to the left. If they are correct in their expectations, the price should move progressively to the left, and they should be able to collect fees from accompanying market volatility while experiencing relatively low impermanent loss.

**TL;DR - a Mode Left LP uses the right/base asset to profit from upward price movement of the left/quote asset. The Mode Left LP wants to keep a bin of base asset directly to the right of price as it moves left in the pool, ready to capture fee whenever price dips right again.**

> For example, let’s return to our ABC-XYZ pool, but imagine an LP who foresees a bear market for XYZ . They choose Mode Left, adding some XYZ to the bin immediately to the right of the current active bin. Now let’s assume the LP’s expectation is correct, and XYZ begins to lose market value. Traders come to the AMM to swap their XYZ for ABC, and as the ratio of the assets in the pool changes the AMM moves the price to the left (effectively lowering the amount of ABC a trader will receive for 1 XYZ).&#x20;
>
> As the price moves left out of the active bin, that bin is completely swapped to XYZ. The AMM automatically reconcentrates all of our LP's XYZ into this bin, which now sits immediately to the right of the new active bin. As market volatility moves the price back and forth into this right bin, the LP earns fees from the swaps, and can continue to do so as long as the price stays there or moves further to the left.

{% hint style="warning" %}
Much like Mode Right, Mode Left only functions in one direction. If the price moves to the right, the AMM will not move the LP’s bins at all, and they risk being swapped entirely to the under-performing asset (i.e., the asset on the left/base asset) and becoming exposed to [impermanent loss](/further-information/glossary#impermanent-loss). Again, the modes do not guarantee a particular return–they are designed as a tool to facilitate an LP’s strategy based on their own assessment of market conditions.
{% endhint %}

### Mode Both

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

Mode Both functions as a kind of dynamic range order that follows the price in a pool wherever it moves–right or left. In other words, it follows the pool price up and down. This is in contrast to Mode Right and Mode Left, which only move an LP’s liquidity when the price moves in a single direction.

Mode Both allows an LP to add liquidity to the current active bin and to either of the bins immediately to the left or right of the activer bin. If trading activity moves the price from the active bin into a new bin in either direction (e.g., to the right), the LP’s liquidity on the opposite side (in this case, the left) will be automatically reconcentrated into what was previously the active bin, making more of it available near the pool price.

> For example, let’s use a ABC-XYZ pool again. We’ll imagine an LP who uses Mode Both to stake liquidity in the bin immediately to the left of the current active bin. This means their initial position consists entirely of ABC.
>
> The market value of XYZ goes up, and traders come to the pool to swap it out for ABC. Eventually, these trades swap through all of the XYZ in the current active bin and the price moves right into the next bin, which is composed entirely of XYZ. The AMM now reconcentrates the LP’s liquidity into the bin directly to the left of the active bin, which is composed entirely of ABC. Up to this point, Mode Both has functioned like [Mode Right](#mode-right).

If the price continues to move in the same direction into new bins, the AMM will continue to reconcentrate the LP’s liquidity to follow it. If the price should rebound in the other direction (e.g., from right to left), the AMM will first allow the LP to get swapped through completely and then begin reconcentrating the LP’s liquidity to follow price from the opposite side (in this case, from the right). The purpose of this mechanism is to keep the LP’s liquidity as close to the current price as possible at all times.

> Continuing our example, let’s imagine that the previous price trend reverses, and the value of XYZ begins to fall. Trading activity sends the price back to the left, out of the current active bin and into the bin directly to the left, where our LP’s liquidity was recently reconcentrated. This means the LP's bin is now the current active bin.
>
> The value of XYZ continues to fall, and the price moves through the active bin–swapping all the ABC in it for XYZ–and into the bin to its left. The LP is now staked in the bin directly to the right of the active bin, and their position consists entirely of XYZ. If the price continues trending to the left and moves into the bin to the left of the current active bin, the AMM will reconcentrate the LP's XYZ into the bin directly to the right of the new active bin (formerly the active bin).

Mode Both is designed to capture as much fee as possible by keeping all of the LP’s liquidity concentrated close to the price. Any time the price is moving through a bin in which the LP owns liquidity, they will collect fees.

{% hint style="warning" %}
As should be obvious from the example, however, the risk of [impermanent loss](/further-information/glossary#impermanent-loss) with this mode is higher than either Mode Right or Mode Left, since the LP is exposed to it in both directions. Moreover, they are also subject to “[permanent loss](/further-information/glossary#permanent-loss)” by implicitly agreeing to sell underperforming assets at any point in time. Mode Both therefore carries a significant measure of risk, and users should think carefully before using it.
{% endhint %}

### Mode Static/Understanding Distributions

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

As the name suggests, **Mode Static** allows you to add liquidity without engaging any of Maverick AMM’s liquidity shifting mechanisms. It therefore behaves much like established Range AMMs, in that an LP adds liquidity to a bin or range of bins and that liquidity stays in those bins regardless of where the price moves. Since it doesn’t move liquidity to follow price, Mode Static is likely to be less capital efficient than the other Modes, but LPs may discover their own use cases for it.

Other Range AMMs allow LPs to pick a range over which their liquidity is evenly distributed. In Maverick AMM, an LP can customize their distribution bin by bin, unlocking the potential for more complex liquidity strategies.

When a user selects Mode Static, they get the option of three default distributions:

* **Exponential** - starts with a concentration of liquidity around the current pool price and spreads  the rest of your liquidity in exponentially decreasing amounts across the bins to the left and right.
* **Flat** - distributes liquidity evenly across a range of bins, centered around the current pool price (similar to constant product AMMs).
* **Single Bin** - distributes your liquidity only in the active bin.

For both Exponential and Flat, the user can also specify the percentage of the price range they wish to cover, and the UI will select the appropriate amount of bins based on the bin width of the current pool.&#x20;

Maverick has provided the Exponential distribution as an out-of-the-box option based on the findings of [this paper](https://arxiv-export1.library.cornell.edu/abs/2204.00464) out of Harvard, which concludes that this is the most risk-optimized distribution for LPing in Range AMMs. Flat is available for users who want an LPing experience similar to Uniswap V2 and other constant product AMMs. Both of these distributions can also be customized bin by bin after they have been selected.

Now that we have reviewed the four Modes, we can walk through how to Add Liquidity to Maverick AMM.


# How to Add Liquidity

This page offers step-by-step instructions on how to provide liquidity to a Maverick Pool.

{% hint style="warning" %}
When you add liquidity to Maverick V2, you will mint a Maverick Position NFT. This NFT stores the details of all your liquidity position on Maverick, and is used to manage and remove that liquidity. The wallet that holds a Maverick Position NFT controls the liquidity associated with that NFT. **Do not transfer or sell your Maverick Position NFT unless you want to give control of the liquidity to another wallet.**
{% endhint %}

Users add liquidity to Maverick using the **Add Liquidity** page, which can be accessed from the menu at the top of the screen.

<figure><img src="/files/00qgU0JXflQljfnlrJC0" alt=""><figcaption><p>The Add Liquidity page with Pools tab selected.</p></figcaption></figure>

The Add Liquidity has two tabs: **Boosted Positions** and **Pools**. Boosted Positions are pre-configured positions within a pool that may also offer token incentives for LPs. They are covered in more detail in [this section](/guides/incentives/understanding-boosted-positions) of the docs.

This guide will explain the process of adding liquidity to a regular pool, which will require you to choose a configuration for your liquidity.

Adding liquidity consists of three steps:

1. [**Select Pool**](#select-pool)
2. [**Select Mode**](#select-mode)
3. [**Add Liquidity**](#undefined)

Let's look at each step in turn.

### Select Pool

Once you have navigated to the Pools tab of the Add Liquidity page, the first step is to select the pool you want to add liquidity to. The Pools tab will present a list of pools that have already been deployed across all chains. You can filter the list by chain and by token.

You can choose a pool from this list or create a new pool from scratch. In this guide we'll assume you're choosing an existing pool from the list, since deploying a new pool costs more gas and is for users who have specific liquidity needs that are not met by the available pools. To deploy a new pool, follow [our guide](/guides/liquidity-providers/how-to-deploy-a-new-pool).

In order to add liquidity to a pool, you will need to hold at least one of the two pool tokens in your wallet. You can choose a pool from the list that includes tokens you already hold, or go to the [Swap page](/guides/traders/how-to-make-a-swap) to acquire tokens you will need for a pool.

<figure><img src="/files/zSLSvqBnEqZDV9koDvEr" alt=""><figcaption><p>The Select Pool page.</p></figcaption></figure>

Click a pool will take you to the Select Pool screen. If you want, you can change the token pair you want to add liquidity to using the drop-down menus **(1)**. You can also select a fee tier and bin width at which to add your liquidity. For more information on fee tiers, see [the section in the FAQ](/further-information/frequently-asked-questions#how-do-transaction-fees-work-on-the-testnet).

If you want to change the fee tier and bin width, you can click the **Edit** button **(2)**. This will open a modal where you can choose between the pools that have been deployed for the selected tokens based on fee tier and bin width.

<figure><img src="/files/PEflEEs7vXaXxxVsmrdB" alt=""><figcaption><p>This modal lets you choose between pools based on fee tier and bin width.<br>The checkmark indicates which pool you have selected.</p></figcaption></figure>

The modal lets you choose between pools that have already been deployed and pools that are not yet deployed. If a pool is deployed, it means that at least one other user has added liquidity to that pool. Pools that are not deployed have no liquidity in them and therefore are not yet active. If you use this modal to select a fee tier and bin width that has not yet been deployed, you will have to deploy the pool yourself.

Since there is a wide range of possibilities for combining different fee tiers and bin widths, it is unlikely that all combinations will have been deployed. For the purposes of this guide, we will assume you want to pick from a pool that is already deployed. If you want to deploy a new pool, please see our separate section on [Deploying a New Pool](/guides/liquidity-providers/how-to-deploy-a-new-pool).

The modal sorts pools in ascending order, first by fee tier and then by bin width. You can select the fee tier and bin width you want by clicking on it. This will cause a checkmark to appear by that pool, indicating your selection. Once you've chosen the pool you want, you can click the **Select** button to confirm your choice and close the modal.

The UI will load information about your chosen token pair and fee tier in the windows on the right, including TVL, volume, and an overview of the current liquidity distribution in that pool. If everything looks good, click **Next (3)** to continue.

### Select Mode

<figure><img src="/files/vwFUKkJL8aySni3ITLpt" alt=""><figcaption><p>The Select Mode page.</p></figcaption></figure>

On the next page, you can select the liquidity mode. If you haven't already, now would be a good time to review our section on [Understanding Modes](/guides/liquidity-providers/understanding-modes). The Select Mode page presents a brief explanation of each Mode and accompanying video, but the section here goes into a lot more detail.

Select the desired Mode for your liquidity, then click **Next** to continue. Alternatively, you can click **Back** to return to the Select Pool page and change your token pair and/or fee tier.

### Add Liquidity

In the final step, you choose how much liquidity to add from your wallet, as well as how that liquidity will be distributed within the pool.

Maverick AMM provides a lot of options for configuring liquidity distributions. Here, we'll walk through the basic mechanics for adding liquidity, starting with the three movement modes and then looking at Mode Static. Again, if you need help understanding Modes, please see the [relevant section in this guide](/guides/liquidity-providers/understanding-modes).

#### Adding Liquidity to a Movement Mode

<figure><img src="/files/gZb6bupgZXUxCe6Hjsbh" alt=""><figcaption><p>The Add Liquidity page, with Mode Right selected. Since the bin to the left of the active bin is selected, only USDC is required.</p></figcaption></figure>

The screenshot above shows the Add Liquidity page after a user has selected Mode Right. The two token boxes on the right **(1)** are used to set the overall amount of liquidity you wish to add to the pool. These are interactive with the distribution chart on the right, meaning that the AMM will automatically compute the correct ratios of the two tokens required by your current distribution.

The default state for Mode Right is to add liquidity to the bin directly to the left of the current active bin. Since this bin isn't active, it will consist entirely of the left/base token (here, ZRO). This means that the current distribution will only require you to deposit ZRO, so adjusting the amount of ZRO in the token box on the left will have no effect on the other token box (here, ETH).

You can adjust the amount of ZRO being added by grabbing the top of the bin **(2)** and dragging it up and down. in height corresponds to amount of liquidity in the bin, and as you move the bin heights you will see the amounts on the left change accordingly. Since the bin we're looking at contains only ZRO, changing its height will only change the amount of ZRO to be added.

In Mode Right, you can also choose to add liquidity to the current active bin or the bin to its right. To do this, click on the tab for that bin **(3)** and drag it up. The active bin will contain both tokens, and so once it is active you will need to deposit quantities of both. In this example, if we activated this bin we would see the amount of ETH increase in the token box on the left.

The bins for the three movement Modes behave similarly, with these important differences:

* **Mode Right**: starts with bin to left of active bin, active bin and bin to its right can be staked as well
* **Mode Left**: starts with bin to right of active bin, active bin and bin to its left can be staked as well
* **Mode Both**: starts with active bin, bin to right and/or left can be staked as well

Default bins were chosen for what is theoretically the ideal use-case for each Mode, but users are also offered the flexibility to find other uses for all of the Modes.

Once you have finished customizing the size and distribution of your position, you can click **Confirm** to [continue](#confirming-your-pool-transaction).

#### Adding Liquidity to Mode Static

<figure><img src="/files/cuPHqw8Y1ysW0rjfi8v1" alt=""><figcaption><p>The Add Liquidity page, with Mode Static selected.</p></figcaption></figure>

The screenshot above shows the Add Liquidity page after a user has selected Mode Static. The two token boxes on the right **(1)** are used to set the overall amount of liquidity you wish to add to the pool. These are interactive with the distribution chart on the left, meaning that the AMM will automatically compute the correct ratios of the two tokens required by your current distribution.

You can use the Edit button **(2)** in the Select Distribution section to choose an initial distribution model for you to use or customize. The options are:

* Exponential
* Flat
* Single Bin

For more information on distributions, please see our [Understanding Modes](/guides/liquidity-providers/understanding-modes) section.

You can also edit the Distribution Width **(3)** to change the overall width of your distribution across the pool's price range. By default, this is set to 0.1%, meaning that your distribution will span 0.1% of the total price range, plus the current active bin as a center point. The UI will automatically calculate the number of bins required to cover this width. The number of bins required will depend on the bin width in the pool (the wider the bins, the fewer will be required to cover the width of your distribution). A pool with a 0.01% bin width will require 11 bins to cover a distribution width of 0.1% (10 bins plus the current active bin).

{% hint style="info" %}
Larger distribution widths will cost more gas. Please keep this in mind when adjusting your distribution width.
{% endhint %}

If you want to change the Distribution Width, edit the numeric field at **(3)** and then click the **Update** button. The distribution chart will refresh to show the new distribution.

You can tweak the shape of any of the distributions by clicking the top of a bin (e.g., at **(4)**) and dragging the bin up and down. Bin height corresponds to amount of liquidity in the bin, and as you move the bin heights you will see the amounts on the right **(1)** change accordingly. The active bin contains both tokens, so moving it will affect both token amounts. The bins to either side of the active bin are single token bins, so will only affect one of the tokens.

Once you have finished customizing the size and distribution of your position, you can click **Confirm** to continue.

#### Confirming Your Pool Transaction

{% hint style="info" %}
Please note, the first time you use any token on Maverick, you will be asked to Approve that particular token. UI buttons like Swap/Confirm Amount will show as **Approve \[Token]** until that token has been approved. Approving a token requires you to confirm the choice in a software cryptocurrency wallet pop-up. You may also need to set an appropriate spending allowance. Read more [here](/getting-started/approving-tokens).
{% endhint %}

<figure><img src="/files/0bQYEH1ANSfWmHX8DzJv" alt=""><figcaption><p>The Confirm Pool modal.</p></figcaption></figure>

Clicking the Confirm button will open the Confirm Pool modal. This modal will walk you through the final steps necessary to add liquidity to the pool. If you have yet to approve either token on Maverick, you will first be asked to approve them. In the screenshot above, USDC and LINK have already been approved, so the modal has advanced to the third step.

The modal will present a summary of your proposed transaction, including the amounts of each token to be deposited from your wallet, the chosen Fee Tier for your pool, and the Mode you are using for your liquidity. If everything looks correct, click **Confirm Amount** to send the transaction to MetaMask for approval. If you need to edit something, you can click the X at the top right of the modal to return to the Add Liquidity flow.

If you click **Confirm Amount**, a pop-up window should appear asking you to confirm the transaction in your wallet. Confirm the transaction. After a short wait, you will see a green pop-up window that reads "Add Liquidity Successful." You can now choose to review the transaction on Explorer or close the modal to be taken to the Portfolio page, where you can track all of your liquidity positions on Maverick.


# How to Deploy a New Pool

This section will walk you through the additional steps required to deploy a new pool.

In our [guide to adding liquidity](/guides/liquidity-providers/how-to-add-liquidity), we saw that it was possible to deploy a new pool if one did not already exist at your desired fee tier and bin width. In this section, we'll address the additional steps that deploying a new pool will require as you're adding liquidity.

For every token pair in Maverick AMM, there can be multiple pools with different fee tiers and bin widths. This is in order to fit the needs and strategies of different liquidity providers. These pools are not differentiated for swappers—instead, the AMM will intelligently rout their swaps to whichever pool can currently offer them the best overall price. For more information on fees, please see the [section in our FAQ](/further-information/frequently-asked-questions#how-do-transaction-fees-work-on-the-testnet).

If there isn't yet a pool for your desired token pair or if the pool that does exist doesn't have the bin width and/or fee tier you want, you can deploy a new pool. You will have to add liquidity to it before it becomes active. If you do not complete every step of the Add Liquidity flow, the pool will remain undeployed.

{% hint style="info" %}
When a new pool is deployed, it first needs liquidity to be added in Mode Static. Without a base layer of some static liquidity the movement modes will not work as expected. If you choose to deploy a new pool, the movement modes will be disabled and you will be required to start it with static liquidity. Learn more [here](/guides/liquidity-providers/understanding-liquidity-provision#unwanted-movement-risk).
{% endhint %}

## How to deploy a new pool

You can start the new pool flow by adjusting parameters on the Select Pool page, which can be accessed by clicking on any pool in the list on the Pools page.

The first step is to select the token pair using the dropdown menus on the Select Pool screen. If you select a pair that has not yet been deployed on Maverick, the page will update to the Pool Not Deployed state ([more on that below](#configuring-a-new-pool)).

If the pair has already been deployed but you want to choose a new fee tier and/or bin width, you can click the **Edit** button (**1)** under Select Fee Tier:

<figure><img src="/files/jMtoV5bijPtuRrzFpKX5" alt=""><figcaption><p>On the Select Pool page, users can choose to edit the fee tier and bin width of the pool to which they will be adding liquidity.</p></figcaption></figure>

This will open a modal showing all the fee tier and bin width options. By default, the modal lists all of the currently deployed pools, but a user can click the **Not Deployed** tab **(2)** at the top of the modal to choose from a list of pools that have yet to be deployed:

<figure><img src="/files/VHRAmd7iaeduAlyziBb8" alt=""><figcaption><p>From within this modal, users can click on the "Not Deployed" tab to see a list of pools that have yet to be deployed.</p></figcaption></figure>

Like the Deployed tab, the pools listed here are listed in ascending order, first by fee tier and then by bin width. If a pool is listed under this tab, it means that there is no liquidity in it and it is not active on Maverick.

If you want to move ahead with deploying one of the fee/width combinations that has not yet been deployed, you can select it by clicking on it. A checkmark will appear next to it to show it has been selected. You can now click **Select** and the modal will close.

The Select Pool page will now update to the Pool Not Deployed state.

### Configuring a new pool

When the Select Pool is in the Pool Not Deployed state, the liquidity graph on the right is replaced by basic instructions on deploying a new pool.&#x20;

<figure><img src="/files/Hpu1uRSAtzEswohMuBNt" alt=""><figcaption><p>The Select Pool page in the Pool Not Deployed state.</p></figcaption></figure>

If you haven't already, you should select the fee tier and bin width. This is done by clicking the **Edit** button **(1)** under **Select Fee Tier**.

You will also need to select a starting price for your pool **(2)**. This is denominated in the base asset (the first of the two assets selected).

{% hint style="warning" %}
Be very careful when selecting the starting price of a new pool. It is recommended that you choose a price as close to the market price as possible. If you start a new pool at a price that diverges from the market price, you may lose funds to arbitrage.
{% endhint %}

After you have selected the initial pool parameters, you will need to [add liquidity](/guides/liquidity-providers/how-to-add-liquidity) as with any other pool. Again, if you do not complete all the steps in the add liquidity flow, the new pool will not be deployed.


# How to Check Position Balances

This page explains different methods to check the balance(s) of tokens in your liquidity position.

## Use the dApp UI <a href="#docs-internal-guid-30082fc7-7fff-cea9-6781-139b7c2c0745" id="docs-internal-guid-30082fc7-7fff-cea9-6781-139b7c2c0745"></a>

Perhaps the easiest way to check your position balance is to use the dApp itself. Navigate to the Portfolio page using the link in the top menu.

<figure><img src="/files/f1ZerL0KROcZHmx8qlGV" alt=""><figcaption><p>The Portfolio page with three position cards, representing three positions.</p></figcaption></figure>

On this page you will find a card or cards representing every liquidity position associated with your wallet. Each card shows the pool, distribution, TVL, and fees earned by the position. If you want more information about a particular position, you can click Manage to be taken to that position’s sub-page.

<figure><img src="/files/St0NihOHdBhuRBj8dqVs" alt=""><figcaption><p>The Manage Liquidity page shows more detail about a position. Highlighting a liquidity bin will show you exactly how many tokens you have in that bin.</p></figcaption></figure>

On this page you can find more detailed information about the position. The top row presents balances for each token in the pair, the TVL of the position denominated in USD, and the volume and fees generated by the position.

You can also mouseover individual bins in the position chart to find the exact quantities of each token deposited in each bin.

## Use blockchain calls

If you prefer, you can query the blockchain using a block explorer. In order to do this, you will need your wallet address and the address of the pool you've added liquidity to. You can find the address of any pool in the Maverick UI using the link icon on the Select Pool page.

<figure><img src="/files/oNgIpPdoJ0Eg67w4wB9L" alt=""><figcaption><p>Use this link icon to find the address of a pool from the UI.</p></figcaption></figure>

In the screenshot above, the link icon leads to this URL:

```
https://explorer.zksync.io/address/0x74a8f079eb015375b5dbb3ee98cbb1b91089323f
```

The pool address is the 0x number. So in this case, it is `0x74a8f079eb015375b5dbb3ee98cbb1b91089323f`.

Once you have the pool address, you can navigate to the relevant PositionInspector contract for each chain:

* **Ethereum:** <https://etherscan.io/address/0x456A37144162900799f405be34f815dE7C3DA53C#readContract>
* **zkSync Era:** <https://explorer.zksync.io/address/0x852639EE9dd090d30271832332501e87D287106C#contract>
* **BNB Smartchain:** <https://bscscan.com/address/0x70cd6087033e0b99e4e449d3b904fad194d888a0#readContract>

On the contract page, select **Read Contract** and expand the second section labelled `addressBinReservesAllKindsAllTokenIds`.

<figure><img src="/files/3i8bLl9wIbyq2ebCHc2A" alt=""><figcaption><p>Example of the PositionInspector contract on zkSync Era with the pool address pasted in.</p></figcaption></figure>

Copy/paste your wallet address into the `owner (address)` field and the pool address you found above in the `pool (address)` field.

Click Query. If you have a position in the pool, you will see how much of each of the tokens you have.


# How to Manage Liquidity in a Pool

This page explains how to add or remove liquidity to or from an existing position in a Maverick pool, including how to close your position entirely.

Once you have added liquidity to a pool in Maverick, you will be able to find a summary of your position(s) on the **Portfolio** page, accessed from the top left menu on any page in the dApp. Here you can easily see the total balance of each position and its distribution within the pool.

<figure><img src="/files/YqVnQZJF97Fwpq5hDCJW" alt=""><figcaption><p>Once you have added liquidity, your positions will be shown on the Portfolio page.</p></figcaption></figure>

If you want to make any changes to one of your liquidity positions, simply click on the Manage button at the bottom of that position’s card. This will take you to the **Manage Liquidity** page, where you will again find a summary of your balance and its distribution within the pool.

<figure><img src="/files/Zj9VFwel7hmW0hr4tTVN" alt=""><figcaption><p>The Manage Liquidity page.</p></figcaption></figure>

From here, you can choose to Remove liquidity from your position or Add more liquidity to it. Clicking **Add** will also give you the option to adjust the distribution of the liquidity in your position.

### Removing Liquidity

Clicking **Remove** will take you to the **Remove Liquidity** page. Here, you can choose individual bins of liquidity to remove from your position and have their balance returned to your wallet. If you choose to remove a bin, it will be removed entirely–there is no option to remove only a portion of a given bin.

<figure><img src="/files/eVrpvguJX3XZBIHwsWrT" alt=""><figcaption><p>The Remove Liquidity page. By default, no bins are selected for removal.</p></figcaption></figure>

By default, none of your bins will be selected for removal. You can click on the bins in the liquidity chart to select them for removal. Alternatively, you can click the **Bins Selected** drop-down **(1)** to select the bins you want to remove. This will open up a modal which will list every bin in which you have liquidity in this pool. You will be able to see the price range for each bin and the balance of each bin.

<figure><img src="/files/c0qHVrATrlmyWbCHxIgN" alt=""><figcaption><p>Selecting bins for removal. Bins with a visible checkmark will be removed.</p></figcaption></figure>

{% hint style="info" %}
With the exception of the current active bin, which should have a mix of both tokens, your bins should only have a balance for one of the two assets in the pool (e.g., your bins to the left of the current active bin will only have balances of the left asset, and vice versa).
{% endhint %}

Click the boxes next to any bin you wish to remove. If the box has a visible checkmark in it, this means it has been selected for removal. If you want to close your position entirely, simply make sure all of the bins are selected.

Once you have selected all the bins you wish to remove, you can click **Select** to move ahead with the removal process. If you wish to cancel, you can click the **X** in the top right of the modal instead.

<figure><img src="/files/rIbXSzwzb4QiDmgQRfzq" alt=""><figcaption><p>The Remove Liquidity page has updated to show bins selected for removal.</p></figcaption></figure>

The page will now update to highlight the bins you have chosen for removal. You will also be presented with a summary of how much of each token you are about to remove and send to your wallet. If everything looks correct, you can click **Confirm**.

{% hint style="info" %}
The first time you remove liquidity from Maverick, you will need to approve the smart contract's access to your [Maverick Position NFT](/further-information/frequently-asked-questions#what-is-a-maverick-position-nft-why-am-i-being-asked-to-approve-it). This will require a simple confirmation in your connected software wallet.
{% endhint %}

You will be asked to confirm the transaction in your wallet. Once the transaction is confirmed, the funds will be moved to your wallet and you will be returned to the Home page.<br>

### Adding Liquidity

Clicking **Add** will take you to the beginning of the Add Liquidity workflow, with the same pool automatically selected. Your current position will load automatically, and any changes you confirm will update your original position. For more information on the Add Liquidity workflow, please refer to our [detailed section](/guides/liquidity-providers/how-to-add-liquidity).


# How to Migrate from V1 to V2

With the launch of Maverick V2, all LPs are encouraged to migrate any existing liquidity they have in Maverick V1 to the new V2 pools and Boosted Positions.

There are three main reasons to migrate your liquidity:

* With its optimizations to Maverick AMM, V2 is expected to offer cheaper swaps and therefore capture more trade flow than V1. Migrating your liquidity is the best way to make sure your capital stays as efficient as possible.
* Most--if not all--token projects will be directing their incentives to Boosted Positions on Maverick V2, which are eligible for further token rewards from the V2 veFlywheel. LPs who are interested in incentives and rewards should migrate to V2 to make the most of these opportunities.
* Over time, trade flow is expected to migrate entirely from V1 to V2. Swappers will come to the V2 UI instead of the V1 UI, and any liquidity left in V1 will not be used as much.

### How to Migrate from V1 to V2

Migrating liquidity is straightforward. Simple open your Portfolio on [Maverick V1](https://app-v1.mav.xyz/) and remove the liquidity from any pools or Boosted Positions you see there. If you need help managing liquidity, please see [this guide](/guides/liquidity-providers/how-to-manage-liquidity-in-a-pool).

Once you have removed any liquidity and it has been returned to your wallet, you are ready to add it to Maverick V2. Head to the [Maverick V2 UI](https://app-v2.mav.xyz/) and [add  your liquidity](/guides/liquidity-providers/how-to-add-liquidity) to whichever pools and/or Boosted Positions you want. You should find most of the more popular pools already replicated in V2. If you cannot find the precise pool you are looking for, you can always [deploy a new one](/guides/liquidity-providers/how-to-deploy-a-new-pool).

Once your liquidity has been removed from V1 and added to V2, you have successfully completed your migration.


# Understanding Permanent Loss

This page uses an extended example to explain the risks of Permanent Loss, especially using Mode Both.

Elsewhere in these docs, it is indicated that Maverick’s Mode Both carries a risk of something called **permanent loss**. This is a novel concept, and its meaning may not be immediately clear to many users. This page explains how permanent loss can occur. **It is intended for educational purposes only, and should not be understood to constitute financial advice.**

***

In order to explain permanent loss, let’s really simplify a liquidity pool. We’ll use slightly rounder numbers than you’ll see in a real liquidity pool. We’ll also imagine simple, linear price movements, rather than the irregular, zigzag patterns that usually happen in reality. And we won’t be taking into account any fees earned, even though in reality any time an LP’s liquidity is used for swaps they earn a fee.

Let’s start by imagining an ABC-XYZ pool–that is, a pool containing the imaginary tokens ABC and XYZ–which starts at a price ratio of 1:1 (so 1 ABC is worth 1 XYZ). We’ll give this pool a bin width of 1%, which means that each bin covers a price range of 0.01 ABC/XYZ. If we also imagine a linear distribution of liquidity in the pool, it would look something like this:

<figure><img src="/files/8sZAEjBFRJ5FoIbYHKUx" alt=""><figcaption><p>A simplified Maverick AMM pool with imaginary ABC token on the left and imaginary XYZ token on the right.</p></figcaption></figure>

Suppose Alice deposits an even mixture of ABC and XYZ into this pool–say 10 ABC and 10 XYZ. She selects Mode Both, because she wants to keep her liquidity as active as possible. She has read that this carries an increased risk of loss, but decides to continue anyway.

She deposits her 10 ABC and 10 XYZ into the current active bin. In our simplified model, this bin would cover a range where ABC sells for 1.00-1.01 XYZ and XYZ sells for 0.99-1.00 ABC.

<figure><img src="/files/sikQY7voXa8B8UQOxely" alt=""><figcaption><p>Alice adds 10 ABC and 10 XYZ to the current active bin using Mode Both.</p></figcaption></figure>

Now imagine that XYZ pumps in the market. In fact, its market value increases to 1.10 ABC. Alice’s pool is currently selling XYZ for 0.99-1 ABC, so traders will come and swap the pool’s XYZ to ABC.

Alice is swapped completely to ABC. To keep the math simple, let’s assume she got 1 ABC for every XYZ that was sold, so she now holds 20 ABC in that bin in this pool.

<figure><img src="/files/G6tL30nUxklLuHh5MJWD" alt=""><figcaption><p>Traders swap ABC for XYZ and the current active bin (including Alice's liquidity) is swapped completely to ABC. The pool price moves one bin to the right in order to keep servicing swaps.</p></figcaption></figure>

Once the AMM has sold all the XYZ it has available at 0.99-1 ABC, it will move to the next price range and start selling XYZ for 1-1.01 ABC. Since the market price is 1.10 ABC, traders will continue buying XYZ so long as the pool offers it at a discount.

We can expect the AMM to keep selling through each bin until the pool price is roughly equal to the market price. In this case, this would mean reaching the bin where XYZ = 1.09-1.10 ABC.

<figure><img src="/files/IomoPfhFd7UNOmOdcqin" alt=""><figcaption><p>Traders continue to swap ABC for XYZ and the price continues to move right into the next bin over.</p></figcaption></figure>

Since Alice selected Mode Both, the AMM has instructions to move her liquidity to follow the price, so that she can be ready to capture any trades if the price swings back the other way. This means that every time the price moves two bins ahead of Alice’s liquidity, her liquidity is moved one bin closer to the price.

<figure><img src="/files/gI96VBxW5b073tm8SJIx" alt=""><figcaption><p>Because Alice chose Mode Both for her liquidity, the AMM moves her liquidity one bin to the right to follow the price.</p></figcaption></figure>

The end result is Alice’s 20 ABC will be moved by the AMM until it reaches the bin where XYZ = 1.09-1.10 ABC (one tick behind where price moved to). This means Alice’s 20 ABC is available for trades at a price of 0.91-0.92 XYZ. The Mode Both function is essentially offering a discount on Alice’s ABC, in order to make it available for trades ASAP.

<figure><img src="/files/KoF3GMmaMTJSEv3vDQFb" alt=""><figcaption><p>The AMM continues to move liquidity to the right to follow the price right during this XYZ pump.</p></figcaption></figure>

Now let’s assume the price of XYZ suddenly drops. Its market value decreases to 0.9 ABC. Right now, the AMM will buy XYZ for 1.09-1.10 ABC, meaning that traders will come and sell XYZ to Alice’s pool to take advantage of that price.

Once the ABC in the current active bin (which is selling for 0.91-0.92 XYZ) is sold through, the AMM will move to Alice’s bin and start selling the liquidity there–including her 20 ABC. Again, to keep things simple let’s say she gets a price of 0.92 XYZ for her 20 ABC. This leaves her holding 18.4 XYZ.

<figure><img src="/files/efGhNqW4WVTKRFAo7UXf" alt=""><figcaption><p>The market sentiment swings in the other direction, and traders begin swapping XYZ for ABC. The current active bin and Alice's bin are swapped completely to XYZ, and the price continues moving to the left in order to keep servicing swaps.</p></figcaption></figure>

It may be immediately apparent that Alice has taken a loss here, since she only got 18.4 XYZ for her 20 ABC. For comparison, let’s imagine a world where she had used Mode Static instead of Mode Both. In that world, after the initial XYZ pump that swapped her to 20 ABC, her liquidity would not have moved. It would still be in the bin where the price of ABC = 1.00 - 1.01 XYZ. During this XYZ dump, her ABC would not have been sold until the price reached her bin, at which point she would have got something like 20 XYZ for her 20 ABC.

Maverick calls Alice’s loss “permanent loss,” because (unlike [impermanent loss](/further-information/glossary#impermanent-loss)) it is now baked into her liquidity position. By selling low and buying high, Alice has lost some of her liquidity, and this will not be recovered through pool rebalancing.

In fact, permanent loss can actually compound: we said that the market value of XYZ had dumped to 0.9 ABC. This means that the AMM will continue selling through ABC in the pool until the pool price roughly equals the market price. This means when the pool price reaches the bin where XYZ = 0.90-0.91 ABC.

After Alice was sold through to 18.4 XYZ, Mode Both would again have done what it is designed to do: move her liquidity to follow price so that it is available to capture more swaps ASAP. Again, it would have followed one bin behind each price movement as the XYZ price moved down. The end result would be that Alice’s 18.4 XYZ would come to rest in the bin where XYZ = 0.91-0.92 ABC–once again, offering a discount to improve the chances of capturing trades.

<figure><img src="/files/kf9wCjfBoAI0V3vNcCl0" alt=""><figcaption><p>Since Alice chose Mode Both, the AMM moves her liquidity to follow price in the opposite direction as well. Her liquidity ends up in the bin directly to the right of the current active bin.</p></figcaption></figure>

If XYZ pumps again, Alice will quickly be sold through to ABC once again. For simplicity’s sake, let’s say she gets a price 0.92 ABC per XYZ. This leaves her holding 16.928 ABC while XYZ continues to pump.

This is why Mode Both is an especially risky choice for LPing volatile pairs. Every time Mode Both moves an LP’s liquidity, it is essentially offering a discount on their liquidity. The more bins it moves, the bigger the discount. And the more frequent the swings, the more opportunity for these discounts to compound into bigger losses.

***

**If permanent loss is such a risk, why would I use Mode Both?**

Mode Both is a better fit for stablecoin pairs. The relatively low volatility of these pairs means that LPs can provide liquidity in a narrow range without being exposed to as much permanent loss. Fees also tend to be higher, which can help offset any loss accrued from LPing. Stablecoin LPs in other range AMMs would have to spend a lot of gas (\~800k per rebalance) in order to achieve similar capital efficiency to Mode Both.


# Liquidity Strategies

This page explores some of the ways an LP might use Maverick.

Maverick AMM provides a flexible set of tools to facilitate a wide variety of liquidity strategies. This page presents an overview of some of the basic use-cases for Maverick AMM’s modes and distributions. This doesn’t represent the limit of Maverick AMM’s capabilities: it is likely that sophisticated LPs will find any number of new situations where Maverick’s customizable distributions can be put to specific use.

{% hint style="warning" %}
What follows is an overview of theoretical use-cases for Maverick AMM. In no way should this be interpreted as investment advice or a guarantee of specific returns. Most if not all of the strategies explored below require the individual LP to make a correct prediction of how the market will move. Maverick makes no guarantee that an LP’s prediction will be correct. Providing liquidity–especially concentrated liquidity–always comes with a risk of loss. Please be sure to do your own research and understand the risks involved before using Maverick AMM.

For more information, please see Maverick's [Terms of Service](https://assets.mav.xyz/terms-of-service).
{% endhint %}

## Basic strategies for movement modes

Maverick AMM features three movement modes: Right, Left, and Both. If an LP selects one of these modes, the AMM will automatically move their liquidity to follow price according to a certain set of rules. These rules can briefly be summarized as follows:

* **Mode Right** follows price when it moves right, doesn’t move when price moves left
* **Mode Left** follows price when it moves left, doesn’t move when price moves right
* **Mode Both** follows price in both directions

Right and Left correspond to movements along a price axis in a given pool. For example, we can imagine a pool for two tokens–ABC token and XYZ token–and look at a hypothetical liquidity chart for this pool:

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

The AMM smart contract determines the pool price for the ABC-XYZ pool based on the amount of ABC and XYZ in that pool. As trades happen with the pool, the amount of ABC and XYZ will change. For example, if traders bring a lot of ABC and swap it out for XYZ, there will be more ABC and less XYZ in the pool. Trades occur at the current price, using the liquidity in the current active bin. In the chart above, the price is in an active bin which holds a mixture of ABC and XYZ.&#x20;

Following our example, if traders swap ABC for XYZ, the balance in that bin will shift towards more ABC and less XYZ, until a point where the bin only holds ABC and the price moves into the next bin to the right so it can continue to supply XYZ to traders:

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

This is how the AMM understands Right and Left: the movement of price within a pool as the ratio of tokens in it changes. In the ABC-XYZ pool imagined above, a price movement to the Right will correspond to an increase in the price of XYZ and a decrease in the price of ABC. Conversely, a price movement to the Left will correspond to a decrease in the price of XYZ and an increase in the price of ABC.

Since all of the movement in these modes is automated by the smart contract, an LP using a movement mode does not pay gas fees when their liquidity is moved.

### Directional Price Belief

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

If an LP has reason to believe that the price in a particular pool is going to move in a specific direction–that is, that the value of one token is going to increase in relationship to the other–they can use Mode Left or Mode Right to automate a strategy that has their liquidity follow that price movement.

For example, if an LP believes that XYZ token’s market value vs. ABC will increase over time, they can use Mode Right to have a bin of liquidity follow the price movement and collect fees from trading activity in the pool. This LP would put ABC in a Mode Right bin directly to the left of the current active bin. If they anticipate a price movement in the opposite direction, they can reverse the strategy using a bin of XYZ in Mode Left.

✔ **Advantages:**

Keeps capital in range and efficient

LP does not pay gas fees to move their liquidity

LP can stay largely exposed to a single asset

✖ **Drawbacks:**

Requires LP to predict pool price accurately

High risk of impermanent loss if the price moves in the opposite direction

🤔 **Considerations:**

Mode Right and Mode Left only move liquidity in one direction; if price swings dramatically in the opposite direction, LP will likely need to rebalance manually

### Sideways price belief

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

If an LP believes a particular token pair is likely to have a sideways price relationship (i.e., largely stable with subtle moves up and down), they can use Mode Both to keep their liquidity active and collecting as much fee as possible.

In our example pool, they would typically add liquidity to the current active bin in Mode Both. This will usually require a mix of both tokens, depending on the current state of that bin when they add liquidity.<br>

✔ **Advantages:**

Keeps capital in range and efficient wherever price moves

LP does not pay gas fees to move their liquidity

Well-suited to stablecoin pairs<br>

✖ **Drawbacks:**

Requires LP to bring both assets to the pool

Risk of permanent loss in the event of sudden price swing back and forth

## Basic strategies for Mode Static

Maverick AMM also features Mode Static, which doesn’t engage any of the automated liquidity features found in the movement modes. In Mode Static, your liquidity stays wherever you decide to put it. In this way, Mode Static is closer to the experience of adding liquidity to other range AMMs. Maverick AMM, however, gives LPs increased flexibility in choosing exactly how their liquidity is arranged in static distributions, making it more versatile and enabling a wider variety of strategies. Here, we explore just a few approaches Maverick LPs might take when configuring static liquidity distributions.

### Exponential distributions

A [Harvard study](https://arxiv.org/pdf/2204.00464.pdf) has shown that exponential distributions offer the best risk optimization for static liquidity provision. By placing the majority of their liquidity at the current price, and then spreading the rest of it in progressively lower amounts in the bins to either side, an LP can benefit from liquidity concentration while limiting their risk if price moves. This is why the exponential distribution is the default option when a user selects Mode Static in Maverick.

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

✔ **Advantages:**

Presents good balance of concentrated liquidity and risk limitation<br>

✖ **Drawbacks:**

Static liquidity may require rebalancing if price moves out of range

Risk that liquidity on either edge of the range may never be utilized<br>

🤔 **Considerations:**

It would require minting multiple positions NFTs to produce this distribution in Uniswap V3; Maverick lets you do everything with one

### Flat distributions

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

If a user prefers something closer to the traditional *xy=k* AMM, they can also choose a flat distribution that places equal amounts of liquidity in bins at each tick along the price range. This type of liquidity provision continues to enjoy favor due to the low risk of impermanent loss, but is very inefficient and can lead to high slippage for traders.

✔ **Advantages:**

Can cover a broader price range for volatile pairs

Provides some protection against impermanent loss<br>

✖ **Drawbacks:**

Very inefficient, since most of an LP’s capital will be out of range at any point in time

🤔 **Considerations:**

Staking wider ranges is very gas intensive

LPs may still have to rebalance if price moves out of range

### Limit order

<figure><img src="/files/12BbsIxD8tMLSpG70ivB" alt=""><figcaption></figcaption></figure>

An LP can use a single bin of liquidity to mimic a traditional limit order, i.e., a buy or sell order at a particular price. If an LP has a bag of XYZ token they only want to sell if it hits a certain price, they can place all of those tokens in a bin at that price tick. The AMM will only let traders swap it to ABC if the price moves to that tick.<br>

✔ **Advantages:**

Lets users execute limit orders without a middle-man

Users can make a swap and collect fees for it, instead of paying them

✖ **Drawbacks:**

LP could be swapped back if they don’t remove liquidity before price changes

🤔 **Considerations:**

Users might want to compare the cost in gas fees between a simple swap and adding/removing liquidity to/from an LP position

### "Dollar Cost Averaging"

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

While not precisely a Dollar Cost Averaging (DCA) strategy, LPs can use a flat static distribution to sell gradually from one token into another. For example, by placing equal amounts of XYZ at several ticks to the right of price in our pool, an LP can slowly let themselves get swapped to ABC as the value of their XYZ increases.<br>

✔ **Advantages:**

Lets users execute a buy-sell strategy without a middle-man

Users can make a swap and collect fees for it, instead of paying them<br>

✖ **Drawbacks:**

LP could be swapped back if they don’t remove liquidity before price changes<br>

🤔 **Considerations:**

AMM-based buy-sell strategies like this can be used to make large token buys without affecting market price in the same way conventional swaps will

### Buy-Sell ramp

<figure><img src="/files/8g61fXWLLze7O4ux7mec" alt=""><figcaption></figcaption></figure>

Similar to the DCA strategy above, this can be used to sell gradually from one token into another as price moves. The difference is that the DCA strategy sells the same amount of tokens at each price tick, while this strategy sells progressively more tokens as the price moves in the LP’s favor.

✔ **Advantages:**

Lets users execute a buy-sell strategy without a middle-man

Users can make a swap and collect fees for it, instead of paying them<br>

✖ **Drawbacks:**

User could be swapped back if they don’t remove liquidity before price changes

User will swap more slowly than in DCA distribution

🤔 **Considerations:**

Token projects can use a distribution like this as a launch ramp to guide the price of their token to a desired point


# Incentives

In this section you will find information about Maverick's incentive mechanisms.


# Understanding Boosted Positions

This page explains the basic concept of Boosted Positions.

{% hint style="warning" %}
In Maverick V2, Boosted Positions can now have multiple reward contracts. Read the [section below](#changes-to-boosted-positions-in-v2) to learn more.
{% endhint %}

When a user deposits liquidity into a Maverick pool, they select from several options to open a specific [position ](https://docs.mav.xyz/guides/incentives/pages/pXnNNLl5jAWzoyX6yAvN#pools-vs.-positions)in that pool. Each position is differentiated by a number of key variables: token pair, fee tier, bin width, liquidity mode, and liquidity distribution. For example, one position might consist of a single Mode Right bin of USDC in the USDC/USDT 1% fee 1% width pool, while another could consist of twenty-one Mode Static bins including both USDC and USDT in the same pool.

Positions offer users a high degree of control and flexibility when it comes to providing liquidity. As Boosted Positions, they also offer a similar degree of precise control when it comes to directing liquidity incentives.

Instead of adding liquidity and creating a regular position, a user can create a Boosted Position (always denoted with a lightning bolt in the UI). A Boosted Position works exactly like any other position, with two important differences:

1. other users can add liquidity to a Boosted Position, effectively buying a share in that position
2. a Boosted Position can be incentivized with additional token rewards, which are shared among LPs who add liquidity to that Boosted Position

That is to say, users can add more tokens to the Maverick smart contract which will be distributed to LPs who own liquidity in a particular Boosted Position. These incentives function like bribes to other users to add more liquidity to that Boosted Position.

With Maverick’s Boosted Positions, users can thus use incentive rewards to attract liquidity in very precise ways.

For example, a new token project looking to bootstrap liquidity for their token (let’s call it XYZ) doesn’t need LPs to bring more XYZ to Maverick–their treasure already has plenty of it. What they need from users is a quote asset (e.g., ETH) that can be swapped against their XYZ. So they could create a Boosted Position consisting only of ETH in a XYZ/ETH pool and then add incentives to the Boosted Position. This would encourage new LPs to add only ETH to the pool, effectively allowing project XYZ to rent only the liquidity they need for their pool.

Boosted Positions are listed on their own page in the UI, under Add Liquidity. For more information on how to create and incentivize Boosted Positions, please see the directions elsewhere in this section.

## Changes to Boosted Positions in V2

When an LP provides liquidity to a Boosted Position, they receive ERC-20 LP tokens representing their share of the total liquidity in the Boosted Position. To qualify for incentives from the Boosted Position, they must stake these LP tokens into the Boosted Position's reward contract. Incentives are sent to that reward contract, and then distributed to stakers in the contract pro rata.

In Maverick V1, each Boosted Position had a single reward contract. In Maverick V2, it is possible for a Boosted Position to have multiple reward contracts. This enables users to create an alternate reward stream for the same liquidity configuration without having to duplicate the Boosted Position itself.

<figure><img src="/files/KZ0Di8LfZLBh0yQBTMyi" alt=""><figcaption><p>Boosted Position list showing a GRAI-USDC Boosted Position with two reward contracts.</p></figcaption></figure>

In general, it is most likely that a Boosted Position will only have one reward contract. In the event that a second reward contract is deployed, it will appear in the UI as a separate Boosted Position with "-R#" appended to its number, where # is the number of the new reward contract. In the screenshot above, a second reward contract has been deployed for GRAI-USDC #3, and so a second Boosted Position appears as GRAI-USDC #3-R2. None of the other Boosted Positions in this list currently have a second reward contract.

LP tokens can only be staked in one reward contract at a time. If a Boosted Position has more than one reward contract, an LP will have to choose between them. If an LP wants to change reward contract (e.g., if they decide the rewards from another reward contract are more attractive), they will have to unstake their LP tokens from one reward contract and stake them in the other contract.&#x20;


# Understanding Incentives

This page gives an overview of the Maverick incentives and rewards system.

With Boosted Positions, incentives can come from several sources and are distributed according to a variety of factors.

An LP who adds liquidity to a Boosted Position can earn rewards from the following sources:

* Trading fees
* Raw LP incentives
* MAV emissions

Let's look at each of these sources in turn.

## Trading fees

As with any other position in Maverick AMM, an LP in a Boosted Position earns a pro rata share of the trading fees generated by their liquidity. These fees are auto-compounded into the LP's share of the Boosted Position, and do not need to be claimed. If an LP removes their liquidity from the Boosted Position, the amount redeemed will include any fees generated by that liquidity.

## Raw LP incentives

In addition to trading fees, LPs in a Boosted Position may receive incentives that have been added to that Boosted Position (these added incentives are what we mean by “boosted”).

Any user can add incentives in the form of ERC-20 tokens to a Boosted Position. These incentives are split pro rata between LPs in a Boosted Position, and can be used to incentivize more users to add liquidity to a particular Boosted Position.

Incentives are added and distributed over a user-defined period. They can be added at any time (for raw incentives, Maverick does not observe a universal epoch) and are automatically disbursed to LPs over the defined time period.

When adding incentives, a user selects how much of a particular token (defined as `balance`) to add and chooses a distribution period between three and thirty days. Based on the period chosen, the smart contract computes a `reward rate` that will distribute the `balance` evenly throughout the period. The `reward rate` is denominated in seconds, meaning that a proportional amount of the `balance` will be distributed every second to LPs in the Boosted Position.

If another user adds more incentives to the same Boosted Position, the contract checks their contribution against the remaining `balance` of incentives:

* If the new contribution is higher, this second user can define a new distribution period and the `reward rate` will be recalculated to distribute all incentives (both the new incentives and the remaining old incentives) according to the new distribution period.
* If the new contribution is lower, the new incentives will be added to the existing distribution period at the same `reward rate` and the distribution period will be extended proportionately.

> **For example**, imagine Alice adds 700 USDC as incentives to a Boosted Position. She chooses a distribution period of seven days, meaning that the `reward rate` will essentially be 100 USDC a day (distributed equally between LPs every second).
>
> Three days pass, and 300 USDC has been distributed to LPs. The remaining `balance` of incentives is 400 USDC and there are four more days of the distribution period left.
>
> Bob decides he wants to add more incentives to the same Boosted Position. If he adds less than 400 USDC, his contribution will simply be added to the existing `balance` and distributed according to the `reward rate` chosen by Alice. So if he were to add 200 USDC, the new balance would be 600 USDC, the `reward rate` would remain 100 USDC a day, and the distribution period would be extended by two days. There would now be six days left in the distribution period.
>
> If instead he chooses to add more than 400 USDC, he will be able to redefine the distribution period for these incentives and Alice's remaining `balance` will be added to his contribution and reapportioned across the period he chooses. So if Bob adds 1000 USDC, he can change the distribution period to seven days. Alice's remaining 400 USDC will be added to his contribution, and the total `balance` of 1400 USDC will be distributed over the new period (essentially at a `reward rate` of 200 USDC a day).

An LP can claim the rewards they have accrued at any time (e.g., they can claim before a distribution period has finished or after it has finished).

For detailed instructions on how to add incentives to a Boosted Position, please see [the guide](/guides/incentives/how-to-add-incentives) elsewhere in this section.

## MAV Emissions

LPs in a Boosted Position which is part of the [Maverick veFlywheel](/guides/veflywheel) may earn additional rewards in the form of MAV emissions. MAV emissions essentially work like matches to raw MAV incentives sent to a Boosted Position; i.e., when someone sends MAV as a raw incentive to a participating Boosted Position, the Maverick matching contract adds more MAV on top. To learn more about how the veFlywheel works, including the cadence of epochs, please see [Understanding the veFlywheel](/guides/veflywheel/veflywheel-basics).

So an LP in a Boosted Position which is part of the Maverick veFlywheel can ultimately earn rewards from up to three sources:

* Trading fees paid by swappers for using the LP's liquidity
* Raw MAV incentives sent to the Boosted Position
* MAV emissions added as a match to the raw MAV incentives

The combination of these three reward streams offers a lot of earning opportunites for LPs, and makes Boosted Positions a powerful tool for bootstrapping liquidity.

### Boosts to MAV emissions

LPs in a Boosted Position who receive matching MAV emissions among their rewards can receive a boost to those emissions through two mechanisms:

* Holding veMAV
* Staking MAV emissions for veMAV

#### Holding veMAV

If the LP has a veMAV balance associated with the wallet they used to provide liquidity to the Boosted Position, any MAV emissions received as rewards from Boosted Positions participating in the veFlywheel will be boosted. The boost to emissions scales in proportion to the wallet's veMAV balance, so an LP interested in maximizing their boost will want to have as large a veMAV balance as possible.

The boost to a veMAV holder’s emissions is calculated using a combination of their share of the total veMAV supply and their share in the Boosted Position. Basically, to receive the maximum possible boost an LP needs a percentage share of the total veMAV supply equal to their percentage share in the Boosted Position. So an LP with a 50% share of the Boosted Position would need 50% of the total veMAV supply to achieve the maximum boost.

The maximum possible boost to MAV emissions for holding veMAV is 1.33x. E.g., if an LP was entitled to 1,000 MAV emissions, and they owned 50% of the liquidity in the Boosted Position and 50% of the total veMAV supply, they would receive a boost of 333 MAV to their emissions.

The LP will still receive this boost even if they have delegated the voting power of their veMAV.

#### Staking MAV emissions for veMAV

When an LP claims the MAV emissions from a Boosted Position participating in the veFlywheel, the UI will offer them the option to stake the MAV into the Maverick staking contract and receive veMAV in return. LPs who choose the option to stake will receive a boost to the MAV that is being staked. This means that when the staking period ends, they will ultimately collect more MAV than if they had taken the MAV rewards without staking.

The boost an LP receives from staking is as high as 5x their MAV emissions. From the UI, the LP has four options to choose from when staking; the boost factor for each is as follows:

* 4 years = 5x boost
* 3 years = 4x boost
* 2 years = 3x boost
* 1 year = 2x boost

For more information on what staking MAV means, see [veMAV & MAV Staking](/mav-token/vemav-and-mav-staking).


# How to Join a Boosted Position

This page will guide you through the process of joining a Boosted Position.

Users can find Boosted Positions on the **Boosted Positions** tab of the **Add Liquidity** page, which is accessed from  the top menu.

<figure><img src="/files/A5u1GED9E2t92VjbpbNg" alt=""><figcaption><p>Find Boosted Positions under Add Liquidity in the top menu.</p></figcaption></figure>

It's important to remember that Boosted Positions are essentially just regular positions with the ability to receive incentives. As such, they behave exactly like a non-boosted position, and the flows for adding and removing liquidity to/from a Boosted Position are almost identical.

The only other big difference is that other users are able to add liquidity to a Boosted Position and share in the incentives it accrues. For more information, see [Understanding Boosted Positions](/guides/incentives/understanding-boosted-positions).

## Join an Existing Boosted Position

<figure><img src="/files/gCQT6oMnE0bnt6hEIzPp" alt=""><figcaption><p>Boosted Positions can be filtered by chain, token, and incentives.</p></figcaption></figure>

The Boosted Positions tab will present a list of all Boosted Positions currently active in Maverick V2, together with their Chain, TVL, and current incentives. By default, the list includes Boosted Positions across all chains; this can be changed to filter by chain. Use the toggle switch above and to the right of the list to filter between Boosted Positions that have incentives and all Boosted Positions.

Incentives are added and distributed over user-defined timeframes, and are earned by members of Boosted Positions based on their pro-rata share in that position over time. For more information, see [Understanding Incentives](/guides/incentives/understanding-incentives).

Clicking on a Boosted Position in this list will take you to the add liquidity flow for that Boosted Position. This works like a simplified version of [the regular add liquidity flow](/guides/liquidity-providers/how-to-add-liquidity), since the pool and position parameters are pre-selected for you. **When joining a Boosted Position, you do not select a fee tier, width, Mode or distribution: these are pre-selected by the user who created the Boosted Position.**

<figure><img src="/files/wNY4BZfZettoff8NdXNl" alt=""><figcaption><p>The Add LIquidity page for a Boosted Position.</p></figcaption></figure>

The page for each Boosted Position will let you see its fee, width, and mode; current TVL; and the LP Rewards (i.e., incentives) currently directed to it.

To join a Boosted Position, you simply have to select how much of each asset you wish to add to it. The assets will have to be added in a ratio dictated by the parameters of the Boosted Position and the current price in its pool. Since you are essentially taking a pro rata share of the Boosted Position, you need to add assets according to this ratio. You can type a number into either token input field and the UI will automatically calculate the correct ratio of the other asset.

{% hint style="info" %}
By default, the dApp is set to auto-stake when you add liquidity. When you add liquidity to a Boosted Position, you receive LP tokens representing your share in it. In order to earn incentives, these LP tokens need to be staked into the Boosted Position's reward contract.

If you have another use for Boosted Position LP tokens (e.g., an external gauge), you can turn off auto-stake and your LP tokens will not be staked for you when you add liquidity. You can always stake or un-stake tokens later from the Portfolio page.
{% endhint %}

Once you are satisfied with the amounts, click **Add Liquidity**. This will open the Confirm modal.

<figure><img src="/files/rpA5wFbB0RTCtDXWXzHJ" alt=""><figcaption><p>The Confirm modal.</p></figcaption></figure>

{% hint style="info" %}
Please note, the first time you add tokens to a Boosted Position, you will be asked to Approve that particular token. UI buttons like Swap/Deposit will show as **Approve \[Token]** until that token has been approved. Approving a token requires you to confirm the choice in a your software wallet. You may also need to set an appropriate spending allowance. Read more [here](/getting-started/approving-tokens).
{% endhint %}

The Confirm modal will walk you through Verifying and Approving any tokens that need it. You can then click **Confirm Amount**, which will send a transaction to your wallet. Confirm the transaction in your wallet and wait for a transaction confirmation. Once you receive this, you will have successfully joined the Boosted Position and should be able to find it under the **Portfolio** page.


# How to Create a Boosted Position

This page will explain how to create a new Boosted Position on Maverick.

{% hint style="info" %}
The flow for creating Boosted Positions in Maverick V2 is different from that in Maverick V1. Even if you are familiar with V1 Boosted Positions, it is recommended to read this page in its entirety to understand the differences between V1 and V2.
{% endhint %}

<figure><img src="/files/89NsBDcJguZuBFH8ElbN" alt=""><figcaption><p>Create a new Boosted Position by clicking the Create A Boosted Position button on the Add Incentives tab of the Manage Incentives page.</p></figcaption></figure>

Any user can create a new Boosted Position on Maverick by clicking the **Create A Boosted Position** button on the Add Incentives tab of the Manage Incentives page. The Manage Incentives page can be accessed from the **More Tools** menu in the UI's top menu.

In Maverick V2, Boosted Positions are created by cloning existing liquidity positions in the user's portfolio. This change was made to solve the pain-point in V1 where a user would potentially have to create a pool and then a separate liquidity position to make a Boosted Position, thus saving them gas.

When you click the **Create A Boosted Position** button, you will be taken to a page showing the existing positions in your Portfolio that are eligible for cloning. If you do not see any positions there, you will need to create them by either [adding liquidity to an existing pool](/guides/liquidity-providers/how-to-add-liquidity) or [deploying a new pool](/guides/liquidity-providers/how-to-deploy-a-new-pool).

<figure><img src="/files/JgBldU1AOnUhNoNAXdkG" alt=""><figcaption><p>The Create a Boosted Position flow will show positions in the user's Portfolio that are eligible for cloning.</p></figcaption></figure>

Select the position in your Portfolio that you wish to clone and click **Clone to Boosted Position**. This will take you to the second step of the flow.

<figure><img src="/files/GDZhC4OCfy9EHsUm27kC" alt=""><figcaption><p>Seeding the new Boosted Position with liquidity.</p></figcaption></figure>

In the next step, you will be asked to seed the new Boosted Position with some liquidity. Since most users will be creating a Boosted Position with the aim of attracting outside liquidity, it isn't necessary to use more than a token amount at this stage. Use the numeric fields to choose how much liquidity to add. The token amounts are dictated by the current ratio of the tokens in the position, which in turn is dictated by the configuration of the position and the price of its pool. Click **Next** to proceed to the next step.

<figure><img src="/files/wW2r0TWilsL3IACUiTX0" alt=""><figcaption><p>Choosing Reward Tokens for this Boosted Positions reward contract.</p></figcaption></figure>

As explained in [Understanding Boosted Positions](/guides/incentives/understanding-boosted-positions), each Boosted Position has at least one reward contract, which receives and distributes incentives to LPs in that Boosted Position. An LP will stake their Boosted Position LP tokens into the reward contract to earn their rewards. In this step of the flow, you must configure the initial reward contract for your Boosted Position.

A Boosted Position's reward contract can include up to five reward tokens. **If a token is not included in the reward contract, it cannot be used to incentivize the Boosted Position.** You should therefore select all the tokens you might conceivably use as incentives at this stage. Otherwise, you might have to deploy a new reward contract at a later date, which risks fragmenting liquidity as LPs can only be staked in one reward contract at a time ([learn more](/guides/incentives/understanding-boosted-positions#changes-to-boosted-positions-in-v2)).

To choose your first reward token, use the drop-down menu under **Reward Token 1**. To add another reward token, click the **Add Reward Token button** and use the drop-down menu to select it. Repeat this process to add more tokens.

<figure><img src="/files/Y9LCvM5J6IZvCXVvgfcr" alt=""><figcaption><p>The user has selected MAV, USDC, and DAI as reward tokens for this reward contract, and included ve for the MAV token. This means that MAV incentives sent to this Boosted Position will be eligible for matching rewards from the veFactory.</p></figcaption></figure>

For each reward token, you can choose whether or not to include its ve Token. Any token can have a ve Token if it is deployed through the Maverick veFactory, but not every token will have a ve Token. If you opt to include the ve Token, that means this token's incentives will be included in its respective veFlywheel and be eligible for matching and other ve dynamics (provided that veFlywheel exists now or in the future). You can also effectively opt-out of a given veFlywheel by not including the ve Token. For more information, see [Understanding the veFlywheel](/guides/veflywheel/veflywheel-basics).

{% hint style="warning" %}
If you want your Boosted Position to participate in the Maverick veFlywheel, you **must** select MAV as one of the reward tokens and you **must** select **Include ve Token** for MAV. Without these options selected, your Boosted Position will not be eligible for MAV incentives and/or will be ineligible for matching emissions from the veFlywheel.
{% endhint %}

Once you have finished selecting reward tokens, click **Confirm Tokens** to proceed. This will open the confirmation modal, where you will be walked through verifying and approving your chosen tokens (if necessary), adding your seed liquidity, and deploying your reward contract.

If for any reason you do not deploy the reward contract at this stage, you can deploy it later from the [Add Incentives](/guides/incentives/how-to-add-incentives) page. Without a reward contract, your Boosted Position will not be able to receive or distribute incentives.

{% hint style="info" %}
Please note, the first time you add tokens to a Boosted Position, you will be asked to Approve that particular token. Boosted Positions use a different contract, so you will need to approve tokens even if you have already Approved them elsewhere in the dApp. Approving a token requires you to confirm the choice in a your software wallet. You may also need to set an appropriate spending allowance. Read more [here](/getting-started/approving-tokens).
{% endhint %}

**You do not add incentives to a Boosted Position when you first create it.** This is done in a separate step using the Incentivize page. For more detailed instructions, see [How to Add Incentives](/guides/incentives/how-to-add-incentives).


# How to Manage a Boosted Position

This page explains how to manage a Boosted Position, including claiming rewards and removing your liquidity.

<figure><img src="/files/4hbeXFR0CLiztxz0a673" alt=""><figcaption><p>The Portfolio page. This user has two regular positions on the left and two Boosted Positions on the right. Note the lightning bolts on the Boosted Position cards.</p></figcaption></figure>

Once you have added liquidity to a Boosted Position, you will find a new card on the Portfolio page representing that liquidity. Boosted Positions are easily distinguished from regular liquidity positions by the lightning bolt icon that appears next to them in the UI.

<figure><img src="/files/Ycx05DZdubPDEqVubSia" alt=""><figcaption><p>A Boosted Position card has an extra row for Rewards and a button to claim those rewards.</p></figcaption></figure>

The card for a Boosted Position looks similar to the card for a regular position, but has an additional information row listing any rewards accrued to that Boosted Position and a button to claim those rewards. **Rewards only accrue to a Boosted Position if someone has added incentives to that Boosted Position and those incentives are actively being distributed.**

## Claiming Rewards

You can claim the rewards earned by a Boosted Position directly from this page by clicking the **Claim Rewards** button. The UI will ask you to confirm the claim, and then send an approval request to your wallet. Confirm the request there, and any rewards will be sent to your wallet.

{% hint style="info" %}
Because you can claim rewards at any time, you should always balance the gas fees associated with claiming rewards against the amount available to claim. Rewards will not expire, so you can wait until the balance between available rewards and gas fees is in your favor.
{% endhint %}

## Staked vs. Unstaked Boosted Positions

As explained in the guides to joining and creating Boosted Positions, when you add liquidity to a Boosted Position you receive LP tokens representing your proportional share of it. These form the basis of your claim on the incentives directed to that Boosted Position. In order to earn and claim incentives, these LP tokens need to be staked in the Maverick rewards contract. Since most users will join Boosted Positions to earn Maverick incentives, these LP tokens are set to auto-stake when you add liquidity, but users can choose not to stake LP tokens if they have another use for them (e.g., on an external gauge).

<figure><img src="/files/5vnqAGkIohz9vpKBHbkS" alt=""><figcaption><p>Two Boosted Position cards on the Portfolio page. The Boosted Position on the left is staked. The Boosted Position on the right is unstaked.</p></figcaption></figure>

Unstaked positions appear slightly differently on the Portfolio page. They have an "Unstaked" label, and do not list rewards or have a Claim Rewards button. You can unstake or stake Boosted Positions at any time using the **Manage** button on a Boosted Position's card.

Because the options for managing staked and unstaked Boosted Positions are slightly different, we will deal with them separately below.

## Managing a Staked Boosted Position

Most users on Maverick will likely have a staked Boosted Position, since LP tokens are set to auto-stake when adding liquidity to a Boosted Position. When you click **Manage** on a staked Boosted Position, you will be taken to the Manage Staked Liquidity page.

<figure><img src="/files/60PJRbHQdgR8pcA9b3ip" alt=""><figcaption><p>The Manage Staked Liquidity page.</p></figcaption></figure>

There are four buttons on this page:

* **Claim Rewards** - works like the **Claim Rewards** button on the Portfolio (see above)
* **Add Liquidity and Stake** - used to add more staked liquidity to the same Boosted Position; clicking this will take you to the same page used to [add liquidity to the Boosted Position](/guides/incentives/how-to-join-a-boosted-position#join-an-existing-boosted-position)
* **Unstake and Remove Liquidity** - click this button to unstake your LP tokens and redeem them for your liquidity and fees in the Boosted Position
* **Unstake LP tokens** - click this button to unstake your LP tokens but leave your liquidity in the Boosted Position; unstaked Boosted Positions will continue to earn trading fees but will not earn incentives

### Unstake and Remove Liquidity

If you wish to remove your liquidity from a Boosted Position, you will first need to unstake LP tokens. Clicking **Unstake and Remove Liquidity** will activate a flow that takes you through the required steps in order.

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

You will first be asked to choose how much of your LP tokens you wish to unstake and remove. You can use the slider to select a percentage, up to 100 (which will unstake and remove everything). As you move the slider, you will be shown a preview of how many LP tokens you will be unstaking and how much of the liquidity they represent you will be removing.

Choose how much LP tokens to unstake and remove and click the **Confirm** button. This will open a modal that will walk you through the steps required to complete the operation.

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

First you will need to unstake the LP tokens. Click the **Unstake** button to send a request to your wallet. Approve the transaction there, and your LP tokens will be unstaked. Next, the dApp will determine if you need to approve the LP tokens for removal.

{% hint style="info" %}
Please note, the first time you remove LP tokens from a Boosted Position, you will be asked to Approve those particular LP tokens. Each Boosted Position has a different LP token. Approving a token requires you to confirm the choice in a your software wallet. You may also need to set an appropriate spending allowance. Read more [here](/getting-started/approving-tokens).
{% endhint %}

If required, click **Approve** and confirm the approval in your wallet. Once the LP tokens are approved, you are ready to remove them. Click **Confirm** and confirm the transaction in your wallet. When the transaction is complete, the selected LP tokens will be burned and the proportional amount of liquidity sent to your wallet. If you removed all of your liquidity from this Boosted Position, the relevant card should disappear from the Portfolio page.

If there were any rewards left on this Boosted Position, you will now be asked to claim them. If you wish to claim the rewards, click the **Claim Rewards** button and confirm the transaction in your wallet.

{% hint style="warning" %}
**If you do not claim any remaining rewards at this stage, you will not be able to claim them in the future.** Make sure to claim any rewards you wish to keep before leaving this page.
{% endhint %}

### Unstake LP Tokens

Click the **Unstake LP Tokens** button to unstake your LP tokens for use outside Maverick while leaving your liquidity in the Boosted Position. If your LP tokens are unstaked, your liquidity will continue to earn trading fees but will not earn incentives. You can always re-stake your LP tokens later if you want.

<figure><img src="/files/8Ia9Fh53NSE6VFIfjcvi" alt=""><figcaption></figcaption></figure>

When you click Unstake LP Tokens, the UI will ask you to choose how much of them you want to unstake. You can use the slider to choose a percentage up to 100 (which will unstake all of your LP tokens for this Boosted Position).

Choose how much of your LP tokens to unstake and click **Confirm**. Confirm the transaction in your wallet. When the transaction is complete, the LP tokens will be sent to your wallet and you will find a new card in Portfolio representing your unstaked liquidity in this Boosted Position.

## Managing an Unstaked Boosted Position

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

The options for managing an unstaked Boosted Position are simpler, since the LP tokens for this position are already unstaked. On this page you will find three buttons:

* **Add Liquidity** - used to add more staked liquidity to the same Boosted Position; clicking this will take you to the same page used to [add liquidity to the Boosted Position](/guides/incentives/how-to-join-a-boosted-position#join-an-existing-boosted-position)
* **Stake LP Tokens** - click this to stake LP tokens into the Maverick rewards contract and earn incentives
* **Remove Liquidity** - click this to remove underlying liquidity from the Boosted Position completely

### Stake LP Tokens

This process works much like [Unstaking LP Tokens](#unstake-lp-tokens) described above, only with the opposite result: LP tokens are staked into the Maverick rewards contract to earn incentives. When you click this button, the UI will ask you to choose how much of your LP tokens you want to stake. You can use the slider to choose a percentage up to 100 (which will stake all of your LP tokens).

Choose how much of your LP tokens to stake and click the **Confirm** button.

{% hint style="info" %}
Please note, the first time you stake LP tokens, you will be asked to Approve those particular LP tokens. Each Boosted Position has a different LP token. Approving a token requires you to confirm the choice in a your software wallet. You may also need to set an appropriate spending allowance. Read more [here](/getting-started/approving-tokens).
{% endhint %}

Approve the tokens if necessary, then click the **Confirm** button in the modal. Approve the transaction in your wallet. When the transaction is complete, your tokens will be staked in the Maverick rewards contract. You should see a new card for a staked Boosted Position in the Portfolio page (or if you already had one for this Boosted Position, the balances on that card will increase).

### Remove Liquidity

This process works much like the [Unstake and Remove Liquidity](#unstaking-and-remove-liquidity) flow described above, but with fewer steps since the LP tokens are already unstaked and there are no rewards to be claimed.

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

When you click **Remove Liquidity**, the UI will ask you to choose how much of your LP tokens you want to remove. You can use the slider to choose a percentage up to 100 (which will remove all of your LP tokens). As you move the slider, you will see a preview of how much of the underlying liquidity from this Boosted Position will be redeemed in this transaction.

Choose how much liquidity to remove and then click the **Confirm** button.

{% hint style="info" %}
Please note, the first time you remove LP tokens, you will be asked to Approve those particular LP tokens. Each Boosted Position has a different LP token. Approving a token requires you to confirm the choice in a your software wallet. You may also need to set an appropriate spending allowance. Read more [here](/getting-started/approving-tokens).
{% endhint %}

Approve the tokens if necessary, then click the **Confirm** button in the modal. Approve the transaction in your wallet. When the transaction is complete, the selected LP tokens will be burned and the proportional amount of liquidity sent to your wallet. If you removed all of your liquidity from this Boosted Position, the relevant card should have disappeared from the Portfolio page.


# How to Add Incentives

This page explains how to add incentives to a Boosted Position.

{% hint style="danger" %}
When you add incentives, you are giving tokens away as rewards to LPs. This is not the same as adding liquidity. You will not receive any LP tokens or other compensation for adding incentives. You are giving away rewards to LPs who stake this boosted position. If you do not understand this feature, you are advised not to use it.
{% endhint %}

Any user can add incentives to any Boosted Position on Maverick. **You do not have to be the creator of a Boosted Position in order to add incentives to it.** Incentives are added from the Manage Incentives page, which can be found in the More Tools menu in the top menu.

<figure><img src="/files/89NsBDcJguZuBFH8ElbN" alt=""><figcaption><p>Add incentives by choosing Manage Incentives from the More Tools menu.</p></figcaption></figure>

The **Add Incentives** tab on this page will present you with a list of every Boosted Position on Maverick. Boosted Positions are listed by token pair and accompanied by a unique identifying number to help users differentiate between them. You can also see the fee and width of the pool each Boosted Position is in, together with the TVL for the Position itself (not the pool as a whole).

{% hint style="info" %}
It is only possible to add incentives to a Boosted Position that already exists. If you need to create a Boosted Position first, please see [our guide](/guides/incentives/how-to-create-a-boosted-position).
{% endhint %}

Click on a Boosted Position in the list to add incentives to it. This will take you to the Incentivize Boosted Position page.

<figure><img src="/files/qiqWB9CxJYqKbqBFxicN" alt=""><figcaption><p>The Incentivize Boosted Position page.</p></figcaption></figure>

This page will present more detailed information for the Boosted Position you have selected, including any incentives that have already been added to it, the reward contract, and the eligible reward tokens.

<figure><img src="/files/pLFmndceudQf9QcQJyqP" alt="" width="375"><figcaption><p>Close-up of the Incentivize Boosted Position page. This user has chosen to incentivize the Boosted Position with 100 MAV to be distributed over 7 days.</p></figcaption></figure>

In the screenshot above, we can see the reward contract for this Boosted Position has four available reward tokens: MAV, weETH, WETH, and USDC. This means that these are the only tokens that can be used to incentivize it. We can also see that the MAV token has the "ve" symbol next to it, meaning MAV rewards sent to this Boosted Position are eligible for matching from the veFlywheel.

As explained in [Understanding Boosted Positions](/guides/incentives/understanding-boosted-positions), V2 Boosted Positions can have more than one reward contract. If the token you want to use is not available in the currently selected reward contract, you can use the **Edit** button to select a different one or deploy an entirely new one. Bear in mind that LPs can only be staked in one reward contract at a time, so multiple reward contracts risk fragmenting liquidity.

To add new incentives, use the drop-down menu to select from the available incentive tokens then type the amount of tokens you wish to add into the numeric field to the right. You will need to have the appropriate amount of these tokens in your wallet to proceed.

Use the slider to set the duration for your incentives. This is the period over which your incentives will be distributed to LPs in this boosted position. Incentives are spread evenly across the chosen duration, so if a user chose to add 7 ETH for a duration of 7 days, those incentives would be distributed at a rate of 1 ETH every day.

If you are happy with the amount and duration of your incentives, click the **Incentivize** button to proceed.

<figure><img src="/files/A4UGzCusbShF5kjqlCtu" alt=""><figcaption><p>The UI will ask you to confirm that you understand incentivizing means giving away rewards.</p></figcaption></figure>

You will be asked to confirm that you understand you are giving away rewards by choosing this action. If you understand and agree to that, click the radio button and then click **Continue**. **Again, if you do not understand what incentives are or why you might want to offer them, you are advised not to use this feature.**

{% hint style="info" %}
Please note, the first time you add a token as an incentive, you will be asked to Approve that particular token. Incentives use a different contract, so you will need to approve tokens even if you have already Approved them elsewhere in the dApp. Approving a token requires you to confirm the choice in a your software wallet. You may also need to set an appropriate spending allowance. Read more [here](/getting-started/approving-tokens).
{% endhint %}

If necessary, Verify and/or Approve the token you have chosen as incentives, then **Confirm** the transaction in the modal. This will send a request to your wallet. Approve the transaction there, and the tokens will be sent from your wallet to the rewards contract. Your incentives will be added to this Boosted Position and begin distribution immediately.


# veFlywheel

This section collects articles intended to help users understand and use Maverick's veFlywheel.


# veFlywheel Basics

This page offers a basic overview of how MAV emissions are distributed through Maverick V2's veFlywheel. For a more detailed and technical explanation of the mechanisms involved, please see the [V2 Whitepaper](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1irpxOULWWoYXAKrwP4H%2Fuploads%2FHRLAmxSGhZGOjFSb6RP7%2FMaverick_v2.pdf?alt=media\&token=533cb8b0-4384-4d80-af0e-0832a6601aa3).

### Basic Mechanism

The veFlywheel is best understood as a matching mechanism. It matches [MAV incentives](/guides/incentives/understanding-incentives) sent to V2 Boosted Positions by emitting more MAV tokens to those Boosted Positions. There are two ways in which MAV incentives are matched by the veFlywheel:

* Direct match
* Vote-match

{% hint style="info" %}
Only MAV incentives will trigger the veFlywheel and receive matches. Incentives added to Boosted Positions in the form of other tokens will not trigger matches or contribute to match calculations. This facilitates the matching of emissions on-chain and means the veFlywheel does not have to rely on external oracles to calculate the value of incentives.
{% endhint %}

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

At the start of each epoch, a budget of MAV tokens is added to the veMAV matching contract. This budget is split between direct match and vote-match, effectively establishing two budgets for each epoch: the direct match budget and the vote-match budget. These budgets form the basis of incentive matching for that epoch.

#### Direct match

Direct match is a straightforward matching of any MAV incentives received by a Boosted Position. If the direct match budget allows, the matching contract will make a 1:1 match of MAV incentives; this means that for every 1 MAV sent as incentives to the Boosted Position, the matching contract will send a further 1 MAV to that Boosted Position. If there is not sufficient funds in the direct match budget to afford a 1:1 match for every Boosted Position in a given epoch, the matching contract will instead distribute the direct match budget pro rata of MAV incentives received by each Boosted Position.

Direct match does not require veMAV voting. Simply adding MAV incentives to a Boosted Position that includes MAV and veMAV in its reward contract is sufficient to trigger a direct match.

#### Vote-match

Vote-match is governed by veMAV voting. In each epoch, veMAV holders can vote for Boosted Positions to receive a further match to their incentives through vote-matching. At the end of an epoch's voting period, the matching contract counts the votes received by each Boosted Position and uses it to calculate the vote-match each Boosted Position should receive. A Boosted Position with no veMAV votes would receive no vote-match.

The vote-match received by a Boosted Position is calculated as *total vote-match budget \* Boosted Position's weight/total weights*, where *weight = Boosted Position's incentives/all incentives \* Boosted Position's vote/all votes*. This calculation ensures that the full vote-match budget will be used each epoch.

Like direct match, vote-match is only triggered by MAV incentives being sent to a Boosted Position. Without MAV incentives, there will be no vote-matching. A Boosted Position with 80% of the veMAV vote in an epoch that received no MAV incentives would not receive a vote-match.

### Cadence of epochs

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

Like most ve-systems, the Maverick veFlywheel operates on a cycle of epochs. A new epoch starts every 14 days. Usually, the entire life-cycle of an epoch will be 30 days.

A Maverick epoch breaks down as follows:

* **Day 1**: Start of incentives period (14 days). MAV incentives are sent to Maverick V2 Boosted Positions. Any incentives sent to Boosted Positions during this period will count towards direct match and vote-match.
* **Day 8**: Start of voting period (7 days). At the start of this period, a snapshot of veMAV balances is taken. This fixes the total available veMAV for this voting period. Any veMAV created by staking MAV after this snapshot cannot be used in this epoch. During this period, veMAV holders can apportion their votes between Boosted Positions.
* **Day 15:** Start of veto period (2 days). Included as a security mechanism against exploits of the veFlywheel (e.g., a malicious user creating a Boosted Position using non-transferable tokens only they control and using it to attract emissions).
* **Day 17:** Start of emissions period (normally 14 days). At the start of this period, the matching contract uses incentives and votes to calculate direct matches and vote-matches and adds them to the Boosted Positions that had incentive sent to them during the incentives period. The matching contract will attempt to set a reward duration of 14 days, but in some situations the duration may be longer (see [Understanding Incentives](/guides/incentives/understanding-incentives) for more details).

As indicated in the diagram above, a new epoch will begin at the same time as the veto period from the previous epoch begins.


# Guide to veFlywheel Emissions

This page is intended to help both LPs and projects understand their rewards and emissions received through the veFlywheel.

## Terminology <a href="#docs-internal-guid-dccc4135-7fff-8526-edd4-6db5d4e4efbd" id="docs-internal-guid-dccc4135-7fff-8526-edd4-6db5d4e4efbd"></a>

#### Raw LP Incentives:

* Any user can add raw (unboosted) incentives in the form of ERC-20 tokens to a Boosted Position.
* These incentives are distributed pro rata among Liquidity Providers (LPs) in that Boosted Position.
* The purpose is to encourage more users to add liquidity to the specific Boosted Position.

#### MAV Emissions:

* These are rewards given in the form of MAV tokens to match the Raw LP incentives added to a Boosted Position within the same Epoch.&#x20;
* LPs providing liquidity in Boosted Positions are eligible to receive these MAV emissions, which are distributed pro rata.
* At the start of the emissions period in each epoch, MAV emissions are eligible to be distributed simultaneously across all chains. However, someone needs to distribute the emissions from the UI (**Manage Incentives** -> **Match Incentives** -> **Find the right Epoch** -> **Click the ‘Distribute’ Button**)
* MAV emissions fall into two categories: **Direct Match** and **Vote-Match**.

#### MAV Emissions - Direct Match:

* This is the portion of MAV emissions designed to provide up to a straightforward 100% match to the Raw LP incentives.

#### MAV Emissions - Vote-Match:

* This is the portion of MAV emissions designed to provide additional matching above the Direct Match, as directed by veMAV votes during each Epoch.

## Incentives Flowchart

<figure><img src="/files/GvdCeX3QjW9m2dmzu2CD" alt=""><figcaption><p>Flowchart explaining how incentives and emissions flow as rewards to LPs and veMAV holders.</p></figcaption></figure>

## Where Can I Find My Rewards?

### Liquidity Providers

#### Before Adding Liquidity

You can find the projected Annual Percentage Rate (APR) in the UI based on the current pool statistics.&#x20;

On the Boosted Positions page, under the APR column, the grey APR represents the effective cash on cash APR, which includes fees and the MAV tokens eligible to claim today, if the user chooses not to stake their emissions.&#x20;

The APR shown on the purple chip indicates the total APR available with the maximum extra boost to MAV emissions received if the user is willing to stake for 4 years and holds sufficient veMAV.

#### After You Have Added Liquidity to Maverick V2

**LP fees:** LP fees generated from swaps are automatically compounded into LP positions. You can track the balance of your positions manually in the Portfolio or use 3rd party tracking dApps.&#x20;

**LP Rewards:** On the Portfolio page, position cards for Boosted Positions will also show rewards earned from incentives and/or emissions, all of which can be claimed by clicking the **Claim** button.

LPs have two options for receiving MAV emissions:

1. **Withdraw:** Receive X number of MAV emissions immediately.
2. **Stake:** Stake their MAV emissions for a fixed period to receive a boost to X.
   * Receive 5-6.66x of their eligible MAV emissions in 4 years.
   * Receive 4-5.33x of their eligible MAV emissions in 3 years.
   * Receive 3-4x of their eligible MAV emissions in 2 years.
   * Receive 2-2.66x of their eligible MAV emissions in 1 year.

{% hint style="info" %}
The boost to MAV emissions an LP can claim also depends on how much veMAV the LP holds compared to the total veMAV on the chain. You can find more information about the boost from holding veMAV under [Understanding Incentives](/guides/incentives/understanding-incentives#boosts-to-mav-emissions).
{% endhint %}

### veMAV Holders

veMAV holders will be eligible to claim any boosts to MAV emissions that Liquidity Providers did not claim from Boosted Positions reward contracts. These leftover MAV emissions will be distributed as MAV tokens staked for 4 years. The distribution to veMAV holders will occur quarterly. The staked MAV claim feature for veMAV holders will be available on the UI soon.

## How to Calculate the Matching Ratio

Maverick Boosted Positions allow incentivizers to add liquidity incentives to specific ranges of the pool, using various shapes and movement modes. This approach helps bootstrap liquidity and enhances incentivization efficiency.

MAV emissions matched by the veFlywheel provide an extra boost on top of the raw incentives added to Boosted Positions, further increasing liquidity incentives to LPs. Incentivizers wishing to optimize their incentivized liquidity strategy may find it useful to calculate their **Matching Ratio**, which shows how much MAV emissions are matched to their raw LP incentives. &#x20;

### **Step 1: Raw Incentive Credits**&#x20;

Raw incentives in the form of MAV sent to ve-enabled Boosted Positions are automatically eligible for matching from the veFlywheel on a 1:1 basis.

In addition, anyone can apply to have an arbitrary incentive token selected to receive matching MAV emissions from the Maverick veFlywheel. Each epoch, the Maverick Liquidity Committee can set a multiplier for each arbitrary token which establishes the relative value of that token to MAV for the purposes of emissions.&#x20;

**Raw Incentive Credits** **= Number of Raw Incentive Tokens \* Multiplier**

For example, if the Committee selected USDC as an arbitrary matching token with a 5x multiplier, the matching contract would treat each USDC raw incentive as worth 5 MAV tokens. If a Boosted Position then received 10,000 USDC raw incentives during Epoch 1, its Raw Incentive Credits would be 50,000 during Epoch 1.

Raw MAV incentives have an effective multiplier of 1. So if the Boosted Position with 10,000 USDC raw incentives also received 20,000 MAV raw incentives, its total Raw Incentive Credits would by 70,000 (10,000 \* 5 + 20,000 \*1).

{% hint style="warning" %}
Only Boosted Positions that include veMAV on their reward contract **and** have received raw MAV incentives and/or raw incentives in the form of an included arbitrary token in a given epoch will qualify for matching emissions in that epoch. If a Boosted Position does **not** include veMAV on its reward contract and/or does **not** receive raw incentives in MAV or an included arbitrary token, it will **not** receive any matching emissions.
{% endhint %}

If a token has not been selected as an arbitrary token to join the Maverick veFlywheel, Incentivizers must [fill out this form](https://forms.gle/QdT9rhtYWv5R8pP29) within the first 3 days of the Epoch they want to join.&#x20;

If a token has already been selected as an arbitrary token to join Maverick veFlywheel, you can find out your Raw Incentive Multiplier from the Maverick Liquidity Committee.&#x20;

### **Step 2: MAV Emissions Calculation**&#x20;

As explained above, MAV Emissions include both **Direct Match Emissions** and **Vote-Match Emissions**. The Direct Match and Vote-Match Emissions for each eligible Boosted Position in a given epoch can be calculated as follows:

#### Direct Match

* If the Epoch’s Direct Match budget is greater than or equal to the Total Raw Incentives eligible for match, then **Direct Match = 100% \* Boosted Position's Raw Incentive Credits**
* If the Epoch’s Direct Match budget is less than the Total Raw Incentives eligible for match, then **Direct Match = Direct Match Budget \* Boosted Position's Raw Incentive Credits/Total Raw Incentive Credits Across all Boosted Positions**

#### Vote-Match

Vote-Match is calculated as **Vote-Match Emission budget \* Boosted Position's Weight / all Boosted Positions' Weights** where **Weight = Boosted Position's % of Total Raw Incentives \* Boosted Position's % of Total Votes Cast**.

The Vote-Match design ensures 100% of the Vote-Match budget is used every epoch.

You can find how much total veMAV is eligible to vote during a given epoch and how many votes have been cast at: <https://app.mav.xyz/vote>&#x20;

### **Step 3: Calculate Matching Ratio**

The **Matching Ratio** can be calculated as **(Raw Incentives + Total MAV Emissions) / Raw Incentives in Dollar Value**.

Due to the [staking/boosting mechanics](#after-you-have-added-liquidity-to-maverick-v2) of MAV emissions, you can also calculate a **Cash on Cash Matching Ratio** **= (Raw Incentives + Total MAV Emissions that can be withdrawn now) / Raw Incentives in Dollar Value**.

For example, suppose a Boosted Position receives $10,000 in XYZ tokens and the XYZ token is selected as an arbitrary token for matching by the veFlywheel. The Boosted Position then receives a match of $16,000 in MAV tokens. The Matching Ratio is 260%; Cash on Cash Matching Ratio is 132%.


# How to Vote to Direct Emissions

This page explains the mechanics of voting to direct emissions from the Maverick veFlywheel. For an overview of how the veFlywheel works, see [Understanding the veFlywheel](/guides/veflywheel/veflywheel-basics).

{% hint style="warning" %}
Each epoch of the veFlywheel has a voting period, which begins seven days after the start of the epoch. At the start of the voting period a snapshot is taken of all veMAV balances and their delegations. This snapshot determines the voting power of every address for the current epoch. Any MAV staked or veMAV delegated after the snapshot will not be eligible for voting until the following epoch.
{% endhint %}

{% hint style="info" %}
If you staked MAV for veMAV prior to the launch of Maverick V2, it may need to be synced to the V2 contracts to be used in voting. Please see the page on [Syncing V1 veMAV](/mav-token/syncing-v1-vemav) for more information. Like staking and delegating, syncing must be done before the snapshot for the synced veMAV to be eligible to vote in the current epoch.
{% endhint %}

## How to Vote

All voting is accomplished through the Voting page, which can be accessed by choosing **Vote** from the top menu in the dApp.

<figure><img src="/files/T7ZFmqowAISxZlR8KGqi" alt=""><figcaption><p>The Voting page.</p></figcaption></figure>

The info bar on this page gives you information about the current epoch, including your voting power and when the voting period and epoch start and end. In the future, you can use the drop-down menu under Token to switch between veFlywheels. For the rest of this page, we'll assume you're voting in the MAV veFlywheel, but the mechanics would be the same for any other ve tokens enabled by Maverick.

The list below shows all the Boosted Positions included in the Maverick veFlywheel. To be included, these Boosted Positions all have to include MAV and veMAV in their reward contracts. For more information, see [How to Create a Boosted Position](/guides/incentives/how-to-create-a-boosted-position). You can also see relevant stats for each Boosted Position, including TVL, Incentives (i.e., external incentives sent to this Boosted Position), and Total Votes received in this epoch.

Once the voting period begins, if you have voting power on this chain you will be able to apportion your votes between Boosted Positions using the sliders next to each of them.

<figure><img src="/files/vWvj4sM3no8SmiICIFKW" alt=""><figcaption><p>Using the sliders to split My Votes 50/50 between the first two Boosted Positions on the list.</p></figcaption></figure>

{% hint style="info" %}
As explained in [Understanding the veFlywheel](/guides/veflywheel/veflywheel-basics), voting will only direct more matching emissions to Boosted Positions that have been sent external MAV incentives during the epoch. It is recommended to pay close attention to the Incentives column, and only vote on Boosted Positions that show incentives sent there. Any votes apportioned to a Boosted Position with no external incentives will not produce matching emissions, and are effectively wasted.
{% endhint %}

Once you've decided how to apportion your votes, click the **Cast Votes** button and confirm the transaction in your wallet. Each address with an eligible veMAV balance can vote once per epoch.

## What Rewards Do I Get from Voting?

**Voters do not receive direct rewards for voting with their veMAV.** That means that a veMAV holder who sends votes to a Boosted Position does not automatically receive any rewards for performing this action. Voting simply directs more MAV from the vote-matching budget to LPs in Boosted Positions.

The most straightforward way to get rewards from voting is to vote for a Boosted Position in which you are an LP. So long as that Boosted Position has external incentives in this epoch, your votes will direct more vote-matched incentives to the Boosted Position, increasing the emissions received by you and any other LPs in the Boosted Position.

As explained in [Understanding Incentives](/guides/incentives/understanding-incentives), LPs in Boosted Positions can also get a boost from holding veMAV and agreeing to stake MAV emissions to get more veMAV. Between voting for more emissions and boosts to those emissions, an LP should find a lot of utility for veMAV.

If you hold veMAV but are not interested in LPing, you may find opportunities to earn rewards by delegating your voting power to other individuals or protocols. Please follow Maverick on Twitter and join the Discord for any news on such opportunities.


# Advanced Tutorials

This section provides guides to using Maverick for specific use-cases. Nothing in this section should be understood to constitute financial advice.


# Single-Sided Incentives

This tutorial will walk you through how to use Boosted Positions to incentivize one side of a liquidity pair.

## Getting Started

* This guide will explain how to incentivize targeted liquidity on Maverick’s dApp. We will be using the example of single-sided liquidity, i.e., how to incentivize liquidity providers (LPs) to bring a counter-asset to your token’s pool.
* In order to incentivize liquidity in this way, we will be creating a Boosted Position in Maverick’s UI. You can find more information about Boosted Positions [here](/guides/incentives/understanding-boosted-positions).
* Users can only create Boosted Positions in pools that already exist on Maverick. For example, if you want to create a Boosted Position to encourage users to bring ETH to an ETH-XYZ pool, you will need to make sure that the ETH-XYZ pool is already deployed. A guide to deploying a new pool can be found [here](/guides/liquidity-providers/how-to-deploy-a-new-pool).
* For Maverick’s movement Modes to work properly, a pool will need a layer of static liquidity to help with price discovery. If you are deploying a new pool, please begin with a Mode Static distribution that spreads some liquidity across a range around the current price.

We'll break down this activity into three steps:

1. [**Adding Single-Sided Liquidity**](#adding-single-sided-liquidity)  - we'll set up a one-sided distribution of protocol liquidity in a pool
2. [**Creating a Boosted Position**](#creating-a-boosted-position) - we'll then create a Boosted Position to incentivize ETH liquidity to the other side of this pool
3. [**Adding Incentives**](#adding-incentives) - finally, we'll aim some incentives at this Boosted Position to encourage LPs to bring ETH to it

## Adding Single-Sided Liquidity

In this first section, we’ll assume the role of a project bringing their own token to a Maverick pool. We’ll add that token to one side of the pool, and then in the next section we’ll use a Boosted Position to incentivize users to add ETH as a counter-asset. For this example, we’ll work with the ETH-SAND pair, but simply replace SAND with any token and the process will be the same.

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

Navigate to the **Pools** page, under **Add Liquidity** in the top menu.

Use the pool list on this page to find the pool you want to incentivize. You can scroll or use the search bar. Again, if the pool you want has yet to be deployed, please see our [guide to deploying a new pool](https://docs.mav.xyz/guides/liquidity-providers/deploying-a-new-pool).

Click on the pool in the list to go to the Select Pool page.

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

Check that the details for the pool you selected look correct, then click **Next**.

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

On the Select Mode page, make sure Mode Static is selected then click **Next**.

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

This takes you to the Add Liquidity page. By default, the UI will select an Exponential distribution with a width of 0.1%. We’re going to change that so that we can add only SAND to this pool. You can edit any distribution manually, but to make this process simpler, we’re going to start with a Single Bin distribution.

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

Click the **Edit** button under **Select Distribution**, choose **Single Bin** in the modal, and click **Select**.

<figure><img src="/files/8voQkAmGIUaG1jRgGKrE" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/6IrHmAWgCKqR9IewXqX6" alt=""><figcaption></figcaption></figure>

Move your cursor over the top of the single bin in the Customize Distribution chart, and drag it all the way down to the bottom. This should leave you with an empty chart with all the bins set to zero.

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

We’ll now create a single-sided distribution of SAND by dragging up the bins on the right hand side of this chart (**check to make sure you’re dragging the bins on the correct side for your chosen token pair**).

For this example, we have designed a flat distribution of SAND consisting of five bins directly to the right of the current active bin (i.e., close to the current pool price). Depending on the situation, users may wish to use more/fewer bins in a different configuration at a different price point.

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

Choose how much SAND to add to this Distribution in the **Required Assets** bubble to the left of the chart. Here, we have selected 4000. Note that since we are single-sided, the UI has determined we do not need to add ETH. The amount you choose will be distributed proportionately across the distribution you designed (here, it will be apportioned equally between each of our five bins).

Click **Confirm** and then click **Confirm Amount** in the modal.

Confirm the transaction in your wallet.

## Creating a Boosted Position

Now that we have a supply of the project token in the pool, we’re going to create a Boosted Position to incentivize liquidity into the other side of the pool. In our ETH-SAND example, we’ll be using a Boosted Position to incentivize ETH into the pool we have chosen, but the same principles apply to any token pair.

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

Navigate to the **Boosted Positions** page, under **Add Liquidity** in the top menu.

Click the **New Boosted Position** button on the right, above the list of Boosted Positions.

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

On the Create a new Boosted Position page, select the correct token pair (here, ETH and SAND). Make sure the fee tier and width match the pool you added liquidity to. If they do not, click **Edit** to choose the correct values and select the right pool. Click **Next**.

On the Select Mode screen, make sure **Mode Static** is selected and click **Next**.

As when we added initial liquidity above, we’re going to begin by zeroing out the distribution chart. Click **Edit**, select **Single Bin**, and click **Select**. Then mouseover the top of the single bin in the **Customize Distribution** chart and drag it all the way to the bottom.

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

Now that we have an empty chart, we’re going to design the distribution we want to incentivize people to add liquidity to by dragging the bins on the ETH side of the chart up into the desired distribution (make sure you’re dragging the correct bins for your chosen token pair).

For this example, we’ve created a mirror of the SAND distribution as a simple demonstration of incentivizing matching liquidity in a pool, but a user may have reasons to use more/fewer bins, a different shape, or place this position farther away from the price.

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

Choose how much ETH to add to this Distribution in the **Required Assets** bubble to the left of the chart. Since this is only seed liquidity and we want users to bring their own ETH to this Boosted Position, we’ll keep this amount low.

Click **Confirm** and click **Confirm Amount** in the modal.

Confirm the transaction in your wallet.

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

When the transaction is complete, click **Done** to be taken to the **Portfolio** page. You should see a card representing this Boosted Position. Make a note of the number on this card. In the screenshot above, the Boosted Position is easy to spot because of the lightning bolt and the **Claim Rewards** button. The number we’re looking for in the screenshot is “#17.” We’ll need this to incentivize this Boosted Position in the next step.

## Adding Incentives

Now that we’ve added our protocol liquidity and set up a Boosted Position to direct matching ETH liquidity from LPs, we can add incentives to the Boosted Position to entice the ETH we want in our pool.

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

Navigate to the **Incentivize** page, under **Engage** in the top menu.

Use the Boosted Position list on this page to find the Boosted Position you created earlier. You can scroll or use the search bar. In this example, we’re looking for ETH-SAND #17 (see step 10 in the previous section for how to find this number).

Click on your Boosted Position to go to the Incentivize Boosted Position page.

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

Check to make sure you’ve chosen the correct Boosted Position.

Use the drop-down menu under **Incentivize LP** to select the token you want to use as an incentive. This will be transferred from your wallet to the rewards contract and distributed to LPs who add liquidity to this Boosted Position.

Choose the amount of this token you want to use as incentives using the numeric field to the right of the drop down menu.

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

Once you’ve chosen the token and amount, the **Duration** slider will appear. You can select a distribution period between 3 and 30 days in length. Your token incentives will be distributed evenly across whatever period you select.

In the event you do not see the slider, it is probably because another user has already added incentives to this Boosted Position. For more information, click [here](https://docs.mav.xyz/guides/incentives/understanding-incentives#lp-incentives).

Click **Incentivize** and click **Confirm Amount** in the modal.

Confirm the transaction in your wallet.


# Contract Addresses


# V1 Contract Addresses

This page lists the Maverick contract addresses on each chain.

## Ethereum Mainnet

<table><thead><tr><th width="218">Contract</th><th>Ethereum Address</th></tr></thead><tbody><tr><td>Factory</td><td>0xEb6625D65a0553c9dBc64449e56abFe519bd9c9B</td></tr><tr><td>Position</td><td>0x4A3e49f77a2A5b60682a2D6B8899C7c5211EB646</td></tr><tr><td>PositionInspector</td><td>0x456A37144162900799f405be34f815dE7C3DA53C</td></tr><tr><td>PoolInformation</td><td>0x0087D11551437c3964Dddf0F4FA58836c5C5d949</td></tr><tr><td>PoolPositionManager</td><td>0xE7583AF5121a8f583EFD82767CcCfEB71069D93A</td></tr><tr><td>PoolPositionAndRewardFactorySlim</td><td>0x4F24D73773fCcE560f4fD641125c23A2B93Fcb05</td></tr><tr><td>Router</td><td>0xbBF1EE38152E9D8e3470Dc47947eAa65DcA94913</td></tr><tr><td>MAV token</td><td>0x7448c7456a97769f6cd04f1e83a4a23ccdc46abd</td></tr><tr><td>veMAV token</td><td>0x4949Ac21d5b2A0cCd303C20425eeb29DCcba66D8</td></tr></tbody></table>

## zkSync Era

<table><thead><tr><th width="217.33333333333331">Contract</th><th>zkSync Era Address</th></tr></thead><tbody><tr><td>Factory</td><td>0x2C1a605f843A2E18b7d7772f0Ce23c236acCF7f5</td></tr><tr><td>Position</td><td>0xFd54762D435A490405DDa0fBc92b7168934e8525</td></tr><tr><td>PositionInspector</td><td>0x852639EE9dd090d30271832332501e87D287106C</td></tr><tr><td>PoolInformation</td><td>0x57D47F505EdaA8Ae1eFD807A860A79A28bE06449</td></tr><tr><td>PoolPositionManager</td><td>0x17132CE52D40248F5077f4F51C6E3BDf7682749F</td></tr><tr><td>PoolPositionAndRewardFactorySlim</td><td>0x0e70CA6F0F1a96aBAA4BFB2CD4aC113aF3d4a5a3</td></tr><tr><td>Router</td><td>0x39E098A153Ad69834a9Dac32f0FCa92066aD03f4</td></tr><tr><td>MAV token</td><td>0x787c09494Ec8Bcb24DcAf8659E7d5D69979eE508</td></tr><tr><td>veMAV token</td><td>0x7EDcB053d4598a145DdaF5260cf89A32263a2807</td></tr></tbody></table>

## BNB Smart Chain

<table><thead><tr><th width="217.33333333333331">Contract</th><th>BSC Address</th></tr></thead><tbody><tr><td>Factory</td><td>0x76311728FF86054Ad4Ac52D2E9Ca005BC702f589</td></tr><tr><td>Position</td><td>0x23Aeaf001E5DF9d7410EE6C6916f502b7aC8e9D0</td></tr><tr><td>PositionInspector</td><td>0x70Cd6087033E0b99e4e449D3B904FaD194D888A0</td></tr><tr><td>PoolInformation</td><td>0xB3916179619EEF2497C646e664Be6e13cd1AB445</td></tr><tr><td>PoolPositionManager</td><td>0x2D11545d36FfA0b8558e83C26e45cFaF14BDBAB2</td></tr><tr><td>PoolPositionAndRewardFactorySlim</td><td>0xFC328EA7700A86a9CcBE281D44C258385E26a9c0</td></tr><tr><td>Router</td><td>0xD53a9f3FAe2bd46D35E9a30bA58112A585542869</td></tr><tr><td>MAV token</td><td>0xd691d9a68C887BDF34DA8c36f63487333ACfD103</td></tr><tr><td>veMAV token</td><td>0xE6108f1869d37E5076a56168C66A1607EdB10819</td></tr></tbody></table>

## Base

<table><thead><tr><th width="217.33333333333331">Contract</th><th>Base Address</th></tr></thead><tbody><tr><td>Factory</td><td>0xB2855783a346735e4AAe0c1eb894DEf861Fa9b45</td></tr><tr><td>Position</td><td>0x0d8127A01bdb311378Ed32F5b81690DD917dBa35</td></tr><tr><td>PositionInspector</td><td>0x550056A68cB155b6Cc3DeF4A7FA656260e7842e2</td></tr><tr><td>PoolInformation</td><td>0x6E230D0e457Ea2398FB3A22FB7f9B7F68F06a14d</td></tr><tr><td>PoolPositionManager</td><td>0xC402D13B0D04867649a632F17528c753d8f6FBD2</td></tr><tr><td>PoolPositionAndRewardFactorySlim</td><td>0xbBF1EE38152E9D8e3470Dc47947eAa65DcA94913</td></tr><tr><td>Router</td><td>0x32AED3Bce901DA12ca8489788F3A99fCe1056e14</td></tr><tr><td>MAV token</td><td>0x64b88c73A5DfA78D1713fE1b4c69a22d7E0faAa7</td></tr><tr><td>veMAV token</td><td>0xFcCB5263148fbF11d58433aF6FeeFF0Cc49E0EA5</td></tr></tbody></table>

## Ethereum Goerli

<table><thead><tr><th width="217.33333333333331">Contract</th><th>Goerli Address</th></tr></thead><tbody><tr><td>Factory</td><td>0x6292B737E6640223EB783F1355737315985Ece49</td></tr><tr><td>Position</td><td>0x46040d596fe176A1b88A43be3537d9f6365ccbe1</td></tr><tr><td>PositionInspector</td><td>0xd9254a4E05C727C6797930Ba4799a6f39F6039C0</td></tr><tr><td>PoolInformation</td><td>0x0Eb806b0daE0D9639A531F1eB820d8F94fB9E941</td></tr><tr><td>PoolPositionManager</td><td>0x625cf8D5c6AE5Af9B359Becb1b1C4B63B8B8d56C</td></tr><tr><td>PoolPositionAndRewardFactorySlim</td><td>0x680ca064ACcEbdF5B7B8079924C5D0bb79302285</td></tr><tr><td>Router</td><td>0x9563Fdb01BFbF3D6c548C2C64E446cb5900ACA88</td></tr></tbody></table>


# V2 Contract Addresses

## Mainnets

### Arbitrum <a href="#arbitrum" id="arbitrum"></a>

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| WETH                              | 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1 |
| MaverickV2Factory                 | 0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e |
| MaverickV2PoolLens                | 0x6A9EB38DE5D349Fe751E0aDb4c0D9D391f94cc8D |
| MaverickV2Quoter                  | 0xb40AfdB85a07f37aE217E7D6462e609900dD8D7A |
| MaverickV2Router                  | 0x5c3b380e5Aeec389d1014Da3Eb372FA2C9e0fc76 |
| MaverickV2Position                | 0x116193c58B40D50687c0433B2aa0cC4AE00bC32c |
| MaverickV2BoostedPositionFactory  | 0xd94C8f6D13Cf480FfAC686712C63471D1596cc29 |
| MaverickV2BoostedPositionLens     | 0x12DD145927CECF616cbD196789c89C2573A53244 |
| MaverickV2IncentiveMatcherFactory | 0x11C0F55102790f84A6F132d8B25FDFe1c96d0992 |
| MaverickV2VotingEscrowFactory     | 0x51E4AE1BA70D657eEF8e31a2Cb6a8b9AA61aB84e |
| MaverickV2RewardFactory           | 0x873b272D7493Da5860E9c513cB805Ff3287D8470 |
| MaverickV2RewardRouter            | 0x293A7D159C5AD1b36b784998DE5563fe36963460 |
| MaverickV2VotingEscrowLens        | 0x102f936B0fc2E74dC34E45B601FaBaA522f381F0 |
| Maverick Token                    | 0x7448c7456a97769F6cD04F1E83A4a23cCdC46aBD |
| MaverickVeV2                      | 0xd5d8cB7569BB843c3b8FA98dBD5960d37E83eA8d |
| MaverickTokenIncentiveMatcher     | 0xB1F334176AadC61F74afc6381210e8786CcEc37D |

#### Pre-Epoch 3 Contracts

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| MaverickV2IncentiveMatcherFactory | 0x6A534cCd08Ab6aeB70336f345Edf563Dc5B84A84 |
| MaverickV2RewardFactory           | 0x353904E4AFDa57E8c4353a2Eb173e566D8dF826C |

### &#x20;<a href="#base" id="base"></a>

### Base <a href="#base" id="base"></a>

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| WETH                              | 0x4200000000000000000000000000000000000006 |
| MaverickV2Factory                 | 0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e |
| MaverickV2PoolLens                | 0x6A9EB38DE5D349Fe751E0aDb4c0D9D391f94cc8D |
| MaverickV2Quoter                  | 0xb40AfdB85a07f37aE217E7D6462e609900dD8D7A |
| MaverickV2Router                  | 0x5eDEd0d7E76C563FF081Ca01D9d12D6B404Df527 |
| MaverickV2Position                | 0x116193c58B40D50687c0433B2aa0cC4AE00bC32c |
| MaverickV2BoostedPositionFactory  | 0xd94C8f6D13Cf480FfAC686712C63471D1596cc29 |
| MaverickV2BoostedPositionLens     | 0x12DD145927CECF616cbD196789c89C2573A53244 |
| MaverickV2IncentiveMatcherFactory | 0xa476bb7DfCDD4E59dDaA6Ea9311A24cF28561544 |
| MaverickV2VotingEscrowFactory     | 0x1dE8C03c2D5DD021bd456bc4bB4F0ecD85f99443 |
| MaverickV2RewardFactory           | 0x1cdC67950a68256c5157987bBF700e94595807F8 |
| MaverickV2RewardRouter            | 0xE7c73727c1b67A2fA47E63DCBaa4859777aeF392 |
| MaverickV2VotingEscrowLens        | 0x102f936B0fc2E74dC34E45B601FaBaA522f381F0 |
| Maverick Token                    | 0x64b88c73A5DfA78D1713fE1b4c69a22d7E0faAa7 |
| LegacyMaverickVe                  | 0xFcCB5263148fbF11d58433aF6FeeFF0Cc49E0EA5 |
| MaverickVeV2                      | 0x05b1b801191B41a21B9C0bFd4c4ef8952eb28cd9 |
| MaverickTokenIncentiveMatcher     | 0xc84bDDC0C45FEeFB0F59e1c48332E4d47e29D112 |

#### Pre-Epoch 3 Contracts

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| MaverickV2IncentiveMatcherFactory | 0x8a4c87252BCAbB1B930Ba6B675d0fB7eB6Ba54a1 |
| MaverickV2RewardFactory           | 0x3fa57C30fF8B13f84817416CD748B2260Ce40B9A |

### &#x20;<a href="#bnb-smart-chain" id="bnb-smart-chain"></a>

### BNB Smart Chain <a href="#bnb-smart-chain" id="bnb-smart-chain"></a>

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| WETH                              | 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c |
| MaverickV2Factory                 | 0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e |
| MaverickV2PoolLens                | 0x6A9EB38DE5D349Fe751E0aDb4c0D9D391f94cc8D |
| MaverickV2Quoter                  | 0xb40AfdB85a07f37aE217E7D6462e609900dD8D7A |
| MaverickV2Router                  | 0x374bFCc264678c67a582D067AD91f1951bC6b20f |
| MaverickV2Position                | 0x116193c58B40D50687c0433B2aa0cC4AE00bC32c |
| MaverickV2BoostedPositionFactory  | 0xd94C8f6D13Cf480FfAC686712C63471D1596cc29 |
| MaverickV2BoostedPositionLens     | 0x12DD145927CECF616cbD196789c89C2573A53244 |
| MaverickV2IncentiveMatcherFactory | 0x53EEE0a9d1D301eA570329C298Af3f19d1D556c7 |
| MaverickV2VotingEscrowFactory     | 0x790d33B4271EDD0a611d91E971F2143D8a7DD936 |
| MaverickV2RewardFactory           | 0x443b1F86D45C1dDC60b355D5A8A931656aB25267 |
| MaverickV2RewardRouter            | 0x5DeB1bAe837374f988d8a30Cc0Fbccbc63892Bb3 |
| MaverickV2VotingEscrowLens        | 0x102f936B0fc2E74dC34E45B601FaBaA522f381F0 |
| MaverickToken                     | 0xd691d9a68C887BDF34DA8c36f63487333ACfD103 |
| LegacyMaverickVe                  | 0xE6108f1869d37E5076a56168C66A1607EdB10819 |
| MaverickVeV2                      | 0x675178AE86A75EE7D7Ef81e30a91E1798306094C |
| MaverickTokenIncentiveMatcher     | 0x053D0eC15e60c7D8936Ab966A82BB62cCb7E3Ced |

#### Pre-Epoch 3 Contracts

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| MaverickV2IncentiveMatcherFactory | 0xeB223179EFA75b1F2b592F5D0281c3E6e4111002 |
| MaverickV2RewardFactory           | 0x7573B601B2E4e0cDC8fbaA328e08e733C697c565 |

### &#x20;<a href="#ethereum-mainnet" id="ethereum-mainnet"></a>

### Ethereum Mainnet <a href="#ethereum-mainnet" id="ethereum-mainnet"></a>

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| WETH                              | 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 |
| MaverickV2Factory                 | 0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e |
| MaverickV2PoolLens                | 0x6A9EB38DE5D349Fe751E0aDb4c0D9D391f94cc8D |
| MaverickV2Quoter                  | 0xb40AfdB85a07f37aE217E7D6462e609900dD8D7A |
| MaverickV2Router                  | 0x62e31802c6145A2D5E842EeD8efe01fC224422fA |
| MaverickV2Position                | 0x116193c58B40D50687c0433B2aa0cC4AE00bC32c |
| MaverickV2BoostedPositionFactory  | 0xd94C8f6D13Cf480FfAC686712C63471D1596cc29 |
| MaverickV2BoostedPositionLens     | 0x12DD145927CECF616cbD196789c89C2573A53244 |
| MaverickV2IncentiveMatcherFactory | 0x924Dd05c2325829fa4063CAbE1456273084009d7 |
| MaverickV2VotingEscrowFactory     | 0x451d47fd6207781dc053551edFD98De8d5EB4Cda |
| MaverickV2RewardFactory           | 0x63EF1a657cc53747689B201aa07A76E9ef22f8Fe |
| MaverickV2RewardRouter            | 0xc0C3BC532690af8922a2f260c6e1dEb6CFaB45A0 |
| MaverickV2VotingEscrowLens        | 0x102f936B0fc2E74dC34E45B601FaBaA522f381F0 |
| MaverickToken                     | 0x7448c7456a97769F6cD04F1E83A4a23cCdC46aBD |
| LegacyMaverickVe                  | 0x4949Ac21d5b2A0cCd303C20425eeb29DCcba66D8 |
| MaverickVeV2                      | 0xC6addB3327A7D4b3b604227f82A6259Ca7112053 |
| MaverickTokenIncentiveMatcher     | 0x9172a390Cb35a15a890293f59EA5aF250b234D55 |

#### Pre-Epoch 3 Contracts

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| MaverickV2IncentiveMatcherFactory | 0x5740cA1B634D772fb5edB8bbc380FA982623E0b0 |
| MaverickV2RewardFactory           | 0x37232785ACD3EADdfd784dB3f9eCc1f8bcBd7eC7 |

### &#x20;<a href="#base" id="base"></a>

### Scroll <a href="#base" id="base"></a>

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| WETH                              | 0x5300000000000000000000000000000000000004 |
| MaverickV2Factory                 | 0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e |
| MaverickV2PoolLens                | 0x6A9EB38DE5D349Fe751E0aDb4c0D9D391f94cc8D |
| MaverickV2Quoter                  | 0xb40AfdB85a07f37aE217E7D6462e609900dD8D7A |
| MaverickV2Router                  | 0x15D5ff975c1181FAf938cd33BD0633435bdfA18d |
| MaverickV2Position                | 0x116193c58B40D50687c0433B2aa0cC4AE00bC32c |
| MaverickV2BoostedPositionFactory  | 0xd94C8f6D13Cf480FfAC686712C63471D1596cc29 |
| MaverickV2BoostedPositionLens     | 0x12DD145927CECF616cbD196789c89C2573A53244 |
| MaverickV2IncentiveMatcherFactory | 0x11C0F55102790f84A6F132d8B25FDFe1c96d0992 |
| MaverickV2VotingEscrowFactory     | 0x51E4AE1BA70D657eEF8e31a2Cb6a8b9AA61aB84e |
| MaverickV2RewardFactory           | 0x873b272D7493Da5860E9c513cB805Ff3287D8470 |
| MaverickV2RewardRouter            | 0xd837fcba68A6A5Aa63f791ea51F258d30546d2c1 |
| MaverickV2VotingEscrowLens        | 0x102f936B0fc2E74dC34E45B601FaBaA522f381F0 |

###

### zkSync Era <a href="#zksync-era" id="zksync-era"></a>

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| WETH                              | 0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91 |
| MaverickV2Factory                 | 0x7A6902af768a06bdfAb4F076552036bf68D1dc56 |
| MaverickV2PoolLens                | 0x9439280a7d04FCa28d12a4eB74c92173241d5b2F |
| MaverickV2Quoter                  | 0x3e1c4b57c9d9624f2841f07C6328D3c25ca30C79 |
| MaverickV2Router                  | 0xad8262e847676E7eDdAFEe664c4fd492789260ba |
| MaverickV2Position                | 0x4D93c58B348d99969257cec007cFb31B410b21A0 |
| MaverickV2BoostedPositionFactory  | 0x270a03bfc3EA123c041d4A0c72D30202A514D845 |
| MaverickV2BoostedPositionLens     | 0xd32CE31CaC98CAC0631764B8286358c0606D87F9 |
| MaverickV2IncentiveMatcherFactory | 0x11244D8b724De7788f62667791e35284E191745F |
| MaverickV2VotingEscrowFactory     | 0x521B444d5f9bb4B36CDd771f4D85cCd0B291FB92 |
| MaverickV2RewardFactory           | 0xc9e5F0832C96F8E2EEDe472C1B87621Cbb86D7e0 |
| MaverickV2RewardRouter            | 0x432e6791d35dc6c638f44E949A5c0228e4048244 |
| MaverickV2VotingEscrowLens        | 0x74E56528CDd2F831cc4ecc9414bCE9C4d540ceC7 |
| MaverickToken                     | 0x787c09494Ec8Bcb24DcAf8659E7d5D69979eE508 |
| LegacyMaverickVe                  | 0x7EDcB053d4598a145DdaF5260cf89A32263a2807 |
| MaverickVeV2                      | 0xe86151Af9cc43533add87921c381dA11c314DEBf |
| MaverickTokenIncentiveMatcher     | 0x57FA162aCb48376455c5Ff4D45FE0d36E947D79b |

#### Pre-Epoch 3 Contracts, Since Updated

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| MaverickV2IncentiveMatcherFactory | 0xA3c1648EaA480Dd52Bb8990b34D2B827E8834c29 |
| MaverickV2RewardFactory           | 0xdb7168fe2f3c1C3B400337ac0BDeDb9b193775F9 |

### &#x20;<a href="#bnb-smart-chain" id="bnb-smart-chain"></a>

## Testnets

### Arbitrum Sepolia <a href="#base" id="base"></a>

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| WETH                              | 0x997FE31Adda5c969691768Ad1140273290952333 |
| MaverickV2Factory                 | 0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e |
| MaverickV2PoolLens                | 0x6A9EB38DE5D349Fe751E0aDb4c0D9D391f94cc8D |
| MaverickV2Quoter                  | 0xb40AfdB85a07f37aE217E7D6462e609900dD8D7A |
| MaverickV2Router                  | 0x9ce6a2Df87Ab67C5C8317418524069793bc13DDc |
| MaverickV2Position                | 0x116193c58B40D50687c0433B2aa0cC4AE00bC32c |
| MaverickV2BoostedPositionFactory  | 0xd94C8f6D13Cf480FfAC686712C63471D1596cc29 |
| MaverickV2BoostedPositionLens     | 0x12DD145927CECF616cbD196789c89C2573A53244 |
| MaverickV2IncentiveMatcherFactory | 0x7b4F5FA58363c6c38a10ACb0EcBB8C7cFeF41aF4 |
| MaverickV2VotingEscrowFactory     | 0xFB1EAbBECC59fc531f9c5dCb71cCAADF24CE538a |
| MaverickV2RewardFactory           | 0x348c888eB04c0Dd4D44d075C9560be1e80AB4fe9 |
| MaverickV2RewardRouter            | 0xd487dca6e01C29DA00f5fF1060Ea465675D29B24 |
| MaverickV2VotingEscrowLens        | 0x102f936B0fc2E74dC34E45B601FaBaA522f381F0 |

### &#x20;<a href="#base-sepolia" id="base-sepolia"></a>

### Base Sepolia <a href="#base-sepolia" id="base-sepolia"></a>

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| WETH                              | 0x4200000000000000000000000000000000000006 |
| MaverickV2Factory                 | 0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e |
| MaverickV2PoolLens                | 0x6A9EB38DE5D349Fe751E0aDb4c0D9D391f94cc8D |
| MaverickV2Quoter                  | 0xb40AfdB85a07f37aE217E7D6462e609900dD8D7A |
| MaverickV2Router                  | 0x5eDEd0d7E76C563FF081Ca01D9d12D6B404Df527 |
| MaverickV2Position                | 0x116193c58B40D50687c0433B2aa0cC4AE00bC32c |
| MaverickV2BoostedPositionFactory  | 0xd94C8f6D13Cf480FfAC686712C63471D1596cc29 |
| MaverickV2BoostedPositionLens     | 0x12DD145927CECF616cbD196789c89C2573A53244 |
| MaverickV2IncentiveMatcherFactory | 0x11C0F55102790f84A6F132d8B25FDFe1c96d0992 |
| MaverickV2VotingEscrowFactory     | 0x51E4AE1BA70D657eEF8e31a2Cb6a8b9AA61aB84e |
| MaverickV2RewardFactory           | 0x873b272D7493Da5860E9c513cB805Ff3287D8470 |
| MaverickV2RewardRouter            | 0xd87D5dC4f1a093E02F84d1419F501afe0254CB53 |
| MaverickV2VotingEscrowLens        | 0x102f936B0fc2E74dC34E45B601FaBaA522f381F0 |

###

### BNB Testnet

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| WETH                              | 0xf80880c41ad3f470b9aac9393c4dec82b334b436 |
| MaverickV2Factory                 | 0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e |
| MaverickV2PoolLens                | 0x6A9EB38DE5D349Fe751E0aDb4c0D9D391f94cc8D |
| MaverickV2Quoter                  | 0xb40AfdB85a07f37aE217E7D6462e609900dD8D7A |
| MaverickV2Router                  | 0xCff049230d142965c2c73b1b801557062E824a71 |
| MaverickV2Position                | 0x116193c58B40D50687c0433B2aa0cC4AE00bC32c |
| MaverickV2BoostedPositionFactory  | 0xd94C8f6D13Cf480FfAC686712C63471D1596cc29 |
| MaverickV2BoostedPositionLens     | 0x12DD145927CECF616cbD196789c89C2573A53244 |
| MaverickV2IncentiveMatcherFactory | 0x11C0F55102790f84A6F132d8B25FDFe1c96d0992 |
| MaverickV2VotingEscrowFactory     | 0x51E4AE1BA70D657eEF8e31a2Cb6a8b9AA61aB84e |
| MaverickV2RewardFactory           | 0x873b272D7493Da5860E9c513cB805Ff3287D8470 |
| MaverickV2RewardRouter            | 0x730ee2707C30bE816907d87386ed44C39E45B15b |
| MaverickV2VotingEscrowLens        | 0x102f936B0fc2E74dC34E45B601FaBaA522f381F0 |

### &#x20;<a href="#sepolia" id="sepolia"></a>

### Sepolia <a href="#sepolia" id="sepolia"></a>

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| WETH                              | 0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9 |
| MaverickV2Factory                 | 0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e |
| MaverickV2PoolLens                | 0x6A9EB38DE5D349Fe751E0aDb4c0D9D391f94cc8D |
| MaverickV2Quoter                  | 0xb40AfdB85a07f37aE217E7D6462e609900dD8D7A |
| MaverickV2Router                  | 0x4563d58D072C3198A66EAfCf3333024330dE9104 |
| MaverickV2Position                | 0x116193c58B40D50687c0433B2aa0cC4AE00bC32c |
| MaverickV2BoostedPositionFactory  | 0xd94C8f6D13Cf480FfAC686712C63471D1596cc29 |
| MaverickV2BoostedPositionLens     | 0x12DD145927CECF616cbD196789c89C2573A53244 |
| MaverickV2IncentiveMatcherFactory | 0x11C0F55102790f84A6F132d8B25FDFe1c96d0992 |
| MaverickV2VotingEscrowFactory     | 0x51E4AE1BA70D657eEF8e31a2Cb6a8b9AA61aB84e |
| MaverickV2RewardFactory           | 0x873b272D7493Da5860E9c513cB805Ff3287D8470 |
| MaverickV2RewardRouter            | 0x0d17027A98F1396EC2A250d99Dc349e8cf93abb1 |
| MaverickV2VotingEscrowLens        | 0x102f936B0fc2E74dC34E45B601FaBaA522f381F0 |

### &#x20;<a href="#zksync-sepolia" id="zksync-sepolia"></a>

### zkSync Sepolia <a href="#zksync-sepolia" id="zksync-sepolia"></a>

| Contract                          | Address                                    |
| --------------------------------- | ------------------------------------------ |
| WETH                              | 0x53F7e72C7ac55b44c7cd73cC13D4EF4b121678e6 |
| MaverickV2Factory                 | 0x6D121BcABEf869518414a747e30c4568869aE0B4 |
| MaverickV2PoolLens                | 0x945cb8E04A9469959C08675846914B13905E5EaD |
| MaverickV2Quoter                  | 0x2D2ED310f4ED89c6460154D8f3AA98d1A254cd1e |
| MaverickV2Router                  | 0xC7F2F69C4A07362d1b8144e78564D166f83aFb7A |
| MaverickV2Position                | 0xD61Fa8Fb76F90ae007E6CeEA4F8FFf7Fcc5BB1C9 |
| MaverickV2BoostedPositionFactory  | 0x4C7A6AE41b51564f579Ce7f86694A9e1e15633D9 |
| MaverickV2BoostedPositionLens     | 0x67E8F8Fa97D528094e24A3b2f5AB0E9B14E2Bc50 |
| MaverickV2IncentiveMatcherFactory | 0x471199b467b180fFBa5E488b52F8AdFde3A51037 |
| MaverickV2VotingEscrowFactory     | 0x7d88e512949763C4dF1F431E873761cC829B0BF6 |
| MaverickV2RewardFactory           | 0xb1e6BDfd9651c70f390FD7dDdD68b891fAccb470 |
| MaverickV2RewardRouter            | 0x9D4222b09E6f61E572c6D75abD88c8E229AeB6E3 |
| MaverickV2VotingEscrowLens        | 0x852eB4863d5F3c0924fDfeD393E09e32c8e20e4A |


# Maverick V1

This section collects technical information related to Maverick V1.


# V1  Contracts

{% content-ref url="/pages/ImNr6EmuFUvUta86hVnz" %}
[Router](/technical-reference/maverick-v1/v1-contracts/router)
{% endcontent-ref %}

{% content-ref url="/pages/66UXftDEePkJZD0TJ1IQ" %}
[Pool](/technical-reference/maverick-v1/v1-contracts/pool)
{% endcontent-ref %}

{% content-ref url="/pages/VHi0IsViEu2KNkyTN4gA" %}
[Factory](/technical-reference/maverick-v1/v1-contracts/factory)
{% endcontent-ref %}

{% content-ref url="/pages/mlIBnuYIuoqW4omOwEbj" %}
[SlimRouter](/technical-reference/maverick-v1/v1-contracts/slimrouter)
{% endcontent-ref %}


# Router

This documentation provides an overview of the IRouter.sol. This contract defines various functions and structs used for interacting with the Maverick AMM.

## Contents

* [**Contract Details**](#contract-details)
* [**Structs**](#structs)
  * [ExactInputParams](#struct-exactinputparams)
  * [ExactOutputParams](#struct-exactoutputparams)
  * [PoolParams](#struct-poolparams)
* [**Functions**](#functions)
  * [factory()](#fn-factory)
  * [position()](#fn-position)
  * [exactInput()](#fn-exactinput)
  * [exactOutput()](#fn-exactoutput)
  * [getOrCreatePoolAndAddLiquidity()](#fn-getorcreatepoolandaddliquidity)
  * [addLiquidityToPool()](#fn-addliquiditytopool)
  * [addLiquidityWTickLimits()](#fn-addliquiditywticklimits)
  * [migrateBinsUpStack()](#fn-migratebinsupstack)
  * [removeLiquidity()](#fn-removeliquidity)

## **Contract Details** <a href="#contract-details" id="contract-details"></a>

* **Name :** *IRouter*
* **Solidity Version :** *^0.8.0*
* *SPDX License-Identifier : GPL-2.0-or-later*
* **`Router` is Deployed to**
  * Ethereum: [`0xbBF1EE38152E9D8e3470Dc47947eAa65DcA94913`](https://etherscan.io/address/0xbBF1EE38152E9D8e3470Dc47947eAa65DcA94913#code)
  * ZKSync Era: [`0x39E098A153Ad69834a9Dac32f0FCa92066aD03f4`](https://explorer.zksync.io/address/0x39E098A153Ad69834a9Dac32f0FCa92066aD03f4#contract)
* Code: [Github](https://github.com/maverickprotocol/router-v1/tree/main/contracts)

## **Structs** <a href="#structs" id="structs"></a>

### PoolParams <a href="#struct-poolparams" id="struct-poolparams"></a>

```solidity
struct PoolParams {
    uint256 fee;
    uint256 tickSpacing;
    int256 lookback;
    int32 activeTick;
    IERC20 tokenA;
    IERC20 tokenB;
}
```

* `fee` : The fee value `uint256` associated with the pool.
* `tickSpacing` : The tick spacing value `uint256` for the pool.
* `lookback` : The lookback value `int256` for the pool.
* `activeTick` : The active tick value `int32` for the pool.
* `tokenA` : The ERC20 token A `address` associated with the pool.
* `tokenB` : The ERC20 token B `address` associated with the pool.

### ExactInputParams <a href="#struct-exactinputparams" id="struct-exactinputparams"></a>

```solidity
struct ExactInputParams {
    bytes path;
    address recipient;
    uint256 deadline;
    uint256 amountIn;
    uint256 amountOutMinimum;
}
```

* `path` : A `bytes` string representing the path of tokens to swap.
* `recipient` : The `address` where the swapped tokens will be sent.
* `deadline` : The deadline timestamp (in seconds) `uint256` until which the swap can be executed.
* `amountIn` : The amount of the input token `uint256` to be swapped.
* `amountOutMinimum` : The minimum acceptable amount of the output token `uint256` specified to prevent infinite slippage.

### ExactOutputParams <a href="#struct-exactoutputparams" id="struct-exactoutputparams"></a>

```solidity
struct ExactOutputParams {
    bytes path;
    address recipient;
    uint256 deadline;
    uint256 amountOut;
    uint256 amountInMaximum;
}
```

* `path` : A `bytes` string representing the path of tokens to swap *(reversed)*.
* `recipient` : The `address` where the swapped tokens will be sent.
* `deadline` : The deadline timestamp (in seconds) `uint256` until which the swap can be executed.
* `amountOut` : The amount of the output token `uint256` desired.
* `amountInMaximum` : The maximum acceptable amount of the input token `uint256` required.

## **Functions** <a href="#functions" id="functions"></a>

### factory() <a href="#fn-factory" id="fn-factory"></a>

Returns the address of the factory.

```solidity
function factory() external view returns (IFactory);
```

* Returns :
  * IFactory : The `address` of the Factory

### position() <a href="#fn-position" id="fn-position"></a>

Returns the address of the Position NFT.

```solidity
function position() external view returns (IPosition);
```

* Returns
  * IPosition : The position NFT `address`

### exactInput() <a href="#fn-exactinput" id="fn-exactinput"></a>

Swaps `amountIn` of one token for as much as possible of another along the specified path.

```solidity
function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);
```

* Parameters :
  * `params` : The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
* Returns :
  * `amountOut` : The amount of the received token in `uint256`

### exactOutput() <a href="#fn-exactoutput" id="fn-exactoutput"></a>

Swaps as little as possible of one token for `amountOut` of another along the specified path *(reversed)*.

```solidity
function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
```

* Parameters :
  * `params` : The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata
* Returns :
  * `amountIn` : The amount of the input token in `uint256`

### getOrCreatePoolAndAddLiquidity() <a href="#fn-getorcreatepoolandaddliquidity" id="fn-getorcreatepoolandaddliquidity"></a>

Either gets an existing pool or creates a pool if it does not exist and adds liquidity to it.

```solidity
function getOrCreatePoolAndAddLiquidity(
    PoolParams calldata poolParams,
    uint256 tokenId,
    IPool.AddLiquidityParams[] calldata addParams,
    uint256 minTokenAAmount,
    uint256 minTokenBAmount,
    uint256 deadline
) external payable returns (uint256 receivingTokenId, uint256 tokenAAmount, uint256 tokenBAmount, IPool.BinDelta[] memory binDeltas);
```

* Parameters :
  * `poolParams` : Parameters of a pool with `poolParams`
  * `tokenId` : NFT ID of the token `uint256` that will hold LP balance. Use `0` to mint a new token
  * `addParams` : Parameters of liquidity addition with `addParams`
  * `minTokenAAmount` : Minimum amount of token A `uint256` to add. Reverts if not met
  * `minTokenBAmount` : Minimum amount of token B `uint256` to add. Reverts if not met
  * `deadline` : Epoch timestamp (in seconds) `uint256`
* Returns :
  * `receivingTokenId` : The ID `uint256` of the receiving token
  * `tokenAAmount` : The amount of token A `uint256`
  * `tokenBAmount` : The amount of token B `uint256`
  * `binDeltas` : An array of `BinDelta` structures

### addLiquidityToPool() <a href="#fn-addliquiditytopool" id="fn-addliquiditytopool"></a>

Adds liquidity to a pool.

```solidity
function addLiquidityToPool(
    IPool pool,
    uint256 tokenId,
    IPool.AddLiquidityParams[] calldata params,
    uint256 minTokenAAmount,
    uint256 minTokenBAmount,
    uint256 deadline
) external payable returns (uint256 receivingTokenId, uint256 tokenAAmount, uint256 tokenBAmount, IPool.BinDelta[] memory binDeltas);
```

* Parameters :
  * `pool` : Pool to add liquidity to `IPool`
  * `tokenId` : NFT ID of the token `uint256` that will hold LP balance. Use `0` to mint a new token
  * `params` : Parameters of liquidity addition with `params`
  * `minTokenAAmount` : Minimum amount of token A `uint256` to add. Reverts if not met
  * `minTokenBAmount` : Minimum amount of token B `uint256` to add. Reverts if not met
  * `deadline` : Epoch timestamp (in seconds) `uint256`
* Returns :
  * `receivingTokenId` : The ID of the receiving token `uint256`
  * `tokenAAmount` : The amount of token A `uint256`
  * `tokenBAmount` : The amount of token B `uint256`
  * `binDeltas` : An array of `BinDelta` structures

### addLiquidityWTickLimits() <a href="#fn-addliquiditywticklimits" id="fn-addliquiditywticklimits"></a>

Adds liquidity to a pool with active tick limits.

```solidity
function addLiquidityWTickLimits(
    IPool pool,
    uint256 tokenId,
    IPool.AddLiquidityParams[] calldata params,
    uint256 minTokenAAmount,
    uint256 minTokenBAmount,
    int32 minActiveTick,
    int32 maxActiveTick,
    uint256 deadline
) external payable returns (uint256 receivingTokenId, uint256 tokenAAmount, uint256 tokenBAmount, IPool.BinDelta[] memory binDeltas);
```

* Parameters :
  * `pool` : Pool to add liquidity to `IPool`
  * `tokenId` : NFT ID of the token `uint256` that will hold LP balance. Use `0` to mint a new token
  * `params` : Parameters of liquidity addition with `params`
  * `minTokenAAmount` : Minimum amount of token A `uint256` to add. Reverts if not met
  * `minTokenBAmount` : Minimum amount of token B `uint256` to add. Reverts if not met
  * `minActiveTick` : Lowest activeTick `int32` *(inclusive)* of the pool that will permit the transaction to pass
  * `maxActiveTick` : Highest activeTick `int32` *(inclusive)* of the pool that will permit the transaction to pass
  * `deadline` : Epoch timestamp *(in seconds)*
* Returns :
  * `receivingTokenId` : The ID of the receiving token `uint256`
  * `tokenAAmount` : The amount of token A `uint256`
  * `tokenBAmount` : The amount of token B `uint256`
  * `binDeltas` : An array of `BinDelta` structures

### migrateBinsUpStack() <a href="#fn-migratebinsupstack" id="fn-migratebinsupstack"></a>

Moves the head of input merged bins to the active bin.

```solidity
function migrateBinsUpStack(IPool pool, uint128[] calldata binIds, uint32 maxRecursion, uint256 deadline) external;
```

* Parameters :
  * `pool` : Pool to remove from with `IPool`
  * `binIds` : Array of `binIds` to migrate
  * `maxRecursion` : Maximum recursion depth `uint32` before returning; `0` means no maximum
  * `deadline` : Epoch timestamp *(in seconds)* `uint256`

### removeLiquidity() <a href="#fn-removeliquidity" id="fn-removeliquidity"></a>

Removes liquidity from a pool and receives WETH if one of the tokens is WETH.

```solidity
function removeLiquidity(
    IPool pool,
    address recipient,
    uint256 tokenId,
    IPool.RemoveLiquidityParams[] calldata params,
    uint256 minTokenAAmount,
    uint256 minTokenBAmount,
    uint256 deadline
) external returns (uint256 tokenAAmount, uint256 tokenBAmount, IPool.BinDelta[] memory binDeltas);
```

> Router must be approved for the withdrawing tokenId: `Position.approve(router, tokenId)`

* Parameters :
  * `pool` : Pool to remove from with `IPool`
  * `recipient` : `address` where the proceeds are sent. Use `zero` or router address to leave tokens in the router
  * `tokenId` : ID `uint256` of the position NFT that holds liquidity
  * `params` : Parameters of liquidity removal with `params`
  * `minTokenAAmount` : Minimum amount of token A `uint256` to receive. Reverts if not met
  * `minTokenBAmount` : Minimum amount of token B `uint256` to receive. Reverts if not met
  * `deadline` : Epoch timestamp *(in seconds)* `uint256`
* Returns :
  * `tokenAAmount` : The amount of token A `uint256` received
  * `tokenBAmount` : The amount of token B `uint256` received
  * `binDeltas` : An array of `BinDelta` structure


# Pool

This documentation provides an overview of the IPool.sol. This contract defines the functions and events for interacting with a liquidity pool in Maverick AMM.

### **Table of Contents**

* [**Contract Details**](#contract-details)
* [**Events**](#events)
  * [Swap](#event-swap)
  * [AddLiquidity](#event-addliquidity)
  * [MigrateBinsUpStack](#event-migratebinsupstack)
  * [TransferLiquidity](#event-transferliquidity)
  * [RemoveLiquidity](#event-removeliquidity)
  * [BinMerged](#event-binmerged)
  * [BinMoved](#event-binmoved)
  * [ProtocolFeeCollected](#event-protocolfeecollected)
  * [SetProtocolFeeRatio](#event-setprotocolfeeratio)
* [**Structs**](#structs)
  * [BinDelta](#struct-bindelta)
  * [TwaState](#struct-twastate)
  * [BinState](#struct-binstate)
  * [AddLiquidityParams](#struct-addliquidityparams)
  * [RemoveLiquidityParams](#struct-removeliquidityparams)
  * [State](#struct-state)
* [**Functions**](#functions)
  * [fee()](#fn-fee)
  * [tickSpacing()](#fn-tickspacing)
  * [tokenA()](#fn-tokena)
  * [tokenB()](#fn-tokenb)
  * [factory()](#fn-factory)
  * [binMap()](#fn-binmap)
  * [binPositions()](#fn-binpositions)
  * [binBalanceA()](#fn-binbalancea)
  * [binBalanceB()](#fn-binbalanceb)
  * [getTwa()](#fn-gettwa)
  * [getCurrentTwa()](#fn-getcurrenttwa)
  * [getState()](#fn-getstate)
  * [addLiquidity()](#fn-addliquidity)
  * [transferLiquidity()](#fn-transferliquidity)
  * [removeLiquidity()](#fn-removeliquidity)
  * [migrateBinUpStack()](#fn-migratebinupstack)
  * [swap()](#fn-swap)
  * [getBin()](#fn-getbin)
  * [balanceOf()](#fn-balanceof)
  * [tokenAScale()](#fn-tokenascale)
  * [tokenBScale()](#fn-tokenbscale)

## **Contract Details** <a href="#contract-details" id="contract-details"></a>

* **Name :** *IPool*
* **Solidity Version :** *^0.8.0*
* *SPDX License-Identifier : GPL-2.0-or-later*
* Code: [Github](https://github.com/maverickprotocol/maverick-v1-interfaces/blob/main/contracts/interfaces/IPool.sol)

## **Events** <a href="#events" id="events"></a>

### Swap <a href="#event-swap" id="event-swap"></a>

```solidity
event Swap(address sender, address recipient, bool tokenAIn, bool exactOutput, uint256 amountIn, uint256 amountOut, int32 activeTick);
```

* `sender` : The `address` that executed this swap
* `recipient` : The `address` receiving this swap
* `tokenAIn` : A `boolean` to determine if there is any input for Token A
* `exactOutput` : A `boolean` to determine if there is any exact amount of tokens expected to receive
* `amountIn` : The `uint256` amount of the input token
* `amountOut` : The `uint256` amount of the output token
* `activeTick` : The active tick `int32` value for the pool

### AddLiquidity <a href="#event-addliquidity" id="event-addliquidity"></a>

```solidity
event AddLiquidity(address indexed sender, uint256 indexed tokenId, BinDelta[] binDeltas);
```

* `sender` : The indexed sender `address` that executed `addLiquidity()`
* `tokenId` : The `uint256` indexed ID of the receiving token
* `binDeltas` : An array of `BinDelta` structures

### MigrateBinsUpStack <a href="#event-migratebinsupstack" id="event-migratebinsupstack"></a>

```solidity
event MigrateBinsUpStack(address indexed sender, uint128 binId, uint32 maxRecursion);
```

* `sender` : The indexed sender `address` that executed `MigrateBinsUpStack()`
* `binId` : The `uint128` bin ID that was migrated
* `maxRecursion` : Maximum recursion depth in `uint32`

### TransferLiquidity <a href="#event-transferliquidity" id="event-transferliquidity"></a>

```solidity
event TransferLiquidity(uint256 fromTokenId, uint256 toTokenId, RemoveLiquidityParams[] params);
```

* `fromTokenId` : Transfer liquidity from token ID `uint256`
* `toTokenId` : Transfer liquidity to token ID `uint256`
* `params` : Array of `RemoveLiquidityParams` that specify the bins and amounts

### RemoveLiquidity <a href="#event-removeliquidity" id="event-removeliquidity"></a>

```solidity
event RemoveLiquidity(address indexed sender, address indexed recipient, uint256 indexed tokenId, BinDelta[] binDeltas);
```

* `sender` : Remove liquidity from sender `address`
* `recipient` : Remove liquidity to receiver `address`
* `tokenId` : Current indexed `uint256` tokenId to remove liquidity from
* `binDeltas` : Array of `BinDelta` that specify the bins and amounts

### BinMerged <a href="#event-binmerged" id="event-binmerged"></a>

```solidity
event BinMerged(uint128 indexed binId, uint128 reserveA, uint128 reserveB, uint128 mergeId);
```

* `binId` : The indexed bin ID `uint128` that was merged.
* `reserveA` : amount of A token `uint128` in bin.
* `reserveB` : amount of B token `uint128` in bin.
* `mergeId` : The current active bin `uint128`.

### BinMoved <a href="#event-binmoved" id="event-binmoved"></a>

```solidity
event BinMoved(uint128 indexed binId, int128 previousTick, int128 newTick);
```

* `binId` : The indexed bin ID `uint128` that was moved.
* `previousTick` : Previous tick value in `int128`.
* `newTick` : New tick value in `uint128`.

### ProtocolFeeCollected <a href="#event-protocolfeecollected" id="event-protocolfeecollected"></a>

```solidity
event ProtocolFeeCollected(uint256 protocolFee, bool isTokenA);
```

* `protocolFee` : Amount of Protocol fee collected in `uint256`.
* `isTokenA` : `boolean` check if Token A was used for Protocol fee.

### SetProtocolFeeRatio <a href="#event-setprotocolfeeratio" id="event-setprotocolfeeratio"></a>

```solidity
event SetProtocolFeeRatio(uint256 protocolFee);
```

* `protocolFee` : The new amount of Protocol fee set in `uint256`.

## **Structs** <a href="#structs" id="structs"></a>

### BinDelta <a href="#struct-bindelta" id="struct-bindelta"></a>

Return parameters for Add/Remove liquidity.

```solidity
struct BinDelta {
        uint128 deltaA;
        uint128 deltaB;
        uint256 deltaLpBalance;
        uint128 binId;
        uint8 kind;
        int32 lowerTick;
        bool isActive;
    }
```

* `deltaA` : The amount of A token `uint128` that has been added or removed
* `deltaB` : The amount of B token `uint128` that has been added or removed
* `deltaLpBalance` : The amount of LP balance `uint256` that has increase *(add)* or decreased *(remove)*
* `binId` : The bin ID `uint128` of the bin that changed
* `kind` : One of the 4 Kinds *(0=static, 1=right, 2=left, 3=both)* in `uint8`
* `lowerTick` : The lower price tick `int32` of the bin in its current state
* `isActive` : A `boolean` to indicate whether the bin is still active

### TwaState <a href="#struct-twastate" id="struct-twastate"></a>

Time weighted average state.

```solidity
    struct TwaState {
        int96 twa;
        int96 value;
        uint64 lastTimestamp;
    }
```

* `twa` : The twa `int96` at the last update instant
* `value` : The new value `int96` that was passed in at the last update
* `lastTimestamp` : The timestamp `uint64` of the last update in seconds

### BinState <a href="#struct-binstate" id="struct-binstate"></a>

The bin state parameters.

```solidity
    struct BinState {
        uint128 reserveA;
        uint128 reserveB;
        uint128 mergeBinBalance;
        uint128 mergeId;
        uint128 totalSupply;
        uint8 kind;
        int32 lowerTick;
    }
```

* `reserveA` : The amount of A token `uint128` in bin
* `reserveB` : The amount of B token `uint128` in bin
* `mergeBinBalance` : The LP token balance `uint128` that this bin possesses after merge
* `mergeId` : The `binId` that this bin `uint128` has merged in to
* `totalSupply` : The total amount of LP tokens `uint128` in this bin
* `kind` : one of the 4 Kinds *(0=static, 1=right, 2=left, 3=both)* in `uint8`
* `lowerTick` : The lower price tick `int32` of the bin in its current state

### AddLiquidityParams <a href="#struct-addliquidityparams" id="struct-addliquidityparams"></a>

Parameters for each bin that will get new liquidity.

```solidity
    struct AddLiquidityParams {
        uint8 kind;
        int32 pos;
        bool isDelta;
        uint128 deltaA;
        uint128 deltaB;
    }
```

* `kind` : one of the 4 Kinds *(0=static, 1=right, 2=left, 3=both)* in `uint8`
* `pos` : The bin position in `int32`
* `isDelta` : A `boolean` that indicates whether the bin position is relative to the current bin or an absolute position
* `deltaA` : The amount of A token `uint128` to add
* `deltaB` : The amount of B token `uint128` to add

### RemoveLiquidityParams <a href="#struct-removeliquidityparams" id="struct-removeliquidityparams"></a>

Parameters for each bin that will have liquidity removed.

```solidity
    struct RemoveLiquidityParams {
        uint128 binId;
        uint128 amount;
    }
```

* `binId` : The index of the bin `uint128` losing liquidity
* `amount` : The LP balance amount `uint128` to remove

### State <a href="#struct-state" id="struct-state"></a>

The state of the pool.

```solidity
    struct State {
        int32 activeTick;
        uint8 status;
        uint128 binCounter;
        uint64 protocolFeeRatio;
    }
```

* `activeTick` : The current bin position `int32` that contains the active bins
* `status` : The status values `uint8` defined in `Pool.sol` *e.g. locked or unlocked;*
* `binCounter` : The index `uint128` of the last bin created
* `protocolFeeRatio` : The ratio of the swap fee that is kept for the protocol in `uint64`

## **Functions** <a href="#functions" id="functions"></a>

### fee() <a href="#fn-fee" id="fn-fee"></a>

Retrieves the fee for the pool in 18 decimal format.

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

* Returns :
  * The fee `uint256` for the pool as a uint256 value

### tickSpacing() <a href="#fn-tickspacing" id="fn-tickspacing"></a>

Retrieves the tick spacing of the pool. The tick spacing is used to calculate the bin width.

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

* Returns :
  * The tick spacing as a `uint256` value

### tokenA() <a href="#fn-tokena" id="fn-tokena"></a>

Retrieves the address of token A associated with the pool.

```solidity
function tokenA() external view returns (IERC20);
```

* Returns :
  * The `address` of token A as an IERC20 interface

### tokenB() <a href="#fn-tokenb" id="fn-tokenb"></a>

Retrieves the address of token B associated with the pool.

```solidity
function tokenB() external view returns (IERC20);
```

* Returns :
  * The `address` of token B as an IERC20 interface

### factory() <a href="#fn-factory" id="fn-factory"></a>

Retrieves the address of the factory contract associated with the pool.

```solidity
function factory() external view returns (IFactory);
```

* Returns :
  * The `address` of the factory contract as an `IFactory` interface

### binMap() <a href="#fn-binmap" id="fn-binmap"></a>

Retrieves the bitmap of active bins at the given tick.

```solidity
function binMap(int32 tick) external view returns (uint256);
```

* Parameters :
  * tick : The tick `int32` for which to retrieve the active bin map
* Returns :
  * The bitmap of active bins as a `uint256` value

### binPositions() <a href="#fn-binpositions" id="fn-binpositions"></a>

Retrieves the bin ID for the given tick and bin kind

```solidity
function binPositions(int32 tick, uint256 kind) external view returns (uint128);
```

* Parameters:
  * `tick`: The tick `int32` for which to retrieve the bin ID
  * `kind`: The kind `uint256` of the bin *(0=static, 1=right, 2=left, 3=both)*
* Returns:
  * The bin ID as a uint128 value

### binBalanceA() <a href="#fn-binbalancea" id="fn-binbalancea"></a>

Retrieves the internal accounting of the sum of token A balances across bins.

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

* Returns: The sum of token A balances as a `uint128` value

### binBalanceB() <a href="#fn-binbalanceb" id="fn-binbalanceb"></a>

Retrieves the internal accounting of the sum of token B balances across bins.

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

* Returns:
  * The sum of token B balances as a `uint128` value

### getTwa() <a href="#fn-gettwa" id="fn-gettwa"></a>

Retrieves the time-weighted average (TWA) state values.

```solidity
function getTwa() external view returns (TwaState memory);
```

* Returns:
  * A `TwaState` structure containing the TWA, value, last timestamp, and look back

### getCurrentTwa() <a href="#fn-getcurrenttwa" id="fn-getcurrenttwa"></a>

Retrieves the log base binWidth of the time-weighted average price.

```solidity
function getCurrentTwa() external view returns (int256);
```

* Returns:
  * The log base binWidth of the TWA as an `int256` value.

### getState() <a href="#fn-getstate" id="fn-getstate"></a>

Retrieves the state of the pool.

```solidity
function getState() external view returns (State memory);
```

* Returns:
  * A `State` structure containing the active tick, status, bin counter, and protocol fee ratio

### addLiquidity() <a href="#fn-addliquidity" id="fn-addliquidity"></a>

Adds liquidity to a pool.

```solidity
function addLiquidity(uint256 tokenId, AddLiquidityParams[] calldata params, bytes calldata data)
    external
    returns (uint256 tokenAAmount, uint256 tokenBAmount, BinDelta[] memory binDeltas);
```

* Parameters:
  * `tokenId`: The NFT token ID `uint256` that will hold the position.
  * `params`: An array of `AddLiquidityParams` structures that specify the mode, position, and liquidity details.
  * `data`: A callback function that `addLiquidity` will call to transfer tokens.
* Returns:
  * `tokenAAmount`: The amount of token A added as a `uint256` value.
  * `tokenBAmount`: The amount of token B added as a `uint256` value.
  * `binDeltas`: An array of `BinDelta` structures representing the changes in bin states.

### transferLiquidity() <a href="#fn-transferliquidity" id="fn-transferliquidity"></a>

Transfers liquidity from one NFT token ID to another using an array of bins.

```solidity
function transferLiquidity(uint256 fromTokenId, uint256 toTokenId, RemoveLiquidityParams[] calldata params) external;
```

* Parameters:
  * `fromTokenId`: The NFT token ID `uint256` that holds the position being transferred.
  * `toTokenId`: The NFT token ID `uint256` that is receiving the liquidity.
  * `params`: An array of `RemoveLiquidityParams` structures specifying the bins and amounts to transfer.

### removeLiquidity() <a href="#fn-removeliquidity" id="fn-removeliquidity"></a>

Removes liquidity from a pool.

```solidity
function removeLiquidity(address recipient, uint256 tokenId, RemoveLiquidityParams[] calldata params)
    external
    returns (uint256 tokenAOut, uint256 tokenBOut, BinDelta[] memory binDeltas);
```

* Parameters:
  * `recipient`: The `address` that will receive the removed tokens.
  * `tokenId`: The NFT token ID `uint256` that holds the position being removed.
  * `params`: An array of `RemoveLiquidityParams` structures specifying the bins and amounts to remove.
* Returns:
  * `tokenAOut`: The amount of token A `uin256` received as a result of removing liquidity.
  * `tokenBOut`: The amount of token B `uin256` received as a result of removing liquidity.
  * `binDeltas`: An array of `BinDelta` structures representing the changes in bin states.

### migrateBinUpStack() <a href="#fn-migratebinupstack" id="fn-migratebinupstack"></a>

Migrates bins up the linked list of merged bins so that its mergeId is the current active bin.

```solidity
function migrateBinUpStack(uint128 binId, uint32 maxRecursion) external;
```

* Parameters:
  * `binId`: An array of the bin IDs `uint128` to be migrated.
  * `maxRecursion`: The maximum recursion depth `uint32` of the migration. Set to `zero` to recurse until the active bin is found.

### swap() <a href="#fn-swap" id="fn-swap"></a>

Swaps tokens.

```solidity
function swap(
    address recipient,
    uint256 amount,
    bool tokenAIn,
    bool exactOutput,
    uint256 sqrtPriceLimit,
    bytes calldata data
) external returns (uint256 amountIn, uint256 amountOut);
```

* Parameters:
  * `recipient`: The `address` that will receive the output tokens.
  * `amount`: The amount of tokens `uint256` to swap.
  * `tokenAIn`: A `boolean` indicating whether token A is the input.
  * `exactOutput`: A `boolean` indicating whether the amount specified is the exact output amount *(true)*.
  * `sqrtPriceLimit`: The limiting square root price `uint256` of the swap. A value of `0` indicates no limit. The limit is only engaged for `exactOutput=false`. If the limit is reached, only part of the input amount will be swapped, and the callback will only require that amount of the swap to be paid.
  * `data`: A callback function `bytes` that swap will call to transfer tokens.
* Returns:
  * `amountIn`: The amount of tokens `uint256` swapped as input.
  * `amountOut`: The amount of tokens `uint256` received as output.

### getBin() <a href="#fn-getbin" id="fn-getbin"></a>

Retrieves the bin information for a given bin ID.

```solidity
function getBin(uint128 binId) external view returns (BinState memory bin);
```

* Parameters:
  * `binId`: The index of the bin `uint128`.
* Returns:
  * A `BinState` structure containing the details of the bin.

### balanceOf() <a href="#fn-balanceof" id="fn-balanceof"></a>

Retrieves the LP token balance for a given tokenId at a specific binId.

```solidity
function balanceOf(uint256 tokenId, uint128 binId) external view returns (uint256 lpToken);
```

* Parameters:
  * `tokenId`: The NFT token ID `uint256`.
  * `binId`: The index of the bin `uint128`.
* Returns:
  * The LP token balance as a `uint256` value.

### tokenAScale() <a href="#fn-tokenascale" id="fn-tokenascale"></a>

Retrieves the tokenA scale value.

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

> `msb` is a flag to indicate whether tokenA has more or less than 18 decimals. Scale is used in conjuction with `Math.toScale/Math.fromScale` functions to convert from token amounts to D18 scale internal pool accounting.

* Returns:
  * The tokenA scale value as a `uint256`.

### tokenBScale() <a href="#fn-tokenbscale" id="fn-tokenbscale"></a>

Retrieves the tokenB scale value.

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

> `msb` is a flag to indicate whether tokenA has more or less than 18 decimals. Scale is used in conjuction with `Math.toScale/Math.fromScale` functions to convert from token amounts to D18 scale internal pool accounting.

* Returns:
  * The tokenB scale value as a `uint256`.


# Factory

This documentation provides an overview of the IFactory.sol. This contract defines the functions and events for creating and managing pools on Maverick AMM.

### **Table of Contents**

* [**Contract Details**](#contract-details)
* [**Events**](#events)
  * [PoolCreated](#event-poolcreated)
  * [SetFactoryProtocolFeeRatio](#event-setfactoryprotocolfeeratio)
  * [SetFactoryOwner](#event-setfactoryowner)
* [**Functions**](#functions)
  * [create()](#fn-create)
  * [lookup()](#fn-lookup)
  * [owner()](#fn-owner)
  * [position()](#fn-position)
  * [protocolFeeRatio()](#fn-protocolfeeratio)
  * [isFactoryPool()](#fn-isfactorypool)

## **Contract Details** <a href="#contract-details" id="contract-details"></a>

* **Name :** *IFactory*
* **Solidity Version :** *^0.8.0*
* *SPDX License-Identifier : GPL-2.0-or-later*
* **`Factory` is Deployed to**
  * Ethereum: [`0xEb6625D65a0553c9dBc64449e56abFe519bd9c9B`](https://etherscan.io/address/0xEb6625D65a0553c9dBc64449e56abFe519bd9c9B)
  * ZKSync Era: [`0x2C1a605f843A2E18b7d7772f0Ce23c236acCF7f5`](https://explorer.zksync.io/address/0x2C1a605f843A2E18b7d7772f0Ce23c236acCF7f5)
* Code: [Github](https://github.com/maverickprotocol/maverick-v1-interfaces/blob/main/contracts/interfaces/IFactory.sol)

## **Events** <a href="#events" id="events"></a>

### PoolCreated <a href="#event-poolcreated" id="event-poolcreated"></a>

Event emitted when a new pool is created.

```solidity
event PoolCreated(
    address poolAddress,
    uint256 fee,
    uint256 tickSpacing,
    int32 activeTick,
    int256 lookback,
    uint64 protocolFeeRatio,
    IERC20 tokenA,
    IERC20 tokenB
);
```

* Parameters :
  * `poolAddress` : The `address` of the created pool
  * `fee` : The rate in `prbmath 60x18` decimal format
  * `tickSpacing` : The bin width represented as `1.0001^tickSpacing`
  * `activeTick` : The initial active tick of the pool
  * `lookback` : The time-weighted average price *(TWAP)* lookback in whole seconds
  * `protocolFeeRatio` : The ratio of the swap fee that is kept for the protocol
  * `tokenA` : The `ERC20` token A used in the pool
  * `tokenB` : The `ERC20` token B used in the pool

### SetFactoryProtocolFeeRatio <a href="#event-setfactoryprotocolfeeratio" id="event-setfactoryprotocolfeeratio"></a>

Event emitted when the protocol fee ratio is updated.

```solidity
event SetFactoryProtocolFeeRatio(uint64 protocolFeeRatio);
```

* Parameters :
  * `protocolFeeRatio` : The new protocol fee ratio

### SetFactoryOwner <a href="#event-setfactoryowner" id="event-setfactoryowner"></a>

Event emitted when the owner of the factory is updated.

```solidity
event SetFactoryOwner(address owner);
```

* Parameters :
  * `owner` : The new owner `address`

## **Functions** <a href="#functions" id="functions"></a>

### create() <a href="#fn-create" id="fn-create"></a>

Creates a new pool.

```solidity
function create(
    uint256 _fee,
    uint256 _tickSpacing,
    int256 _lookback,
    int32 _activeTick,
    IERC20 _tokenA,
    IERC20 _tokenB
) external returns (IPool);
```

* Parameters :
  * `_fee` : The rate in `prbmath 60x18` decimal format
  * `_tickSpacing` : The bin width represented as `1.0001^tickSpacing`
  * `_lookback` : The time-weighted average price (TWAP) lookback in whole seconds
  * `_activeTick` : The initial active tick of the pool
  * `_tokenA` : The ERC20 token A to be used in the pool
  * `_tokenB` : The ERC20 token B to be used in the pool
* Returns :
  * `IPool` : An instance of the `IPool` interface representing the created pool

### lookup() <a href="#fn-lookup" id="fn-lookup"></a>

Looks up an existing pool based on the specified parameters.

```solidity
function lookup(
    uint256 fee,
    uint256 tickSpacing,
    int256 lookback,
    IERC20 tokenA,
    IERC20 tokenB
) external view returns (IPool);
```

* Parameters :
  * `fee` : The rate in `prbmath 60x18` decimal format
  * `tickSpacing` : The bin width represented as `1.0001^tickSpacing`
  * `lookback` : The time-weighted average price *(TWAP)* lookback in whole `seconds`
  * `tokenA` : The `ERC20` token A used in the pool
  * `tokenB` : The `ERC20` token B used in the pool
* Returns :
  * `IPool` : An instance of the `IPool` interface representing the found pool, or a `zero` address if no pool matches the parameters

### owner() <a href="#fn-owner" id="fn-owner"></a>

Retrieves the address of the factory owner.

```solidity
function owner() external view returns (address);
```

* Returns :
  * `address` : The `address` of the factory owner<br>

### position() <a href="#fn-position" id="fn-position"></a>

Retrieves the IPosition interface associated with the factory.

```solidity
function position() external view returns (IPosition);
```

* Returns :
  * `IPosition` : An instance of the `IPosition` interface associated with the factory

### protocolFeeRatio() <a href="#fn-protocolfeeratio" id="fn-protocolfeeratio"></a>

Retrieves the current protocol fee ratio.

```solidity
function protocolFeeRatio() external view returns (uint64);
```

* Returns :
  * The current protocol fee ratio in `uint64`.

### isFactoryPool(IPool pool) <a href="#fn-isfactorypool" id="fn-isfactorypool"></a>

Checks if a pool is owned by the factory.

```solidity
function isFactoryPool(IPool pool) external view returns (bool);
```

* Parameters :
  * `pool` : An instance of the `IPool` interface representing the pool to check.
* Returns :
  * A `boolean` indicating whether the pool is owned by the factory.


# SlimRouter

This documentation provides an overview of the ISlimRouter.sol contract, which defines the functions & events for conducting token swaps & managing token balances. The IRouter inherits this contract.

## **Table of Contents**

* [**Contract Details**](#contract-details)
* [**Structs**](#structs)
  * [ExactInputSingleParams](#struct-exactinputsingleparams)
  * [ExactOutputSingleParams](#struct-exactoutputsingleparams)
* [**Functions**](#functions)
  * [WETH9()](#fn-weth9)
  * [exactInputSingle()](#fn-exactinputsingle)
  * [exactOutputSingle()](#fn-exactoutputsingle)
  * [unwrapWETH9()](#fn-unwrapweth9)
  * [refundETH()](#fn-refundeth)
  * [sweepToken()](#fn-sweeptoken)

## **Contract Details** <a href="#contract-details" id="contract-details"></a>

* **Name :** *ISlimRouter*
* **Solidity Version :** *^0.8.0*
* *SPDX License-Identifier : GPL-2.0-or-later*
* Code: [Github](https://github.com/maverickprotocol/router-v1/blob/main/contracts/interfaces/ISlimRouter.sol)

## **Structs** <a href="#structs" id="structs"></a>

### ExactInputSingleParams <a href="#struct-exactinputsingleparams" id="struct-exactinputsingleparams"></a>

```solidity
struct ExactInputSingleParams {
    address tokenIn;
    address tokenOut;
    IPool pool;
    address recipient;
    uint256 deadline;
    uint256 amountIn;
    uint256 amountOutMinimum;
    uint256 sqrtPriceLimitD18;
}
```

* `tokenIn` : The address of the token to be swapped.
* `tokenOut` : The address of the desired token to receive in the swap.
* `pool` : An instance of the IPool interface representing the pool to perform the swap in.
* `recipient` : The address where the swapped tokens will be sent.
* `deadline` : The deadline timestamp for the swap to be executed before it expires.
* `amountIn` : The amount of tokenIn token to be swapped.
* `amountOutMinimum` : The minimum amount of tokenOut tokens expected to be received from the swap.
* `sqrtPriceLimitD18` : The square root of the price limit for the swap, represented with 18 decimal places.

### ExactOutputSingleParams <a href="#struct-exactoutputsingleparams" id="struct-exactoutputsingleparams"></a>

```solidity
struct ExactOutputSingleParams {
    address tokenIn;
    address tokenOut;
    IPool pool;
    address recipient;
    uint256 deadline;
    uint256 amountOut;
    uint256 amountInMaximum;
}
```

* `tokenIn` : The address of the token to be used as input in the swap.
* `tokenOut` : The address of the token to be received as output in the swap.
* `pool` : An instance of the IPool interface representing the pool to perform the swap in.
* `recipient` : The address where the swapped tokens will be sent.
* `deadline` : The deadline timestamp for the swap to be executed before it expires.
* `amountOut` : The desired amount of tokenOut tokens to be received from the swap.
* `amountInMaximum` : The maximum amount of tokenIn tokens to be used for the swap.

## **Functions** <a href="#functions" id="functions"></a>

### WETH9() <a href="#fn-weth9" id="fn-weth9"></a>

Retrieves the address of the WETH9 token.

```solidity
function WETH9() external view returns (IWETH9);
```

* Returns :
  * `IWETH9` : An instance of the `IWETH9` interface representing the WETH9 token.

### exactInputSingle() <a href="#fn-exactinputsingle" id="fn-exactinputsingle"></a>

Swaps `amountIn` of one token for as much as possible of another token.

```solidity
function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
```

* Parameters :
  * `params` : The parameters necessary for the swap, encoded as `ExactInputSingleParams` structure in calldata.
* Returns :
  * `amountOut` : The amount of the received token `uint256`.

### exactOutputSingle() <a href="#fn-exactoutputsingle" id="fn-exactoutputsingle"></a>

Swaps as little as possible of one token for `amountOut` of another token.

```solidity
function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);
```

* Parameters :
  * `params` : The parameters necessary for the swap, encoded as `ExactOutputSingleParams` structure in calldata.
* Returns:
  * `amountIn` : The amount of the input token `uint256`.

### unwrapWETH9() <a href="#fn-unwrapweth9" id="fn-unwrapweth9"></a>

Unwraps the contract's `WETH9` balance and sends it to the specified recipient as `ETH`.

```solidity
function unwrapWETH9(uint256 amountMinimum, address recipient) external payable;
```

* Parameters:
  * `amountMinimum` : The `minimum amount` of `WETH9` to unwrap.
  * `recipient` : The `address` receiving ETH.

### refundETH() <a href="#fn-refundeth" id="fn-refundeth"></a>

Refunds any `ETH` balance held by this contract to the `msg.sender`.

```solidity
function refundETH() external payable;
```

### sweepToken() <a href="#fn-sweeptoken" id="fn-sweeptoken"></a>

Transfers the full amount of a specified token held by this contract to the recipient.

```solidity
function sweepToken(IERC20 token, uint256 amountMinimum, address recipient) external payable;
```

* Parameters:
  * `token` : The contract `address` of the token to be transferred.
  * `amountMinimum` : The `minimum amount` of token `uint256` required for the transfer.
  * `recipient` : The destination `address` of the token.


# Maverick V2

This section collects technical information relevant to Maverick V2.


# V2 Contracts


# Maverick V2 Common Contracts


# base

* [IMulticall](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/base/imulticall)
* [IPayableMulticall](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/base/ipayablemulticall)
* [Multicall](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/base/multicall)
* [PayableMulticall](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/base/payablemulticall)


# IMulticall

### Functions <a href="#functions" id="functions"></a>

#### multicall <a href="#multicall" id="multicall"></a>

```solidity
function multicall(bytes[] calldata data) external returns (bytes[] memory results);
```


# IPayableMulticall

### Functions <a href="#functions" id="functions"></a>

#### multicall <a href="#multicall" id="multicall"></a>

```solidity
function multicall(bytes[] calldata data) external payable returns (bytes[] memory results);
```


# Multicall

**Inherits:** [IMulticall](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/base/imulticall)

### Functions <a href="#functions" id="functions"></a>

#### multicall <a href="#multicall-1" id="multicall-1"></a>

This function allows multiple calls to different contract functions in a single transaction.

```solidity
function multicall(bytes[] calldata data) external returns (bytes[] memory results);
```

**Parameters**

| Name   | Type      | Description                             |
| ------ | --------- | --------------------------------------- |
| `data` | `bytes[]` | An array of encoded function call data. |

**Returns**

| Name      | Type      | Description                                    |
| --------- | --------- | ---------------------------------------------- |
| `results` | `bytes[]` | An array of the results of the function calls. |


# PayableMulticall

**Inherits:** [IPayableMulticall](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/base/ipayablemulticall)

### Functions <a href="#functions" id="functions"></a>

#### multicall <a href="#multicall" id="multicall"></a>

This function allows multiple calls to different contract functions in a single transaction.

```solidity
function multicall(bytes[] calldata data) external payable returns (bytes[] memory results);
```

**Parameters**

| Name   | Type      | Description                             |
| ------ | --------- | --------------------------------------- |
| `data` | `bytes[]` | An array of encoded function call data. |

**Returns**

| Name      | Type      | Description                                    |
| --------- | --------- | ---------------------------------------------- |
| `results` | `bytes[]` | An array of the results of the function calls. |


# interfaces

* [IMaverickV2AddLiquidityCallback](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/interfaces/imaverickv2addliquiditycallback)
* [IMaverickV2Factory](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/interfaces/imaverickv2factory)
* [IMaverickV2FactoryAdmin](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/interfaces/imaverickv2factoryadmin)
* [IMaverickV2FlashLoanCallback](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/interfaces/imaverickv2flashloancallback)
* [IMaverickV2Pool](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/interfaces/imaverickv2pool)
* [IMaverickV2PoolAdmin](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/interfaces/imaverickv2pooladmin)
* [IMaverickV2SwapCallback](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/interfaces/imaverickv2swapcallback)


# IMaverickV2AddLiquidityCallback

### Functions <a href="#functions" id="functions"></a>

#### maverickV2AddLiquidityCallback <a href="#maverickv2addliquiditycallback" id="maverickv2addliquiditycallback"></a>

```solidity
function maverickV2AddLiquidityCallback(
    IERC20 tokenA,
    IERC20 tokenB,
    uint256 amountA,
    uint256 amountB,
    bytes calldata data
) external;
```

<br>


# IMaverickV2Factory

### Functions <a href="#functions" id="functions"></a>

#### deployParameters <a href="#deployparameters" id="deployparameters"></a>

Called by deployer library to initialize a pool.

```solidity
function deployParameters()
    external
    view
    returns (
        uint64 feeAIn,
        uint64 feeBIn,
        uint32 lookback,
        int32 activeTick,
        uint64 tokenAScale,
        uint64 tokenBScale,
        IERC20 tokenA,
        IERC20 tokenB,
        uint16 tickSpacing,
        uint8 kinds,
        address accessor
    );
```

#### create <a href="#create" id="create"></a>

Create a new MaverickV2Pool with symmetric swap fees.

```solidity
function create(
    uint64 fee,
    uint16 tickSpacing,
    uint32 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    int32 activeTick,
    uint8 kinds
) external returns (IMaverickV2Pool);
```

**Parameters**

| Name          | Type     | Description                                                                                                                                                        |
| ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `fee`         | `uint64` | Fraction of the pool swap amount that is retained as an LP in D18 scale.                                                                                           |
| `tickSpacing` | `uint16` | Tick spacing of pool where 1.0001^tickSpacing is the bin width.                                                                                                    |
| `lookback`    | `uint32` | Pool lookback in second in D2 scale.                                                                                                                               |
| `tokenA`      | `IERC20` | Address of tokenA.                                                                                                                                                 |
| `tokenB`      | `IERC20` | Address of tokenB.                                                                                                                                                 |
| `activeTick`  | `int32`  | Tick position that contains the active bins.                                                                                                                       |
| `kinds`       | `uint8`  | 1-15 number to represent the active kinds 0b0001 = static; 0b0010 = right; 0b0100 = left; 0b1000 = both. E.g. a pool with all 4 modes will have kinds = b1111 = 15 |

#### create <a href="#create-1" id="create-1"></a>

Create a new MaverickV2Pool.

```solidity
function create(
    uint64 feeAIn,
    uint64 feeBIn,
    uint16 tickSpacing,
    uint32 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    int32 activeTick,
    uint8 kinds
) external returns (IMaverickV2Pool);
```

**Parameters**

| Name          | Type     | Description                                                                                                                                                        |
| ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `feeAIn`      | `uint64` | Fraction of the pool swap amount for tokenA-input swaps that is retained as an LP in D18 scale.                                                                    |
| `feeBIn`      | `uint64` | Fraction of the pool swap amount for tokenB-input swaps that is retained as an LP in D18 scale.                                                                    |
| `tickSpacing` | `uint16` | Tick spacing of pool where 1.0001^tickSpacing is the bin width.                                                                                                    |
| `lookback`    | `uint32` | Pool lookback in second in D2 scale.                                                                                                                               |
| `tokenA`      | `IERC20` | Address of tokenA.                                                                                                                                                 |
| `tokenB`      | `IERC20` | Address of tokenB.                                                                                                                                                 |
| `activeTick`  | `int32`  | Tick position that contains the active bins.                                                                                                                       |
| `kinds`       | `uint8`  | 1-15 number to represent the active kinds 0b0001 = static; 0b0010 = right; 0b0100 = left; 0b1000 = both. e.g. a pool with all 4 modes will have kinds = b1111 = 15 |

#### createPermissioned <a href="#createpermissioned" id="createpermissioned"></a>

Create a new MaverickV2PoolPermissioned with symmetric swap fees.

```solidity
function createPermissioned(
    uint64 fee,
    uint16 tickSpacing,
    uint32 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    int32 activeTick,
    uint8 kinds,
    address accessor
) external returns (IMaverickV2Pool);
```

**Parameters**

| Name          | Type      | Description                                                                                                                                                        |
| ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `fee`         | `uint64`  | Fraction of the pool swap amount that is retained as an LP in D18 scale.                                                                                           |
| `tickSpacing` | `uint16`  | Tick spacing of pool where 1.0001^tickSpacing is the bin width.                                                                                                    |
| `lookback`    | `uint32`  | Pool lookback in second in D2 scale.                                                                                                                               |
| `tokenA`      | `IERC20`  | Address of tokenA.                                                                                                                                                 |
| `tokenB`      | `IERC20`  | Address of tokenB.                                                                                                                                                 |
| `activeTick`  | `int32`   | Tick position that contains the active bins.                                                                                                                       |
| `kinds`       | `uint8`   | 1-15 number to represent the active kinds 0b0001 = static; 0b0010 = right; 0b0100 = left; 0b1000 = both. E.g. a pool with all 4 modes will have kinds = b1111 = 15 |
| `accessor`    | `address` | Only address that can access the pool's public write functions.                                                                                                    |

#### createPermissioned <a href="#createpermissioned-1" id="createpermissioned-1"></a>

Create a new MaverickV2PoolPermissioned.

```solidity
function createPermissioned(
    uint64 feeAIn,
    uint64 feeBIn,
    uint16 tickSpacing,
    uint32 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    int32 activeTick,
    uint8 kinds,
    address accessor
) external returns (IMaverickV2Pool);
```

**Parameters**

| Name          | Type      | Description                                                                                                                                                        |
| ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `feeAIn`      | `uint64`  | Fraction of the pool swap amount for tokenA-input swaps that is retained as an LP in D18 scale.                                                                    |
| `feeBIn`      | `uint64`  | Fraction of the pool swap amount for tokenB-input swaps that is retained as an LP in D18 scale.                                                                    |
| `tickSpacing` | `uint16`  | Tick spacing of pool where 1.0001^tickSpacing is the bin width.                                                                                                    |
| `lookback`    | `uint32`  | Pool lookback in second in D2 scale.                                                                                                                               |
| `tokenA`      | `IERC20`  | Address of tokenA.                                                                                                                                                 |
| `tokenB`      | `IERC20`  | Address of tokenB.                                                                                                                                                 |
| `activeTick`  | `int32`   | Tick position that contains the active bins.                                                                                                                       |
| `kinds`       | `uint8`   | 1-15 number to represent the active kinds 0b0001 = static; 0b0010 = right; 0b0100 = left; 0b1000 = both. E.g. a pool with all 4 modes will have kinds = b1111 = 15 |
| `accessor`    | `address` | only address that can access the pool's public write functions.                                                                                                    |

#### updateProtocolFeeRatioForPool <a href="#updateprotocolfeeratioforpool" id="updateprotocolfeeratioforpool"></a>

Update the protocol fee ratio for a pool. Can be called permissionlessly allowing any user to sync the pool protocol fee value with the factory protocol fee value.

```solidity
function updateProtocolFeeRatioForPool(IMaverickV2Pool pool) external;
```

**Parameters**

| Name   | Type              | Description                   |
| ------ | ----------------- | ----------------------------- |
| `pool` | `IMaverickV2Pool` | The pool for which to update. |

#### updateProtocolLendingFeeRateForPool <a href="#updateprotocollendingfeerateforpool" id="updateprotocollendingfeerateforpool"></a>

Update the protocol lending fee rate for a pool. Can be called permissionlessly allowing any user to sync the pool protocol lending fee rate value with the factory value.

```solidity
function updateProtocolLendingFeeRateForPool(IMaverickV2Pool pool) external;
```

**Parameters**

| Name   | Type              | Description                   |
| ------ | ----------------- | ----------------------------- |
| `pool` | `IMaverickV2Pool` | The pool for which to update. |

#### claimProtocolFeeForPool <a href="#claimprotocolfeeforpool" id="claimprotocolfeeforpool"></a>

Claim protocol fee for a pool and transfer it to the protocolFeeReceiver.

```solidity
function claimProtocolFeeForPool(IMaverickV2Pool pool, bool isTokenA) external;
```

**Parameters**

| Name       | Type              | Description                                                                      |
| ---------- | ----------------- | -------------------------------------------------------------------------------- |
| `pool`     | `IMaverickV2Pool` | The pool from which to claim the protocol fee.                                   |
| `isTokenA` | `bool`            | A boolean indicating whether tokenA (true) or tokenB (false) is being collected. |

#### claimProtocolFeeForPool <a href="#claimprotocolfeeforpool-1" id="claimprotocolfeeforpool-1"></a>

Claim protocol fee for a pool and transfer it to the protocolFeeReceiver.

```solidity
function claimProtocolFeeForPool(IMaverickV2Pool pool) external;
```

**Parameters**

| Name   | Type              | Description                                    |
| ------ | ----------------- | ---------------------------------------------- |
| `pool` | `IMaverickV2Pool` | The pool from which to claim the protocol fee. |

#### isFactoryPool <a href="#isfactorypool" id="isfactorypool"></a>

Bool indicating whether the pool was deployed from this factory.

```solidity
function isFactoryPool(IMaverickV2Pool pool) external view returns (bool);
```

#### protocolFeeReceiver <a href="#protocolfeereceiver" id="protocolfeereceiver"></a>

Address that receives the protocol fee when users call `claimProtocolFeeForPool`.

```solidity
function protocolFeeReceiver() external view returns (address);
```

#### isFactoryPoolPermissioned <a href="#isfactorypoolpermissioned" id="isfactorypoolpermissioned"></a>

Bool indicating whether the pool was deployed from this factory.

```solidity
function isFactoryPoolPermissioned(IMaverickV2Pool pool) external view returns (bool);
```

#### lookupPermissioned <a href="#lookuppermissioned" id="lookuppermissioned"></a>

Lookup a pool for given parameters.

```solidity
function lookupPermissioned(
    uint256 feeAIn,
    uint256 feeBIn,
    uint256 tickSpacing,
    uint256 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    uint8 kinds,
    address accessor
) external view returns (IMaverickV2Pool);
```

#### lookupPermissioned <a href="#lookuppermissioned-1" id="lookuppermissioned-1"></a>

Lookup a pool for given parameters.

```solidity
function lookupPermissioned(IERC20 _tokenA, IERC20 _tokenB, address accessor, uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2Pool[] memory pools);
```

#### lookupPermissioned <a href="#lookuppermissioned-2" id="lookuppermissioned-2"></a>

Lookup a pool for given parameters.

```solidity
function lookupPermissioned(uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2Pool[] memory pools);
```

#### lookup <a href="#lookup" id="lookup"></a>

Lookup a pool for given parameters.

```solidity
function lookup(
    uint256 feeAIn,
    uint256 feeBIn,
    uint256 tickSpacing,
    uint256 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    uint8 kinds
) external view returns (IMaverickV2Pool);
```

#### lookup <a href="#lookup-1" id="lookup-1"></a>

Lookup a pool for given parameters.

```solidity
function lookup(IERC20 _tokenA, IERC20 _tokenB, uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2Pool[] memory pools);
```

#### lookup <a href="#lookup-2" id="lookup-2"></a>

Lookup a pool for given parameters.

```solidity
function lookup(uint256 startIndex, uint256 endIndex) external view returns (IMaverickV2Pool[] memory pools);
```

#### owner <a href="#owner" id="owner"></a>

Get the current factory owner.

```solidity
function owner() external view returns (address);
```

#### protocolFeeRatioD3 <a href="#protocolfeeratiod3" id="protocolfeeratiod3"></a>

Proportion of protocol fee to collect on each swap. Value is in 3-decimal format with a maximum value of 0.25e3.

```solidity
function protocolFeeRatioD3() external view returns (uint8);
```

#### protocolLendingFeeRateD18 <a href="#protocollendingfeerated18" id="protocollendingfeerated18"></a>

Fee rate charged by the protocol for flashloans. Value is in 18-decimal format with a maximum value of 0.02e18.

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

#### poolAddress <a href="#pooladdress" id="pooladdress"></a>

Address of a permissionless pool.

```solidity
function poolAddress(
    uint256 feeAIn,
    uint256 feeBIn,
    uint256 tickSpacing,
    uint256 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    uint8 kinds
) external view returns (IMaverickV2Pool pool);
```

#### poolAddress <a href="#pooladdress-1" id="pooladdress-1"></a>

Address of a permissioned pool.

```solidity
function poolAddress(
    uint256 feeAIn,
    uint256 feeBIn,
    uint256 tickSpacing,
    uint256 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    uint8 kinds,
    address accessor
) external view returns (IMaverickV2Pool pool);
```

### Events <a href="#events" id="events"></a>

#### PoolCreated <a href="#poolcreated" id="poolcreated"></a>

```solidity
event PoolCreated(
    IMaverickV2Pool poolAddress,
    uint8 protocolFeeRatio,
    uint256 feeAIn,
    uint256 feeBIn,
    uint256 tickSpacing,
    uint256 lookback,
    int32 activeTick,
    IERC20 tokenA,
    IERC20 tokenB,
    uint8 kinds,
    address accessor
);
```

#### SetFactoryProtocolFeeRatio <a href="#setfactoryprotocolfeeratio" id="setfactoryprotocolfeeratio"></a>

```solidity
event SetFactoryProtocolFeeRatio(uint8 protocolFeeRatioD3);
```

#### SetFactoryProtocolLendingFeeRate <a href="#setfactoryprotocollendingfeerate" id="setfactoryprotocollendingfeerate"></a>

```solidity
event SetFactoryProtocolLendingFeeRate(uint256 lendingFeeRateD18);
```

#### SetFactoryProtocolFeeReceiver <a href="#setfactoryprotocolfeereceiver" id="setfactoryprotocolfeereceiver"></a>

```solidity
event SetFactoryProtocolFeeReceiver(address receiver);
```

### Errors <a href="#errors" id="errors"></a>

#### FactoryInvalidProtocolFeeRatio <a href="#factoryinvalidprotocolfeeratio" id="factoryinvalidprotocolfeeratio"></a>

```solidity
error FactoryInvalidProtocolFeeRatio(uint8 protocolFeeRatioD3);
```

#### FactoryInvalidLendingFeeRate <a href="#factoryinvalidlendingfeerate" id="factoryinvalidlendingfeerate"></a>

```solidity
error FactoryInvalidLendingFeeRate(uint256 protocolLendingFeeRateD18);
```

#### FactoryProtocolFeeOnRenounce <a href="#factoryprotocolfeeonrenounce" id="factoryprotocolfeeonrenounce"></a>

```solidity
error FactoryProtocolFeeOnRenounce(uint8 protocolFeeRatioD3);
```

#### FactorAlreadyInitialized <a href="#factoralreadyinitialized" id="factoralreadyinitialized"></a>

```solidity
error FactorAlreadyInitialized();
```

#### FactorNotInitialized <a href="#factornotinitialized" id="factornotinitialized"></a>

```solidity
error FactorNotInitialized();
```

#### FactoryInvalidTokenOrder <a href="#factoryinvalidtokenorder" id="factoryinvalidtokenorder"></a>

```solidity
error FactoryInvalidTokenOrder(IERC20 _tokenA, IERC20 _tokenB);
```

#### FactoryInvalidFee <a href="#factoryinvalidfee" id="factoryinvalidfee"></a>

```solidity
error FactoryInvalidFee();
```

#### FactoryInvalidKinds <a href="#factoryinvalidkinds" id="factoryinvalidkinds"></a>

```solidity
error FactoryInvalidKinds(uint8 kinds);
```

#### FactoryInvalidTickSpacing <a href="#factoryinvalidtickspacing" id="factoryinvalidtickspacing"></a>

```solidity
error FactoryInvalidTickSpacing(uint256 tickSpacing);
```

#### FactoryInvalidLookback <a href="#factoryinvalidlookback" id="factoryinvalidlookback"></a>

```solidity
error FactoryInvalidLookback(uint256 lookback);
```

#### FactoryInvalidTokenDecimals <a href="#factoryinvalidtokendecimals" id="factoryinvalidtokendecimals"></a>

```solidity
error FactoryInvalidTokenDecimals(uint8 decimalsA, uint8 decimalsB);
```

#### FactoryPoolAlreadyExists <a href="#factorypoolalreadyexists" id="factorypoolalreadyexists"></a>

```solidity
error FactoryPoolAlreadyExists(
    uint256 feeAIn,
    uint256 feeBIn,
    uint256 tickSpacing,
    uint256 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    uint8 kinds,
    address accessor
);
```

#### FactoryAccessorMustBeNonZero <a href="#factoryaccessormustbenonzero" id="factoryaccessormustbenonzero"></a>

```solidity
error FactoryAccessorMustBeNonZero();
```

### Structs <a href="#structs" id="structs"></a>

#### DeployParameters <a href="#deployparameters-1" id="deployparameters-1"></a>

```solidity
struct DeployParameters {
    uint64 feeAIn;
    uint64 feeBIn;
    uint32 lookback;
    int32 activeTick;
    uint64 tokenAScale;
    uint64 tokenBScale;
    IERC20 tokenA;
    IERC20 tokenB;
    uint16 tickSpacing;
    uint8 kinds;
    address accessor;
}
```

<br>


# IMaverickV2FactoryAdmin

### Functions <a href="#functions" id="functions"></a>

#### setProtocolFeeRatio <a href="#setprotocolfeeratio" id="setprotocolfeeratio"></a>

Set the protocol fee ratio.

```solidity
function setProtocolFeeRatio(uint8 _protocolFeeRatioD3) external;
```

**Parameters**

| Name                  | Type    | Description                                           |
| --------------------- | ------- | ----------------------------------------------------- |
| `_protocolFeeRatioD3` | `uint8` | The new protocol fee ratio to set in 3-decimal units. |

#### setProtocolLendingFeeRate <a href="#setprotocollendingfeerate" id="setprotocollendingfeerate"></a>

Set the protocol lending fee rate.

```solidity
function setProtocolLendingFeeRate(uint256 _protocolLendingFeeRateD18) external;
```

**Parameters**

| Name                         | Type      | Description                                                   |
| ---------------------------- | --------- | ------------------------------------------------------------- |
| `_protocolLendingFeeRateD18` | `uint256` | The new protocol lending fee rate to set in 18-decimal units. |

#### setProtocolFeeReceiver <a href="#setprotocolfeereceiver" id="setprotocolfeereceiver"></a>

Set the protocol fee receiver address. If protocol fee is non-zero, user will be able to permissionlessly push protocol fee from a given pool to this address.

```solidity
function setProtocolFeeReceiver(address receiver) external;
```

#### renounceOwnership <a href="#renounceownership" id="renounceownership"></a>

Renounce ownership of the contract.

```solidity
function renounceOwnership() external;
```

#### transferOwnership <a href="#transferownership" id="transferownership"></a>

Transfer ownership of the contract to a new owner.

```solidity
function transferOwnership(address newOwner) external;
```

**Parameters**

| Name       | Type      | Description                   |
| ---------- | --------- | ----------------------------- |
| `newOwner` | `address` | The address of the new owner. |

<br>


# IMaverickV2FlashLoanCallback

### Functions <a href="#functions" id="functions"></a>

#### maverickV2FlashLoanCallback <a href="#maverickv2flashloancallback" id="maverickv2flashloancallback"></a>

```solidity
function maverickV2FlashLoanCallback(
    IERC20 tokenA,
    IERC20 tokenB,
    uint256 amountALent,
    uint256 amountAPayback,
    uint256 amountBLent,
    uint256 amountBPayback,
    bytes calldata data
) external;
```

<br>


# IMaverickV2Pool

### Functions <a href="#functions" id="functions"></a>

#### kinds <a href="#kinds" id="kinds"></a>

1-15 number to represent the active kinds. 0b0001 = static; 0b0010 = right; 0b0100 = left; 0b1000 = both; E.g. a pool with all 4 modes will have kinds = b1111 = 15

```solidity
function kinds() external view returns (uint8);
```

#### fee <a href="#fee" id="fee"></a>

Pool swap fee for the given direction (A-in or B-in swap) in 18-decimal format. E.g. 0.01e18 is a 1% swap fee.

```solidity
function fee(bool tokenAIn) external view returns (uint256);
```

#### tickSpacing <a href="#tickspacing" id="tickspacing"></a>

TickSpacing of pool where 1.0001^tickSpacing is the bin width.

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

#### lookback <a href="#lookback" id="lookback"></a>

Lookback period of pool in seconds.

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

#### accessor <a href="#accessor" id="accessor"></a>

Address of Pool accessor. This is Zero address for permissionless pools.

```solidity
function accessor() external view returns (address);
```

#### tokenA <a href="#tokena" id="tokena"></a>

Pool tokenA. Address of tokenA is such that tokenA < tokenB.

```solidity
function tokenA() external view returns (IERC20);
```

#### tokenB <a href="#tokenb" id="tokenb"></a>

Pool tokenB.

```solidity
function tokenB() external view returns (IERC20);
```

#### factory <a href="#factory" id="factory"></a>

Deploying factory of the pool and also contract that has ability to set and collect protocol fees for the pool.

```solidity
function factory() external view returns (IMaverickV2Factory);
```

#### tokenAScale <a href="#tokenascale" id="tokenascale"></a>

Most significant bit of scale value is a flag to indicate whether tokenA has more or less than 18 decimals. Scale is used in conjuction with Math.toScale/Math.fromScale functions to convert from token amounts to D18 scale internal pool accounting.

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

#### tokenBScale <a href="#tokenbscale" id="tokenbscale"></a>

Most significant bit of scale value is a flag to indicate whether tokenA has more or less than 18 decimals. Scale is used in conjuction with Math.toScale/Math.fromScale functions to convert from token amounts to D18 scale internal pool accounting.

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

#### binIdByTickKind <a href="#binidbytickkind" id="binidbytickkind"></a>

ID of bin at input tick position and kind.

```solidity
function binIdByTickKind(int32 tick, uint256 kind) external view returns (uint32);
```

#### protocolFeeA <a href="#protocolfeea" id="protocolfeea"></a>

Accumulated tokenA protocol fee.

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

#### protocolFeeB <a href="#protocolfeeb" id="protocolfeeb"></a>

Accumulated tokenB protocol fee.

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

#### lendingFeeRateD18 <a href="#lendingfeerated18" id="lendingfeerated18"></a>

Lending fee rate on flash loans.

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

#### getCurrentTwa <a href="#getcurrenttwa" id="getcurrenttwa"></a>

External function to get the current time-weighted average price.

```solidity
function getCurrentTwa() external view returns (int256);
```

#### getState <a href="#getstate" id="getstate"></a>

External function to get the state of the pool.

```solidity
function getState() external view returns (State memory);
```

#### getBin <a href="#getbin" id="getbin"></a>

Return state of Bin at input binId.

```solidity
function getBin(uint32 binId) external view returns (BinState memory bin);
```

#### getTick <a href="#gettick" id="gettick"></a>

Return state of Tick at input tick position.

```solidity
function getTick(int32 tick) external view returns (TickState memory tickState);
```

#### balanceOf <a href="#balanceof" id="balanceof"></a>

Retrieves the balance of a user within a bin.

```solidity
function balanceOf(address user, uint256 subaccount, uint32 binId) external view returns (uint128 lpToken);
```

**Parameters**

| Name         | Type      | Description                  |
| ------------ | --------- | ---------------------------- |
| `user`       | `address` | The user's address.          |
| `subaccount` | `uint256` | The subaccount for the user. |
| `binId`      | `uint32`  | The ID of the bin.           |

#### addLiquidity <a href="#addliquidity" id="addliquidity"></a>

Add liquidity to a pool. This function allows users to deposit tokens into a liquidity pool.

This function will call `maverickV2AddLiquidityCallback` on the calling contract to collect the tokenA/tokenB payment.

```solidity
function addLiquidity(address recipient, uint256 subaccount, AddLiquidityParams calldata params, bytes calldata data)
    external
    returns (uint256 tokenAAmount, uint256 tokenBAmount, uint32[] memory binIds);
```

**Parameters**

| Name         | Type                 | Description                                                                              |
| ------------ | -------------------- | ---------------------------------------------------------------------------------------- |
| `recipient`  | `address`            | The account that will receive credit for the added liquidity.                            |
| `subaccount` | `uint256`            | The account that will receive credit for the added liquidity.                            |
| `params`     | `AddLiquidityParams` | Parameters containing the details for adding liquidity, such as token types and amounts. |
| `data`       | `bytes`              | Bytes information that gets passed to the callback.                                      |

**Returns**

| Name           | Type       | Description                                        |
| -------------- | ---------- | -------------------------------------------------- |
| `tokenAAmount` | `uint256`  | The amount of token A added to the pool.           |
| `tokenBAmount` | `uint256`  | The amount of token B added to the pool.           |
| `binIds`       | `uint32[]` | An array of bin IDs where the liquidity is stored. |

#### removeLiquidity <a href="#removeliquidity" id="removeliquidity"></a>

Removes liquidity from the pool.

Liquidity can only be removed from a bin that is either unmerged or has a mergeId of an unmerged bin. If a bin is merged more than one level deep, it must be migrated up the merge stack to the root bin before liquidity removal.

```solidity
function removeLiquidity(address recipient, uint256 subaccount, RemoveLiquidityParams calldata params)
    external
    returns (uint256 tokenAOut, uint256 tokenBOut);
```

**Parameters**

| Name         | Type                    | Description                            |
| ------------ | ----------------------- | -------------------------------------- |
| `recipient`  | `address`               | The address to receive the tokens.     |
| `subaccount` | `uint256`               | The subaccount for the recipient.      |
| `params`     | `RemoveLiquidityParams` | The parameters for removing liquidity. |

**Returns**

| Name        | Type      | Description                     |
| ----------- | --------- | ------------------------------- |
| `tokenAOut` | `uint256` | The amount of token A received. |
| `tokenBOut` | `uint256` | The amount of token B received. |

#### migrateBinUpStack <a href="#migratebinupstack" id="migratebinupstack"></a>

Migrate bins up the linked list of merged bins so that its mergeId is the currrent active bin.

Liquidity can only be removed from a bin that is either unmerged or has a mergeId of an unmerged bin. If a bin is merged more than one level deep, it must be migrated up the merge stack to the root bin before liquidity removal.

```solidity
function migrateBinUpStack(uint32 binId, uint32 maxRecursion) external;
```

**Parameters**

| Name           | Type     | Description                                    |
| -------------- | -------- | ---------------------------------------------- |
| `binId`        | `uint32` | The ID of the bin to migrate.                  |
| `maxRecursion` | `uint32` | The maximum recursion depth for the migration. |

#### swap <a href="#swap" id="swap"></a>

Swap tokenA/tokenB assets in the pool. The swap user has two options for funding their swap.

* The user can push the input token amount to the pool before calling the swap function. In order to avoid having the pool call the callback, the user should pass a zero-length `data` bytes object with the swap call.
* The user can send the input token amount to the pool when the pool calls the `maverickV2SwapCallback` function on the calling contract. That callback has input parameters that specify the token address of the input token, the input and output amounts, and the bytes data sent to the swap function.

If the users elects to do a callback-based swap, the output assets will be sent before the callback is called, allowing the user to execute flash swaps. However, the pool does have reentrancy protection, so a swapper will not be able to interact with the same pool again while they are in the callback function.

```solidity
function swap(address recipient, SwapParams memory params, bytes calldata data)
    external
    returns (uint256 amountIn, uint256 amountOut);
```

**Parameters**

| Name        | Type         | Description                                         |
| ----------- | ------------ | --------------------------------------------------- |
| `recipient` | `address`    | The address to receive the output tokens.           |
| `params`    | `SwapParams` | Parameters containing the details of the swap       |
| `data`      | `bytes`      | Bytes information that gets passed to the callback. |

#### flashLoan <a href="#flashloan" id="flashloan"></a>

Loan tokenA/tokenB assets from the pool to recipient. The fee rate of a loan is determined by `lendingFeeRateD18`, which is set at the protocol level by the factory. This function calls `maverickV2FlashLoanCallback` on the calling contract. At the end of the callback, the caller must pay back the loan with fee (if there is a fee).

```solidity
function flashLoan(address recipient, uint256 amountA, uint256 amountB, bytes calldata data)
    external
    returns (uint128 lendingFeeA, uint128 lendingFeeB);
```

**Parameters**

| Name        | Type      | Description                                         |
| ----------- | --------- | --------------------------------------------------- |
| `recipient` | `address` | The address to receive the loaned tokens.           |
| `amountA`   | `uint256` |                                                     |
| `amountB`   | `uint256` | Loan amount of tokenA sent to recipient.            |
| `data`      | `bytes`   | Bytes information that gets passed to the callback. |

#### setFee <a href="#setfee" id="setfee"></a>

Sets fee for permissioned pools. May only be called by the accessor.

```solidity
function setFee(uint256 newFeeAIn, uint256 newFeeBIn) external;
```

### Events <a href="#events" id="events"></a>

#### PoolSwap <a href="#poolswap" id="poolswap"></a>

```solidity
event PoolSwap(address sender, address recipient, SwapParams params, uint256 amountIn, uint256 amountOut);
```

#### PoolAddLiquidity <a href="#pooladdliquidity" id="pooladdliquidity"></a>

```solidity
event PoolAddLiquidity(
    address sender,
    address recipient,
    uint256 subaccount,
    AddLiquidityParams params,
    uint256 tokenAAmount,
    uint256 tokenBAmount,
    uint32[] binIds
);
```

#### PoolMigrateBinsUpStack <a href="#poolmigratebinsupstack" id="poolmigratebinsupstack"></a>

```solidity
event PoolMigrateBinsUpStack(address sender, uint32 binId, uint32 maxRecursion);
```

#### PoolRemoveLiquidity <a href="#poolremoveliquidity" id="poolremoveliquidity"></a>

```solidity
event PoolRemoveLiquidity(
    address sender,
    address recipient,
    uint256 subaccount,
    RemoveLiquidityParams params,
    uint256 tokenAOut,
    uint256 tokenBOut
);
```

#### PoolSetVariableFee <a href="#poolsetvariablefee" id="poolsetvariablefee"></a>

```solidity
event PoolSetVariableFee(uint256 newFeeAIn, uint256 newFeeBIn);
```

### Errors <a href="#errors" id="errors"></a>

#### PoolZeroLiquidityAdded <a href="#poolzeroliquidityadded" id="poolzeroliquidityadded"></a>

```solidity
error PoolZeroLiquidityAdded();
```

#### PoolMinimumLiquidityNotMet <a href="#poolminimumliquiditynotmet" id="poolminimumliquiditynotmet"></a>

```solidity
error PoolMinimumLiquidityNotMet();
```

#### PoolLocked <a href="#poollocked" id="poollocked"></a>

```solidity
error PoolLocked();
```

#### PoolInvalidInput <a href="#poolinvalidinput" id="poolinvalidinput"></a>

```solidity
error PoolInvalidInput();
```

#### PoolInsufficientBalance <a href="#poolinsufficientbalance" id="poolinsufficientbalance"></a>

```solidity
error PoolInsufficientBalance(uint256 deltaLpAmount, uint256 accountBalance);
```

#### PoolReservesExceedMaximum <a href="#poolreservesexceedmaximum" id="poolreservesexceedmaximum"></a>

```solidity
error PoolReservesExceedMaximum(uint256 amount);
```

#### PoolValueExceedsBits <a href="#poolvalueexceedsbits" id="poolvalueexceedsbits"></a>

```solidity
error PoolValueExceedsBits(uint256 amount, uint256 bits);
```

#### PoolTickMaxExceeded <a href="#pooltickmaxexceeded" id="pooltickmaxexceeded"></a>

```solidity
error PoolTickMaxExceeded(uint256 tick);
```

#### PoolMigrateBinFirst <a href="#poolmigratebinfirst" id="poolmigratebinfirst"></a>

```solidity
error PoolMigrateBinFirst();
```

#### PoolCurrentTickBeyondSwapLimit <a href="#poolcurrenttickbeyondswaplimit" id="poolcurrenttickbeyondswaplimit"></a>

```solidity
error PoolCurrentTickBeyondSwapLimit(int32 startingTick);
```

#### PoolSenderNotAccessor <a href="#poolsendernotaccessor" id="poolsendernotaccessor"></a>

```solidity
error PoolSenderNotAccessor(address sender_, address accessor);
```

#### PoolSenderNotFactory <a href="#poolsendernotfactory" id="poolsendernotfactory"></a>

```solidity
error PoolSenderNotFactory(address sender_, address accessor);
```

#### PoolFunctionNotImplemented <a href="#poolfunctionnotimplemented" id="poolfunctionnotimplemented"></a>

```solidity
error PoolFunctionNotImplemented();
```

#### PoolTokenNotSolvent <a href="#pooltokennotsolvent" id="pooltokennotsolvent"></a>

```solidity
error PoolTokenNotSolvent(uint256 internalReserve, uint256 tokenBalance, IERC20 token);
```

### Structs <a href="#structs" id="structs"></a>

#### TickState <a href="#tickstate" id="tickstate"></a>

Tick state parameters.

```solidity
struct TickState {
    uint128 reserveA;
    uint128 reserveB;
    uint128 totalSupply;
    uint32[4] binIdsByTick;
}
```

#### TickData <a href="#tickdata" id="tickdata"></a>

Tick data parameters.

```solidity
struct TickData {
    uint256 currentReserveA;
    uint256 currentReserveB;
    uint256 currentLiquidity;
}
```

**Properties**

| Name               | Type      | Description                 |
| ------------------ | --------- | --------------------------- |
| `currentReserveA`  | `uint256` | Current reserve of token A. |
| `currentReserveB`  | `uint256` | Current reserve of token B. |
| `currentLiquidity` | `uint256` | Current liquidity amount.   |

#### BinState <a href="#binstate" id="binstate"></a>

Bin state parameters.

```solidity
struct BinState {
    uint128 mergeBinBalance;
    uint128 tickBalance;
    uint128 totalSupply;
    uint8 kind;
    int32 tick;
    uint32 mergeId;
}
```

**Properties**

| Name              | Type      | Description                                                |
| ----------------- | --------- | ---------------------------------------------------------- |
| `mergeBinBalance` | `uint128` | LP token balance that this bin possesses of the merge bin. |
| `tickBalance`     | `uint128` | Balance of the tick.                                       |
| `totalSupply`     | `uint128` | Total amount of LP tokens in this bin.                     |
| `kind`            | `uint8`   | One of the 4 kinds (0=static, 1=right, 2=left, 3=both).    |
| `tick`            | `int32`   | The lower price tick of the bin in its current state.      |
| `mergeId`         | `uint32`  | Bin ID of the bin that this bin has merged into.           |

#### SwapParams <a href="#swapparams" id="swapparams"></a>

Parameters for swap.

```solidity
struct SwapParams {
    uint256 amount;
    bool tokenAIn;
    bool exactOutput;
    int32 tickLimit;
}
```

**Properties**

| Name          | Type      | Description                                                                                                                                                                            |
| ------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `amount`      | `uint256` | Amount of the token that is either the input if exactOutput is false or the output if exactOutput is true.                                                                             |
| `tokenAIn`    | `bool`    | Boolean indicating whether tokenA is the input.                                                                                                                                        |
| `exactOutput` | `bool`    | Boolean indicating whether the amount specified is the exact output amount (true).                                                                                                     |
| `tickLimit`   | `int32`   | The furthest tick a swap will execute in. If no limit is desired, value should be set to type(int32).max for a tokenAIn swap and type(int32).min for a swap where tokenB is the input. |

#### AddLiquidityParams <a href="#addliquidityparams" id="addliquidityparams"></a>

Parameters associated with adding liquidity.

```solidity
struct AddLiquidityParams {
    uint8 kind;
    int32[] ticks;
    uint128[] amounts;
}
```

**Properties**

| Name      | Type        | Description                                             |
| --------- | ----------- | ------------------------------------------------------- |
| `kind`    | `uint8`     | One of the 4 kinds (0=static, 1=right, 2=left, 3=both). |
| `ticks`   | `int32[]`   | Array of ticks to add liquidity to.                     |
| `amounts` | `uint128[]` | Array of bin LP amounts to add.                         |

#### RemoveLiquidityParams <a href="#removeliquidityparams" id="removeliquidityparams"></a>

Parameters for each bin that will have liquidity removed.

```solidity
struct RemoveLiquidityParams {
    uint32[] binIds;
    uint128[] amounts;
}
```

**Properties**

| Name      | Type        | Description                               |
| --------- | ----------- | ----------------------------------------- |
| `binIds`  | `uint32[]`  | Index array of the bins losing liquidity. |
| `amounts` | `uint128[]` | Array of bin LP amounts to remove.        |

#### State <a href="#state" id="state"></a>

State of the pool.

```solidity
struct State {
    uint128 reserveA;
    uint128 reserveB;
    int64 lastTwaD8;
    int64 lastLogPriceD8;
    uint40 lastTimestamp;
    int32 activeTick;
    bool isLocked;
    uint32 binCounter;
    uint8 protocolFeeRatioD3;
}
```

**Properties**

| Name                 | Type      | Description                                                                                                                                                                                                 |
| -------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `reserveA`           | `uint128` | Pool tokenA balanceOf at end of last operation                                                                                                                                                              |
| `reserveB`           | `uint128` | Pool tokenB balanceOf at end of last operation                                                                                                                                                              |
| `lastTwaD8`          | `int64`   | Value of log time weighted average price at last block. Value is 8-decimal scale and is in the fractional tick domain. E.g. a value of 12.3e8 indicates the TWAP was 3/10ths of the way into the 12th tick. |
| `lastLogPriceD8`     | `int64`   | Value of log price at last block. Value is 8-decimal scale and is in the fractional tick domain. E.g. a value of 12.3e8 indicates the price was 3/10ths of the way into the 12th tick.                      |
| `lastTimestamp`      | `uint40`  | Last block.timestamp value in seconds for latest swap transaction.                                                                                                                                          |
| `activeTick`         | `int32`   | Current tick position that contains the active bins.                                                                                                                                                        |
| `isLocked`           | `bool`    | Pool isLocked, E.g., locked or unlocked; isLocked values defined in Pool.sol.                                                                                                                               |
| `binCounter`         | `uint32`  | Index of the last bin created.                                                                                                                                                                              |
| `protocolFeeRatioD3` | `uint8`   | Ratio of the swap fee that is kept for the protocol.                                                                                                                                                        |

#### BinDelta <a href="#bindelta" id="bindelta"></a>

Internal data used for data passing between Pool and Bin code.

```solidity
struct BinDelta {
    uint128 deltaA;
    uint128 deltaB;
}
```


# IMaverickV2PoolAdmin

### Functions <a href="#functions" id="functions"></a>

#### adminAction <a href="#adminaction" id="adminaction"></a>

Perform pool admin action; this function can only be called by the pool factory contract. When called by other callers, this function will revert.

```solidity
function adminAction(AdminAction action, uint256 value) external;
```

**Parameters**

| Name     | Type          | Description                                                                             |
| -------- | ------------- | --------------------------------------------------------------------------------------- |
| `action` | `AdminAction` | Selector of admin action from AdminAction enum.                                         |
| `value`  | `uint256`     | Applicable for "setting" admin actions and is the new value of the parameter being set. |

### Events <a href="#events" id="events"></a>

#### PoolProtocolFeeCollected <a href="#poolprotocolfeecollected" id="poolprotocolfeecollected"></a>

```solidity
event PoolProtocolFeeCollected(uint256 feeCollected, bool isTokenA);
```

#### PoolSetProtocolFeeRatio <a href="#poolsetprotocolfeeratio" id="poolsetprotocolfeeratio"></a>

```solidity
event PoolSetProtocolFeeRatio(uint256 protocolFeeRatioD3);
```

#### PoolSetLendingFeeRate <a href="#poolsetlendingfeerate" id="poolsetlendingfeerate"></a>

```solidity
event PoolSetLendingFeeRate(uint256 lendingFeeRateD18);
```

### Enums <a href="#enums" id="enums"></a>

#### AdminAction <a href="#adminaction-1" id="adminaction-1"></a>

```solidity
enum AdminAction {
    setProtocolFeeRatioD3,
    claimProtocolFeesA,
    claimProtocolFeesB,
    setLendingFeeRateD18
}
```


# IMaverickV2SwapCallback

### Functions <a href="#functions" id="functions"></a>

#### maverickV2SwapCallback <a href="#maverickv2swapcallback" id="maverickv2swapcallback"></a>

```solidity
function maverickV2SwapCallback(IERC20 tokenIn, uint256 amountIn, uint256 amountOut, bytes calldata data) external;
```

<br>


# libraries

* [ArrayOperations](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/libraries/arrayoperations)
* [Constants](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/libraries/constants)
* [Math](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/libraries/math)
* [PoolLib](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/libraries/poollib)
* [TickMath](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/libraries/tickmath)
* [TransferLib](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/libraries/transferlib)


# ArrayOperations

### Functions <a href="#functions" id="functions"></a>

#### checkUnique <a href="#checkunique" id="checkunique"></a>

Checks that array of numbers are unique.

```solidity
function checkUnique(uint32[] memory array, uint256 maxArrayElementValue) internal pure;
```

**Parameters**

| Name                   | Type       | Description                      |
| ---------------------- | ---------- | -------------------------------- |
| `array`                | `uint32[]` | Array of numbers to check.       |
| `maxArrayElementValue` | `uint256`  | Maximum value possible in Array. |

### Errors <a href="#errors" id="errors"></a>

#### ArrayElementsNotUnique <a href="#arrayelementsnotunique" id="arrayelementsnotunique"></a>

```solidity
error ArrayElementsNotUnique(uint256 index, uint256 duplicateEntry);
```

<br>


# Constants

#### MAX\_PROTOCOL\_FEE\_RATIO\_D3 <a href="#max_protocol_fee_ratio_d3" id="max_protocol_fee_ratio_d3"></a>

```solidity
uint8 constant MAX_PROTOCOL_FEE_RATIO_D3 = 0.25e3;
```

#### MAX\_PROTOCOL\_LENDING\_FEE\_RATE\_D18 <a href="#max_protocol_lending_fee_rate_d18" id="max_protocol_lending_fee_rate_d18"></a>

```solidity
uint256 constant MAX_PROTOCOL_LENDING_FEE_RATE_D18 = 0.02e18;
```

#### MAX\_POOL\_FEE\_D18 <a href="#max_pool_fee_d18" id="max_pool_fee_d18"></a>

```solidity
uint64 constant MAX_POOL_FEE_D18 = 0.5e18;
```

#### MIN\_LOOKBACK <a href="#min_lookback" id="min_lookback"></a>

```solidity
uint64 constant MIN_LOOKBACK = 30 minutes;
```

#### MAX\_TICK\_SPACING <a href="#max_tick_spacing" id="max_tick_spacing"></a>

```solidity
uint64 constant MAX_TICK_SPACING = 10_000;
```

#### NUMBER\_OF\_KINDS <a href="#number_of_kinds" id="number_of_kinds"></a>

```solidity
uint8 constant NUMBER_OF_KINDS = 4;
```

#### NUMBER\_OF\_KINDS\_32 <a href="#number_of_kinds_32" id="number_of_kinds_32"></a>

```solidity
int32 constant NUMBER_OF_KINDS_32 = int32(int8(NUMBER_OF_KINDS));
```

#### MAX\_TICK <a href="#max_tick" id="max_tick"></a>

```solidity
uint256 constant MAX_TICK = 322_378;
```

#### MAX\_TICK\_32 <a href="#max_tick_32" id="max_tick_32"></a>

```solidity
int32 constant MAX_TICK_32 = int32(int256(MAX_TICK));
```

#### MIN\_TICK\_32 <a href="#min_tick_32" id="min_tick_32"></a>

```solidity
int32 constant MIN_TICK_32 = int32(-int256(MAX_TICK));
```

#### MAX\_BINS\_TO\_MERGE <a href="#max_bins_to_merge" id="max_bins_to_merge"></a>

```solidity
uint256 constant MAX_BINS_TO_MERGE = 3;
```

#### MINIMUM\_LIQUIDITY <a href="#minimum_liquidity" id="minimum_liquidity"></a>

```solidity
uint128 constant MINIMUM_LIQUIDITY = 1e8;
```

#### MERGED\_LP\_BALANCE\_ADDRESS <a href="#merged_lp_balance_address" id="merged_lp_balance_address"></a>

```solidity
address constant MERGED_LP_BALANCE_ADDRESS = address(0);
```

#### MERGED\_LP\_BALANCE\_SUBACCOUNT <a href="#merged_lp_balance_subaccount" id="merged_lp_balance_subaccount"></a>

```solidity
uint256 constant MERGED_LP_BALANCE_SUBACCOUNT = 0;
```

#### ONE <a href="#one" id="one"></a>

```solidity
uint128 constant ONE = 1e18;
```

#### ONE\_SQUARED <a href="#one_squared" id="one_squared"></a>

```solidity
uint128 constant ONE_SQUARED = 1e36;
```

#### INT256\_ONE <a href="#int256_one" id="int256_one"></a>

```solidity
int256 constant INT256_ONE = 1e18;
```

#### ONE\_D8 <a href="#one_d8" id="one_d8"></a>

```solidity
uint256 constant ONE_D8 = 1e8;
```

#### ONE\_D3 <a href="#one_d3" id="one_d3"></a>

```solidity
uint256 constant ONE_D3 = 1e3;
```

#### INT\_ONE\_D8 <a href="#int_one_d8" id="int_one_d8"></a>

```solidity
int40 constant INT_ONE_D8 = 1e8;
```

#### HALF\_TICK\_D8 <a href="#half_tick_d8" id="half_tick_d8"></a>

```solidity
int40 constant HALF_TICK_D8 = 0.5e8;
```

#### DEFAULT\_DECIMALS <a href="#default_decimals" id="default_decimals"></a>

```solidity
uint8 constant DEFAULT_DECIMALS = 18;
```

#### DEFAULT\_SCALE <a href="#default_scale" id="default_scale"></a>

```solidity
uint256 constant DEFAULT_SCALE = 1;
```

#### EMPTY\_PRICE\_BREAKS <a href="#empty_price_breaks" id="empty_price_breaks"></a>

```solidity
bytes constant EMPTY_PRICE_BREAKS = hex"010000000000000000000000";
```

<br>


# Math

### Functions <a href="#functions" id="functions"></a>

#### min <a href="#min" id="min"></a>

```solidity
function min(uint256 x, uint256 y) internal pure returns (uint256 z);
```

#### min128 <a href="#min128" id="min128"></a>

```solidity
function min128(uint128 x, uint128 y) internal pure returns (uint128 z);
```

#### min <a href="#min-1" id="min-1"></a>

```solidity
function min(int256 x, int256 y) internal pure returns (int256 z);
```

#### max <a href="#max" id="max"></a>

```solidity
function max(uint256 x, uint256 y) internal pure returns (uint256 z);
```

#### max <a href="#max-1" id="max-1"></a>

```solidity
function max(int256 x, int256 y) internal pure returns (int256 z);
```

#### max128 <a href="#max128" id="max128"></a>

```solidity
function max128(uint128 x, uint128 y) internal pure returns (uint128 z);
```

#### clip128 <a href="#clip128" id="clip128"></a>

```solidity
function clip128(uint128 x, uint128 y) internal pure returns (uint128);
```

#### clip <a href="#clip" id="clip"></a>

```solidity
function clip(uint256 x, uint256 y) internal pure returns (uint256);
```

#### divFloor <a href="#divfloor" id="divfloor"></a>

```solidity
function divFloor(uint256 x, uint256 y) internal pure returns (uint256);
```

#### divCeil <a href="#divceil" id="divceil"></a>

```solidity
function divCeil(uint256 x, uint256 y) internal pure returns (uint256);
```

#### mulFloor <a href="#mulfloor" id="mulfloor"></a>

```solidity
function mulFloor(uint256 x, uint256 y) internal pure returns (uint256);
```

#### mulCeil <a href="#mulceil" id="mulceil"></a>

```solidity
function mulCeil(uint256 x, uint256 y) internal pure returns (uint256);
```

#### invFloor <a href="#invfloor" id="invfloor"></a>

```solidity
function invFloor(uint256 x) internal pure returns (uint256);
```

#### invCeil <a href="#invceil" id="invceil"></a>

```solidity
function invCeil(uint256 denominator) internal pure returns (uint256 z);
```

#### mulDivFloor <a href="#muldivfloor" id="muldivfloor"></a>

```solidity
function mulDivFloor(uint256 x, uint256 y, uint256 k) internal pure returns (uint256 result);
```

#### mulDivCeil <a href="#muldivceil" id="muldivceil"></a>

```solidity
function mulDivCeil(uint256 x, uint256 y, uint256 k) internal pure returns (uint256 result);
```

#### mulDivDown <a href="#muldivdown" id="muldivdown"></a>

```solidity
function mulDivDown(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 z);
```

#### mulDivUp <a href="#muldivup" id="muldivup"></a>

```solidity
function mulDivUp(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 z);
```

#### mulDown <a href="#muldown" id="muldown"></a>

```solidity
function mulDown(uint256 x, uint256 y) internal pure returns (uint256);
```

#### mulUp <a href="#mulup" id="mulup"></a>

```solidity
function mulUp(uint256 x, uint256 y) internal pure returns (uint256);
```

#### divDown <a href="#divdown" id="divdown"></a>

```solidity
function divDown(uint256 x, uint256 y) internal pure returns (uint256);
```

#### divUp <a href="#divup" id="divup"></a>

```solidity
function divUp(uint256 x, uint256 y) internal pure returns (uint256);
```

#### scale <a href="#scale" id="scale"></a>

```solidity
function scale(uint8 decimals) internal pure returns (uint256);
```

#### ammScaleToTokenScale <a href="#ammscaletotokenscale" id="ammscaletotokenscale"></a>

```solidity
function ammScaleToTokenScale(uint256 amount, uint256 scaleFactor, bool ceil) internal pure returns (uint256 z);
```

#### tokenScaleToAmmScale <a href="#tokenscaletoammscale" id="tokenscaletoammscale"></a>

```solidity
function tokenScaleToAmmScale(uint256 amount, uint256 scaleFactor) internal pure returns (uint256);
```

#### abs32 <a href="#abs32" id="abs32"></a>

```solidity
function abs32(int32 x) internal pure returns (uint32);
```

#### abs <a href="#abs" id="abs"></a>

```solidity
function abs(int256 x) internal pure returns (uint256);
```

#### sqrt <a href="#sqrt" id="sqrt"></a>

```solidity
function sqrt(uint256 x) internal pure returns (uint256 z);
```

#### floorD8Unchecked <a href="#floord8unchecked" id="floord8unchecked"></a>

Floor of a D8 number without checking overflow in the cast to int32.

```solidity
function floorD8Unchecked(int256 val) internal pure returns (int32);
```


# PoolLib

### Functions <a href="#functions" id="functions"></a>

#### uniqueOrderedTicksCheck <a href="#uniqueorderedtickscheck" id="uniqueorderedtickscheck"></a>

Check to ensure that the ticks are in ascending order and amount array is same length as tick array.

```solidity
function uniqueOrderedTicksCheck(int32[] memory ticks, uint256 amountsLength) internal pure;
```

**Parameters**

| Name            | Type      | Description                                                |
| --------------- | --------- | ---------------------------------------------------------- |
| `ticks`         | `int32[]` | An array of int32 values representing ticks to be checked. |
| `amountsLength` | `uint256` | Amount array length.                                       |

#### binReserves <a href="#binreserves" id="binreserves"></a>

Compute bin reserves assuming the bin is not merged; not accurate reflection of reserves for merged bins.

```solidity
function binReserves(IMaverickV2Pool.BinState storage bin, IMaverickV2Pool.TickState memory tick)
    internal
    view
    returns (uint128 reserveA, uint128 reserveB);
```

**Parameters**

| Name   | Type                        | Description                                      |
| ------ | --------------------------- | ------------------------------------------------ |
| `bin`  | `IMaverickV2Pool.BinState`  | The storage reference to the state for this bin. |
| `tick` | `IMaverickV2Pool.TickState` | The memory reference to the state for this tick. |

**Returns**

| Name       | Type      | Description                     |
| ---------- | --------- | ------------------------------- |
| `reserveA` | `uint128` | The reserve amount for token A. |
| `reserveB` | `uint128` | The reserve amount for token B. |

#### binReserves <a href="#binreserves-1" id="binreserves-1"></a>

Compute bin reserves assuming the bin is not merged; not accurate reflection of reserves for merged bins.

```solidity
function binReserves(uint128 tickBalance, uint128 tickReserveA, uint128 tickReserveB, uint128 tickTotalSupply)
    internal
    pure
    returns (uint128 reserveA, uint128 reserveB);
```

**Parameters**

| Name              | Type      | Description                        |
| ----------------- | --------- | ---------------------------------- |
| `tickBalance`     | `uint128` | Bin's balance in the tick.         |
| `tickReserveA`    | `uint128` | Tick's tokenA reserves.            |
| `tickReserveB`    | `uint128` | Tick's tokenB reserves.            |
| `tickTotalSupply` | `uint128` | Tick total supply of bin balances. |

#### reserveValue <a href="#reservevalue" id="reservevalue"></a>

Reserves of a bin in a tick.

```solidity
function reserveValue(uint128 tickReserve, uint128 tickBalance, uint128 tickTotalSupply)
    internal
    pure
    returns (uint128 reserve);
```

**Parameters**

| Name              | Type      | Description                           |
| ----------------- | --------- | ------------------------------------- |
| `tickReserve`     | `uint128` | Tick reserve amount in a given token. |
| `tickBalance`     | `uint128` | Bin's balance in the tick.            |
| `tickTotalSupply` | `uint128` | Tick total supply of bin balances.    |

#### deltaTickBalanceFromDeltaLpBalance <a href="#deltatickbalancefromdeltalpbalance" id="deltatickbalancefromdeltalpbalance"></a>

Calculate delta A, delta B, and delta Tick Balance based on delta LP balance and the Tick/Bin state.

```solidity
function deltaTickBalanceFromDeltaLpBalance(
    uint256 binTickBalance,
    uint256 binTotalSupply,
    IMaverickV2Pool.TickState memory tickState,
    uint128 deltaLpBalance,
    AddLiquidityInfo memory addLiquidityInfo
) internal pure returns (uint256 deltaTickBalance);
```

#### \_setRequiredDeltaReservesForEmptyTick <a href="#setrequireddeltareservesforemptytick" id="setrequireddeltareservesforemptytick"></a>

Calculates deltaA = liquidity \* (sqrt(upper) - sqrt(lower))

Calculates deltaB = liquidity / sqrt(lower) - liquidity / sqrt(upper),

i.e., liquidity \* (sqrt(upper) - sqrt(lower)) / (sqrt(upper) \* sqrt(lower))

we set liquidity = deltaLpBalance / (1.0001^(tick \* tickspacing) - 1)

which simplifies the A/B amounts to:

deltaA = deltaLpBalance \* sqrt(lower)

deltaB = deltaLpBalance / sqrt(upper)

```solidity
function _setRequiredDeltaReservesForEmptyTick(uint128 deltaLpBalance, AddLiquidityInfo memory addLiquidityInfo)
    internal
    pure;
```

### Structs <a href="#structs" id="structs"></a>

#### AddLiquidityInfo <a href="#addliquidityinfo" id="addliquidityinfo"></a>

```solidity
struct AddLiquidityInfo {
    uint256 deltaA;
    uint256 deltaB;
    bool tickLtActive;
    uint256 tickSpacing;
    int32 tick;
}
```


# TickMath

### Functions <a href="#functions" id="functions"></a>

#### tickSqrtPrices <a href="#ticksqrtprices" id="ticksqrtprices"></a>

Compute the lower and upper sqrtPrice of a tick.

```solidity
function tickSqrtPrices(uint256 tickSpacing, int32 _tick)
    internal
    pure
    returns (uint256 sqrtLowerPrice, uint256 sqrtUpperPrice);
```

**Parameters**

| Name          | Type      | Description                             |
| ------------- | --------- | --------------------------------------- |
| `tickSpacing` | `uint256` | The tick spacing used for calculations. |
| `_tick`       | `int32`   | The input tick value.                   |

#### subTickIndex <a href="#subtickindex" id="subtickindex"></a>

Compute the base tick value from the pool tick and the tickSpacing. Revert if base tick is beyond the max tick boundary.

```solidity
function subTickIndex(uint256 tickSpacing, int32 _tick) internal pure returns (uint32 subTick);
```

**Parameters**

| Name          | Type      | Description                             |
| ------------- | --------- | --------------------------------------- |
| `tickSpacing` | `uint256` | The tick spacing used for calculations. |
| `_tick`       | `int32`   | The input tick value.                   |

#### tickSqrtPrice <a href="#ticksqrtprice" id="ticksqrtprice"></a>

Calculate the square root price for a given tick and tick spacing.

```solidity
function tickSqrtPrice(uint256 tickSpacing, int32 _tick) internal pure returns (uint256 _result);
```

**Parameters**

| Name          | Type      | Description                             |
| ------------- | --------- | --------------------------------------- |
| `tickSpacing` | `uint256` | The tick spacing used for calculations. |
| `_tick`       | `int32`   | The input tick value.                   |

**Returns**

| Name      | Type      | Description            |
| --------- | --------- | ---------------------- |
| `_result` | `uint256` | The square root price. |

#### getTickL <a href="#gettickl" id="gettickl"></a>

Calculate liquidity of a tick.

```solidity
function getTickL(uint256 reserveA, uint256 reserveB, uint256 sqrtLowerTickPrice, uint256 sqrtUpperTickPrice)
    internal
    pure
    returns (uint256 liquidity);
```

**Parameters**

| Name                 | Type      | Description                                   |
| -------------------- | --------- | --------------------------------------------- |
| `reserveA`           | `uint256` | Tick reserve of token A.                      |
| `reserveB`           | `uint256` | Tick reserve of token B.                      |
| `sqrtLowerTickPrice` | `uint256` | The square root price of the lower tick edge. |
| `sqrtUpperTickPrice` | `uint256` | The square root price of the upper tick edge. |

#### getSqrtPrice <a href="#getsqrtprice" id="getsqrtprice"></a>

Calculate square root price of a tick. Returns left edge of the tick if the tick has no reserves.

```solidity
function getSqrtPrice(
    uint256 reserveA,
    uint256 reserveB,
    uint256 sqrtLowerTickPrice,
    uint256 sqrtUpperTickPrice,
    uint256 liquidity
) internal pure returns (uint256 sqrtPrice);
```

**Parameters**

| Name                 | Type      | Description                                   |
| -------------------- | --------- | --------------------------------------------- |
| `reserveA`           | `uint256` | Tick reserve of token A.                      |
| `reserveB`           | `uint256` | Tick reserve of token B.                      |
| `sqrtLowerTickPrice` | `uint256` | The square root price of the lower tick edge. |
| `sqrtUpperTickPrice` | `uint256` | The square root price of the upper tick edge. |
| `liquidity`          | `uint256` |                                               |

**Returns**

| Name        | Type      | Description                       |
| ----------- | --------- | --------------------------------- |
| `sqrtPrice` | `uint256` | The calculated square root price. |

#### getTickSqrtPriceAndL <a href="#getticksqrtpriceandl" id="getticksqrtpriceandl"></a>

Calculate square root price of a tick. Returns left edge of the tick if the tick has no reserves.

```solidity
function getTickSqrtPriceAndL(
    uint256 reserveA,
    uint256 reserveB,
    uint256 sqrtLowerTickPrice,
    uint256 sqrtUpperTickPrice
) internal pure returns (uint256 sqrtPrice, uint256 liquidity);
```

**Parameters**

| Name                 | Type      | Description                                   |
| -------------------- | --------- | --------------------------------------------- |
| `reserveA`           | `uint256` | Tick reserve of token A.                      |
| `reserveB`           | `uint256` | Tick reserve of token B.                      |
| `sqrtLowerTickPrice` | `uint256` | The square root price of the lower tick edge. |
| `sqrtUpperTickPrice` | `uint256` | The square root price of the upper tick edge. |

**Returns**

| Name        | Type      | Description                       |
| ----------- | --------- | --------------------------------- |
| `sqrtPrice` | `uint256` | The calculated square root price. |
| `liquidity` | `uint256` | The calculated liquidity.         |

### Errors <a href="#errors" id="errors"></a>

#### TickMaxExceeded <a href="#tickmaxexceeded" id="tickmaxexceeded"></a>

```solidity
error TickMaxExceeded(int256 tick);
```


# TransferLib

### Functions <a href="#functions" id="functions"></a>

#### transfer <a href="#transfer" id="transfer"></a>

Transfer token amount. Amount is sent from caller address to `to` address.

```solidity
function transfer(IERC20 token, address to, uint256 amount) internal;
```

#### transferFrom <a href="#transferfrom" id="transferfrom"></a>

Transfer token amount. Amount is sent from `from` address to `to` address.

```solidity
function transferFrom(IERC20 token, address from, address to, uint256 amount) internal;
```

### Errors <a href="#errors" id="errors"></a>

#### TransferFailed <a href="#transferfailed" id="transferfailed"></a>

```solidity
error TransferFailed(IERC20 token, address to, uint256 amount);
```

#### TransferFromFailed <a href="#transferfromfailed" id="transferfromfailed"></a>

```solidity
error TransferFromFailed(IERC20 token, address from, address to, uint256 amount);
```

<br>


# Maverick V2 AMM Contracts


# poollib

* [Bin](/technical-reference/maverick-v2/v2-contracts/maverick-v2-amm-contracts/poollib/bin)
* [Delta](/technical-reference/maverick-v2/v2-contracts/maverick-v2-amm-contracts/poollib/delta)
* [Deployer](/technical-reference/maverick-v2/v2-contracts/maverick-v2-amm-contracts/poollib/deployer)
* [DeployerPermissioned](/technical-reference/maverick-v2/v2-contracts/maverick-v2-amm-contracts/poollib/deployerpermissioned)
* [SwapMath](/technical-reference/maverick-v2/v2-contracts/maverick-v2-amm-contracts/poollib/swapmath)
* [Twa](/technical-reference/maverick-v2/v2-contracts/maverick-v2-amm-contracts/poollib/twa)


# Bin

### Functions <a href="#functions" id="functions"></a>

#### lpBalancesFromDeltaReserve <a href="#lpbalancesfromdeltareserve" id="lpbalancesfromdeltareserve"></a>

Calculate pro rata liquidity balances based on delta reserves.

```solidity
function lpBalancesFromDeltaReserve(
    Bin.Instance storage self,
    IMaverickV2Pool.TickState storage tickState,
    uint256 deltaA,
    uint256 deltaB
) internal view returns (uint256 proRataLiquidity);
```

**Parameters**

| Name        | Type                        | Description                         |
| ----------- | --------------------------- | ----------------------------------- |
| `self`      | `Bin.Instance`              | The Bin.Instance storage.           |
| `tickState` | `IMaverickV2Pool.TickState` | The TickState storage.              |
| `deltaA`    | `uint256`                   | The change in A (token A) reserves. |
| `deltaB`    | `uint256`                   | The change in B (token B) reserves. |

**Returns**

| Name               | Type      | Description                     |
| ------------------ | --------- | ------------------------------- |
| `proRataLiquidity` | `uint256` | The pro rata liquidity balance. |

#### addLiquidityByReserves <a href="#addliquiditybyreserves" id="addliquiditybyreserves"></a>

Add liquidity to the bin based on delta reserves.

```solidity
function addLiquidityByReserves(
    Bin.Instance storage self,
    IMaverickV2Pool.TickState storage tickState,
    uint128 deltaA,
    uint128 deltaB,
    uint128 deltaLpBalance
) internal;
```

**Parameters**

| Name             | Type                        | Description                         |
| ---------------- | --------------------------- | ----------------------------------- |
| `self`           | `Bin.Instance`              | The Bin.Instance storage.           |
| `tickState`      | `IMaverickV2Pool.TickState` | The TickState storage.              |
| `deltaA`         | `uint128`                   | The change in A (token A) reserves. |
| `deltaB`         | `uint128`                   | The change in B (token B) reserves. |
| `deltaLpBalance` | `uint128`                   |                                     |

#### addLiquidity <a href="#addliquidity" id="addliquidity"></a>

Add liquidity to the bin. note: lp balance is not the same a "liquidity"; as fees accumulate in a bin, a unit of lp balance will diverge from a unit of liquidity.

```solidity
function addLiquidity(
    Bin.Instance storage self,
    IMaverickV2Pool.TickState storage tickState,
    address recipient,
    uint256 subaccount,
    uint128 deltaLpBalance,
    PoolLib.AddLiquidityInfo memory addLiquidityInfo
) internal;
```

**Parameters**

| Name               | Type                        | Description                     |
| ------------------ | --------------------------- | ------------------------------- |
| `self`             | `Bin.Instance`              | The Bin.Instance storage.       |
| `tickState`        | `IMaverickV2Pool.TickState` | The TickState storage.          |
| `recipient`        | `address`                   | The recipient address.          |
| `subaccount`       | `uint256`                   | The subaccount.                 |
| `deltaLpBalance`   | `uint128`                   | The change in LP balance.       |
| `addLiquidityInfo` | `PoolLib.AddLiquidityInfo`  | The AddLiquidityInfo structure. |

#### [migrateBinsUpStack](file:///C:/Users/mptay/Downloads/v2-amm/docs/book/contracts/poollib/Bin.sol/library.Bin.html#migratebinsupstack) <a href="#migratebinsupstack" id="migratebinsupstack"></a>

Migrate bins up the stack.

```solidity
function migrateBinsUpStack(Instance storage self, mapping(uint32 => Instance) storage bins, uint32 maxRecursion)
    internal;
```

**Parameters**

| Name           | Type                          | Description                  |
| -------------- | ----------------------------- | ---------------------------- |
| `self`         | `Instance`                    | The Instance storage.        |
| `bins`         | `mapping(uint32 => Instance)` | The bins mapping.            |
| `maxRecursion` | `uint32`                      | The maximum recursion depth. |

#### removeLiquidity <a href="#removeliquidity" id="removeliquidity"></a>

Remove liquidity from the bin.

```solidity
function removeLiquidity(
    Instance storage self,
    mapping(int32 => IMaverickV2Pool.TickState) storage tickStates,
    mapping(uint32 => Instance) storage bins,
    address user,
    uint256 subaccount,
    uint256 deltaLpAmount
) internal returns (IMaverickV2Pool.BinDelta memory binDelta);
```

**Parameters**

| Name            | Type                                          | Description               |
| --------------- | --------------------------------------------- | ------------------------- |
| `self`          | `Instance`                                    | The Instance storage.     |
| `tickStates`    | `mapping(int32 => IMaverickV2Pool.TickState)` | The TickState mapping.    |
| `bins`          | `mapping(uint32 => Instance)`                 | The bins mapping.         |
| `user`          | `address`                                     | The user address.         |
| `subaccount`    | `uint256`                                     | The subaccount.           |
| `deltaLpAmount` | `uint256`                                     | The change in LP balance. |

**Returns**

| Name       | Type                       | Description             |
| ---------- | -------------------------- | ----------------------- |
| `binDelta` | `IMaverickV2Pool.BinDelta` | The BinDelta structure. |

#### \_updateBinState <a href="#updatebinstate" id="updatebinstate"></a>

Updates the state of a bin and tick in the MaverickV2Pool.

```solidity
function _updateBinState(
    Bin.Instance storage self,
    IMaverickV2Pool.TickState storage tickState,
    address user,
    uint256 subaccount,
    uint128 deltaA,
    uint128 deltaB,
    uint128 deltaLpBalance,
    uint128 deltaTickBalance
) private;
```

**Parameters**

| Name               | Type                        | Description                                    |
| ------------------ | --------------------------- | ---------------------------------------------- |
| `self`             | `Bin.Instance`              | The bin instance to be updated.                |
| `tickState`        | `IMaverickV2Pool.TickState` | The tick state of the pool.                    |
| `user`             | `address`                   | The address of the user performing the action. |
| `subaccount`       | `uint256`                   | The subaccount identifier for the user.        |
| `deltaA`           | `uint128`                   | The change in reserveA.                        |
| `deltaB`           | `uint128`                   | The change in reserveB.                        |
| `deltaLpBalance`   | `uint128`                   | The change in LP token balance.                |
| `deltaTickBalance` | `uint128`                   | The change in tick balance.                    |

### Structs <a href="#structs" id="structs"></a>

#### Instance <a href="#instance" id="instance"></a>

```solidity
struct Instance {
    IMaverickV2Pool.BinState state;
    mapping(address => mapping(uint256 => uint128)) balances;
}
```


# Delta

### Functions <a href="#functions" id="functions"></a>

#### combine <a href="#combine" id="combine"></a>

Combines two Delta instances by adding their delta values if skipCombine is false.

```solidity
function combine(Instance memory self, Instance memory delta) internal pure;
```

**Parameters**

| Name    | Type       | Description                                          |
| ------- | ---------- | ---------------------------------------------------- |
| `self`  | `Instance` | The first Delta instance.                            |
| `delta` | `Instance` | The second Delta instance to combine with the first. |

#### pastMaxTick <a href="#pastmaxtick" id="pastmaxtick"></a>

Checks if the activeTick is past the tickLimit for swapping to the maximum price.

```solidity
function pastMaxTick(Instance memory self, int32 activeTick) internal pure returns (bool);
```

**Parameters**

| Name         | Type       | Description              |
| ------------ | ---------- | ------------------------ |
| `self`       | `Instance` | The Delta instance.      |
| `activeTick` | `int32`    | The current active tick. |

**Returns**

| Name     | Type   | Description                                                    |
| -------- | ------ | -------------------------------------------------------------- |
| `<none>` | `bool` | true if the activeTick is past the tickLimit, false otherwise. |

### Structs <a href="#structs" id="structs"></a>

#### Instance <a href="#instance" id="instance"></a>

```solidity
struct Instance {
    uint256 deltaInBinInternal;
    uint256 deltaInErc;
    uint256 deltaOutErc;
    uint256 excess;
    bool tokenAIn;
    bool exactOutput;
    bool swappedToMaxPrice;
    bool skipCombine;
    int32 tickLimit;
    uint256 sqrtLowerTickPrice;
    uint256 sqrtUpperTickPrice;
    uint256 sqrtPrice;
    int64 fractionalPart;
}
```


# Deployer

### Functions <a href="#functions" id="functions"></a>

#### deploy <a href="#deploy" id="deploy"></a>

```solidity
function deploy(
    uint256 feeAIn,
    uint256 feeBIn,
    uint256 tickSpacing,
    uint256 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    uint8 kinds
) external returns (IMaverickV2Pool pool);
```

#### poolBytecodeHash <a href="#poolbytecodehash" id="poolbytecodehash"></a>

```solidity
function poolBytecodeHash() external pure returns (bytes32);
```


# DeployerPermissioned

### Functions <a href="#functions" id="functions"></a>

#### deploy <a href="#deploy" id="deploy"></a>

```solidity
function deploy(
    uint256 feeAIn,
    uint256 feeBIn,
    uint256 tickSpacing,
    uint256 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    uint8 kinds,
    address accessor
) external returns (IMaverickV2Pool pool);
```

#### poolBytecodeHash <a href="#poolbytecodehash" id="poolbytecodehash"></a>

```solidity
function poolBytecodeHash() external pure returns (bytes32);
```


# SwapMath

### Functions <a href="#functions" id="functions"></a>

#### \_amountToBinNetOfProtocolFee <a href="#amounttobinnetofprotocolfee" id="amounttobinnetofprotocolfee"></a>

Internal function to calculate the amount after deducting the protocol fee.

```
```

```solidity
function _amountToBinNetOfProtocolFee(uint256 deltaInErc, uint256 feeBasis, uint256 protocolFeeD3)
    private
    pure
    returns (uint256 amount);
```

**Parameters**

| Name            | Type      | Description                                                                                                        |
| --------------- | --------- | ------------------------------------------------------------------------------------------------------------------ |
| `deltaInErc`    | `uint256` | Input delta in ERC token.                                                                                          |
| `feeBasis`      | `uint256` | Fee basis for calculating the fee amount.                                                                          |
| `protocolFeeD3` | `uint256` | Proportion of the fee that goes to the protocol in three-decimal format. e.g. fee of 100 is 10% protocol fee rate. |

**Returns**

| Name     | Type      | Description                                  |
| -------- | --------- | -------------------------------------------- |
| `amount` | `uint256` | The amount after deducting the protocol fee. |

#### \_remainingBinInputSpaceGivenOutput <a href="#remainingbininputspacegivenoutput" id="remainingbininputspacegivenoutput"></a>

Internal function to calculate the remaining input space given the output.

```solidity
function _remainingBinInputSpaceGivenOutput(uint256 binLiquidity, uint256 output, uint256 sqrtPrice, bool tokenAIn)
    private
    pure
    returns (uint256 binAmountIn);
```

**Parameters**

| Name           | Type      | Description                        |
| -------------- | --------- | ---------------------------------- |
| `binLiquidity` | `uint256` | The current liquidity in the bin.  |
| `output`       | `uint256` | The desired output amount.         |
| `sqrtPrice`    | `uint256` | The current square root price.     |
| `tokenAIn`     | `bool`    | True if the swap input is token A. |

**Returns**

| Name          | Type      | Description                                           |
| ------------- | --------- | ----------------------------------------------------- |
| `binAmountIn` | `uint256` | The input amount that can be accommodated in the bin. |

#### computeEndPrice <a href="#computeendprice" id="computeendprice"></a>

Compute end price of a swap as well as the approximate end price in the tick domain. The resulting output fraction tick part is written to the input newDelta object.

Ain: `endSqrtP = in / L + sqrtP`

Bin: `endSqrtP = 1 / (in / L + 1 / sqrtP) = L / (in + L / sqrtP)`

fractional Tick: `(endSqrtP - lowerSqrtP) / (upperSqrtP - lowerSqrtP)`

```solidity
function computeEndPrice(
    Delta.Instance memory delta,
    Delta.Instance memory newDelta,
    IMaverickV2Pool.TickData memory tickData
) internal pure;
```

#### computeSwapExactIn <a href="#computeswapexactin" id="computeswapexactin"></a>

Calculate swap data for an exact input swap.

```solidity
function computeSwapExactIn(
    uint256 sqrtPrice,
    IMaverickV2Pool.TickData memory tickData,
    uint256 amountIn,
    bool tokenAIn,
    uint256 fee,
    uint256 protocolFeeD3
) internal pure returns (Delta.Instance memory delta);
```

**Parameters**

| Name            | Type                       | Description                                      |
| --------------- | -------------------------- | ------------------------------------------------ |
| `sqrtPrice`     | `uint256`                  | Current price.                                   |
| `tickData`      | `IMaverickV2Pool.TickData` | Reserve and liquidity values of the bin.         |
| `amountIn`      | `uint256`                  | Desired input amount.                            |
| `tokenAIn`      | `bool`                     | True if the swap input is token A.               |
| `fee`           | `uint256`                  | Ratio that the swapper pays in D18 format.       |
| `protocolFeeD3` | `uint256`                  | Proportion of the fee that goes to the protocol. |

**Returns**

| Name    | Type             | Description                               |
| ------- | ---------------- | ----------------------------------------- |
| `delta` | `Delta.Instance` | Swap data delta for the exact input swap. |

#### computeSwapExactOut <a href="#computeswapexactout" id="computeswapexactout"></a>

Calculate swap data for an exact output swap.

```solidity
function computeSwapExactOut(
    uint256 sqrtPrice,
    IMaverickV2Pool.TickData memory tickData,
    uint256 amountOut,
    bool tokenAIn,
    uint256 fee,
    uint256 protocolFeeD3
) internal pure returns (Delta.Instance memory delta);
```

**Parameters**

| Name            | Type                       | Description                                      |
| --------------- | -------------------------- | ------------------------------------------------ |
| `sqrtPrice`     | `uint256`                  | Current price.                                   |
| `tickData`      | `IMaverickV2Pool.TickData` | Reserve and liquidity values of the bin.         |
| `amountOut`     | `uint256`                  | Desired output amount.                           |
| `tokenAIn`      | `bool`                     | True if the swap input is token A.               |
| `fee`           | `uint256`                  | Ratio that the swapper pays in D18 format.       |
| `protocolFeeD3` | `uint256`                  | Proportion of the fee that goes to the protocol. |

**Returns**

| Name    | Type             | Description                                |
| ------- | ---------------- | ------------------------------------------ |
| `delta` | `Delta.Instance` | Swap data delta for the exact output swap. |


# Twa

### Functions <a href="#functions" id="functions"></a>

#### updateValue <a href="#updatevalue" id="updatevalue"></a>

Update the TWA (Time-Weighted Average) value in the State memory.

```solidity
function updateValue(IMaverickV2Pool.State memory self, int256 value, uint256 lookback) internal view;
```

**Parameters**

| Name       | Type                    | Description                                         |
| ---------- | ----------------------- | --------------------------------------------------- |
| `self`     | `IMaverickV2Pool.State` | The State memory to update.                         |
| `value`    | `int256`                | The new value to set.                               |
| `lookback` | `uint256`               | The lookback period to use for calculating the TWA. |

#### floor <a href="#floor" id="floor"></a>

Get the floored TWA value from the State memory.

```solidity
function floor(IMaverickV2Pool.State memory self) internal pure returns (int32);
```

**Parameters**

| Name   | Type                    | Description                    |
| ------ | ----------------------- | ------------------------------ |
| `self` | `IMaverickV2Pool.State` | The State memory to read from. |

**Returns**

| Name     | Type    | Description                        |
| -------- | ------- | ---------------------------------- |
| `<none>` | `int32` | The floored TWA value as an int32. |

#### getTwa <a href="#gettwa" id="gettwa"></a>

Get the TWA value from the State memory, considering a lookback period.

```solidity
function getTwa(IMaverickV2Pool.State memory self, uint256 lookback) internal view returns (int256);
```

**Parameters**

| Name       | Type                    | Description                                         |
| ---------- | ----------------------- | --------------------------------------------------- |
| `self`     | `IMaverickV2Pool.State` | The State memory to read from.                      |
| `lookback` | `uint256`               | The lookback period to use for calculating the TWA. |

**Returns**

| Name     | Type     | Description                 |
| -------- | -------- | --------------------------- |
| `<none>` | `int256` | The TWA value as an int256. |

#### getTwaFloor <a href="#gettwafloor" id="gettwafloor"></a>

Get the floored TWA value from the State memory, based on the lookback period.

```solidity
function getTwaFloor(IMaverickV2Pool.State memory self, uint256 lookback) internal view returns (int32);
```

**Parameters**

| Name       | Type                    | Description                                         |
| ---------- | ----------------------- | --------------------------------------------------- |
| `self`     | `IMaverickV2Pool.State` | The State memory to read from.                      |
| `lookback` | `uint256`               | The lookback period to use for calculating the TWA. |

**Returns**

| Name     | Type    | Description                        |
| -------- | ------- | ---------------------------------- |
| `<none>` | `int32` | The floored TWA value as an int32. |


# MaverickV2Factory

**Inherits:** [IMaverickV2Factory](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/interfaces/imaverickv2factory), [IMaverickV2FactoryAdmin](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/interfaces/imaverickv2factoryadmin), Ownable

Pool Factory contract. Deploys both permissionless and permissioned Maverick V2 pools using deterministic create2 addresses. Deployed pools can be looked up by their parameters or by the token pair. This contract is ownable with the owner having permission to set protocol fee for all pools and collect protocol fee proceeds from pools.

### State Variables <a href="#state-variables" id="state-variables"></a>

#### poolLists <a href="#poollists" id="poollists"></a>

Mapping elements are \[tokenA]\[tokenB] -> list of pools.

```solidity
mapping(IERC20 => mapping(IERC20 => IMaverickV2Pool[])) private poolLists;
```

#### poolListsPermissioned <a href="#poollistspermissioned" id="poollistspermissioned"></a>

Mapping elements are \[accessor]\[tokenA]\[tokenB] -> list of pools.

```solidity
mapping(address => mapping(IERC20 => mapping(IERC20 => IMaverickV2Pool[]))) private poolListsPermissioned;
```

#### isFactoryPool <a href="#isfactorypool" id="isfactorypool"></a>

Bool indicating whether the pool was deployed from this factory.

```solidity
mapping(IMaverickV2Pool => bool) public isFactoryPool;
```

#### isFactoryPoolPermissioned <a href="#isfactorypoolpermissioned" id="isfactorypoolpermissioned"></a>

Bool indicating whether the pool was deployed from this factory.

```solidity
mapping(IMaverickV2Pool => bool) public isFactoryPoolPermissioned;
```

#### protocolFeeRatioD3 <a href="#protocolfeeratiod3" id="protocolfeeratiod3"></a>

Proportion of protocol fee to collect on each swap. Value is in 3-decimal format with a maximum value of 0.25e3.

```solidity
uint8 public protocolFeeRatioD3;
```

#### protocolLendingFeeRateD18 <a href="#protocollendingfeerated18" id="protocollendingfeerated18"></a>

Fee rate charged by the protocol for flashloans. Value is in 18-decimal format with a maximum value of 0.02e18.

```solidity
uint256 public protocolLendingFeeRateD18;
```

#### deployParameters <a href="#deployparameters" id="deployparameters"></a>

Called by deployer library to initialize a pool.

```solidity
DeployParameters public deployParameters;
```

#### protocolFeeReceiver <a href="#protocolfeereceiver" id="protocolfeereceiver"></a>

Address that receives the protocol fee when users call `claimProtocolFeeForPool`.

```solidity
address public protocolFeeReceiver;
```

#### allPools <a href="#allpools" id="allpools"></a>

Array of all permissionless pools.

```solidity
IMaverickV2Pool[] private allPools;
```

#### allPoolsPermissioned <a href="#allpoolspermissioned" id="allpoolspermissioned"></a>

Array of all permissioned pools.

```solidity
IMaverickV2Pool[] private allPoolsPermissioned;
```

### Functions <a href="#functions" id="functions"></a>

#### constructor <a href="#constructor" id="constructor"></a>

```solidity
constructor(address initialOwner) Ownable(initialOwner);
```

#### setProtocolFeeRatio <a href="#setprotocolfeeratio" id="setprotocolfeeratio"></a>

Set the protocol fee ratio.

```solidity
function setProtocolFeeRatio(uint8 _protocolFeeRatioD3) external onlyOwner;
```

**Parameters**

| Name                  | Type    | Description                                           |
| --------------------- | ------- | ----------------------------------------------------- |
| `_protocolFeeRatioD3` | `uint8` | The new protocol fee ratio to set in 3-decimal units. |

#### setProtocolLendingFeeRate <a href="#setprotocollendingfeerate" id="setprotocollendingfeerate"></a>

Set the protocol lending fee rate.

```solidity
function setProtocolLendingFeeRate(uint256 _protocolLendingFeeRateD18) external onlyOwner;
```

**Parameters**

| Name                         | Type      | Description                                                   |
| ---------------------------- | --------- | ------------------------------------------------------------- |
| `_protocolLendingFeeRateD18` | `uint256` | The new protocol lending fee rate to set in 18-decimal units. |

#### setProtocolFeeReceiver <a href="#setprotocolfeereceiver" id="setprotocolfeereceiver"></a>

Set the protocol fee receiver address. If protocol fee is non-zero, user will be able to permissionlessly push protocol fee from a given pool to this address.

```solidity
function setProtocolFeeReceiver(address receiver) external onlyOwner;
```

#### transferOwnership <a href="#transferownership" id="transferownership"></a>

Transfer ownership of the contract to a new owner.

```solidity
function transferOwnership(address newOwner) public override(IMaverickV2FactoryAdmin, Ownable) onlyOwner;
```

**Parameters**

| Name       | Type      | Description                   |
| ---------- | --------- | ----------------------------- |
| `newOwner` | `address` | The address of the new owner. |

#### renounceOwnership <a href="#renounceownership" id="renounceownership"></a>

Renounce ownership of the contract.

```solidity
function renounceOwnership() public override(IMaverickV2FactoryAdmin, Ownable) onlyOwner;
```

#### claimProtocolFeeForPool <a href="#claimprotocolfeeforpool" id="claimprotocolfeeforpool"></a>

Claim protocol fee for a pool and transfer it to the protocolFeeReceiver.

```solidity
function claimProtocolFeeForPool(IMaverickV2Pool pool, bool isTokenA) public;
```

**Parameters**

| Name       | Type              | Description                                                                      |
| ---------- | ----------------- | -------------------------------------------------------------------------------- |
| `pool`     | `IMaverickV2Pool` | The pool from which to claim the protocol fee.                                   |
| `isTokenA` | `bool`            | A boolean indicating whether tokenA (true) or tokenB (false) is being collected. |

#### claimProtocolFeeForPool <a href="#claimprotocolfeeforpool-1" id="claimprotocolfeeforpool-1"></a>

Claim protocol fee for a pool and transfer it to the protocolFeeReceiver.

```solidity
function claimProtocolFeeForPool(IMaverickV2Pool pool) public;
```

**Parameters**

| Name   | Type              | Description                                    |
| ------ | ----------------- | ---------------------------------------------- |
| `pool` | `IMaverickV2Pool` | The pool from which to claim the protocol fee. |

#### updateProtocolFeeRatioForPool <a href="#updateprotocolfeeratioforpool" id="updateprotocolfeeratioforpool"></a>

Update the protocol fee ratio for a pool. Can be called permissionlessly allowing any user to sync the pool protocol fee value with the factory protocol fee value.

```solidity
function updateProtocolFeeRatioForPool(IMaverickV2Pool pool) public;
```

**Parameters**

| Name   | Type              | Description                   |
| ------ | ----------------- | ----------------------------- |
| `pool` | `IMaverickV2Pool` | The pool for which to update. |

#### updateProtocolLendingFeeRateForPool <a href="#updateprotocollendingfeerateforpool" id="updateprotocollendingfeerateforpool"></a>

Update the protocol lending fee rate for a pool. Can be called permissionlessly allowing any user to sync the pool protocol lending fee rate value with the factory value.

```solidity
function updateProtocolLendingFeeRateForPool(IMaverickV2Pool pool) public;
```

**Parameters**

| Name   | Type              | Description                   |
| ------ | ----------------- | ----------------------------- |
| `pool` | `IMaverickV2Pool` | The pool for which to update. |

#### create <a href="#create-1" id="create-1"></a>

Create a new MaverickV2Pool with symmetric swap fees.

```solidity
function create(
    uint64 feeAIn,
    uint64 feeBIn,
    uint16 tickSpacing,
    uint32 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    int32 activeTick,
    uint8 kinds
) public returns (IMaverickV2Pool pool);
```

**Parameters**

| Name          | Type     | Description                                                                                                                                                        |
| ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `feeAIn`      | `uint64` |                                                                                                                                                                    |
| `feeBIn`      | `uint64` |                                                                                                                                                                    |
| `tickSpacing` | `uint16` | Tick spacing of pool where 1.0001^tickSpacing is the bin width.                                                                                                    |
| `lookback`    | `uint32` | Pool lookback in second in D2 scale.                                                                                                                               |
| `tokenA`      | `IERC20` | Address of tokenA.                                                                                                                                                 |
| `tokenB`      | `IERC20` | Address of tokenB.                                                                                                                                                 |
| `activeTick`  | `int32`  | Tick position that contains the active bins.                                                                                                                       |
| `kinds`       | `uint8`  | 1-15 number to represent the active kinds 0b0001 = static; 0b0010 = right; 0b0100 = left; 0b1000 = both. E.g. a pool with all 4 modes will have kinds = b1111 = 15 |

#### createPermissioned <a href="#createpermissioned" id="createpermissioned"></a>

Create a new MaverickV2PoolPermissioned with symmetric swap fees.

```solidity
function createPermissioned(
    uint64 fee,
    uint16 tickSpacing,
    uint32 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    int32 activeTick,
    uint8 kinds,
    address accessor
) public returns (IMaverickV2Pool pool);
```

**Parameters**

| Name          | Type      | Description                                                                                                                                                        |
| ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `fee`         | `uint64`  | Fraction of the pool swap amount that is retained as an LP in D18 scale.                                                                                           |
| `tickSpacing` | `uint16`  | Tick spacing of pool where 1.0001^tickSpacing is the bin width.                                                                                                    |
| `lookback`    | `uint32`  | Pool lookback in second in D2 scale.                                                                                                                               |
| `tokenA`      | `IERC20`  | Address of tokenA.                                                                                                                                                 |
| `tokenB`      | `IERC20`  | Address of tokenB.                                                                                                                                                 |
| `activeTick`  | `int32`   | Tick position that contains the active bins.                                                                                                                       |
| `kinds`       | `uint8`   | 1-15 number to represent the active kinds 0b0001 = static; 0b0010 = right; 0b0100 = left; 0b1000 = both. E.g. a pool with all 4 modes will have kinds = b1111 = 15 |
| `accessor`    | `address` | Only address that can access the pool's public write functions.                                                                                                    |

#### owner <a href="#owner" id="owner"></a>

Get the current factory owner.

```solidity
function owner() public view override(IMaverickV2Factory, Ownable) returns (address);
```

#### lookup <a href="#lookup" id="lookup"></a>

Lookup a pool for given parameters.

```solidity
function lookup(
    uint256 _feeAIn,
    uint256 _feeBIn,
    uint256 _tickSpacing,
    uint256 _lookback,
    IERC20 _tokenA,
    IERC20 _tokenB,
    uint8 kinds
) public view returns (IMaverickV2Pool pool);
```

#### lookup <a href="#lookup-1" id="lookup-1"></a>

Lookup a pool for given parameters.

```solidity
function lookup(IERC20 _tokenA, IERC20 _tokenB, uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2Pool[] memory);
```

Lookup a pool for given parameters.

```solidity
function lookup(uint256 startIndex, uint256 endIndex) external view returns (IMaverickV2Pool[] memory);
```

Lookup a pool for given parameters.

```solidity
function lookupPermissioned(
    uint256 _feeAIn,
    uint256 _feeBIn,
    uint256 _tickSpacing,
    uint256 _lookback,
    IERC20 _tokenA,
    IERC20 _tokenB,
    uint8 kinds,
    address accessor
) public view returns (IMaverickV2Pool pool);
```

Lookup a pool for given parameters.

```solidity
function lookupPermissioned(IERC20 _tokenA, IERC20 _tokenB, address accessor, uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2Pool[] memory);
```

Lookup a pool for given parameters.

```solidity
function lookupPermissioned(uint256 startIndex, uint256 endIndex) external view returns (IMaverickV2Pool[] memory);
```

Address of a permissionless pool.

```solidity
function poolAddress(
    uint256 feeAIn,
    uint256 feeBIn,
    uint256 tickSpacing,
    uint256 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    uint8 kinds
) public view returns (IMaverickV2Pool pool);
```

Address of a permissionless pool.

```solidity
function poolAddress(
    uint256 feeAIn,
    uint256 feeBIn,
    uint256 tickSpacing,
    uint256 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    uint8 kinds,
    address accessor
) public view returns (IMaverickV2Pool pool);
```

#### \_slice <a href="#slice" id="slice"></a>

Prune array from storage to subset of array with range \[startIndex, endIndex).

```solidity
function _slice(IMaverickV2Pool[] storage _pools, uint256 startIndex, uint256 endIndex)
    internal
    view
    returns (IMaverickV2Pool[] memory returnPools);
```

**Parameters**

| Name         | Type                | Description                                                  |
| ------------ | ------------------- | ------------------------------------------------------------ |
| `_pools`     | `IMaverickV2Pool[]` | Storage array of full pool list to be sliced.                |
| `startIndex` | `uint256`           | The first index of the pool list in storage to return.       |
| `endIndex`   | `uint256`           | Upper bound index that is not included in the returned list. |

**Returns**

| Name          | Type                | Description                           |
| ------------- | ------------------- | ------------------------------------- |
| `returnPools` | `IMaverickV2Pool[]` | An array of MaverickV2Pool addresses. |

#### \_createChecks <a href="#createchecks" id="createchecks"></a>

Check create pool parameters to ensure they are valid. Reverts on an invalid paramter sets.

```solidity
function _createChecks(
    uint256 feeAIn,
    uint256 feeBIn,
    uint256 tickSpacing,
    uint256 lookback,
    IERC20 tokenA,
    IERC20 tokenB,
    uint8 kinds
) internal view returns (uint64 tokenAScale, uint64 tokenBScale);
```

#### \_checkProtocolFeeRatio <a href="#checkprotocolfeeratio" id="checkprotocolfeeratio"></a>

Checks the validity of the protocol fee ratio.

```solidity
function _checkProtocolFeeRatio(uint8 _protocolFeeRatioD3) internal pure;
```

#### \_checkProtocolLendingFeeRate <a href="#checkprotocollendingfeerate" id="checkprotocollendingfeerate"></a>

Checks the validity of the protocol lending fee rate.

```solidity
function _checkProtocolLendingFeeRate(uint256 _protocolLendingFeeRateD18) internal pure;
```


# MaverickV2Pool

**Inherits:** [IMaverickV2Pool](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/interfaces/imaverickv2pool), [IMaverickV2PoolAdmin](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/interfaces/imaverickv2pooladmin)

Pool contract for Maverick V2. There is no pool owner, but the Factory contract does have the ability to set and collect protocol fees. Users can add liquidity, remove liquidity, swap, and migrate bins up the merge stack. User liquidity is allocated to a recipient and can be assigned, by the sender, to a "subaccount". But liquidity is not transferable. For liquidity transfer and other manipulation capabilities, use the v2-supplemental Position (ERC-721 interfaces) or BoostedPosition (ERC-20 interfaces) contracts.

This contract does not support rebasing tokens. However, there are limited protections built in for tokens that have a negative rebase. On negative rebase, the pool's internal accounting of its balances will diverge from the token balance accounting. In order to interact with swap or add liquidity after a negative rebase, a user will have first make the pool solvent by transfering the pool enough asset so the two accounting systmes match. Post negative rebase, users will be able to remove their pro rata balance from the pool. Any positive rebase of the pool's balance will be accrued to the next add or swap user. That is, the proceeds of a positive rebase will not be distributed to all LPs.

Tokens such as stETH that have a mismatch between the amount transfered and the balanceOf of a user post-transfer are not supported by this contract. Such a mismatch between transfer and balanceOf will result in a revert when attempting to add liquidity.

### State Variables <a href="#state-variables" id="state-variables"></a>

#### accessor <a href="#accessor" id="accessor"></a>

Address of Pool accessor. This is Zero address for permissionless pools.

```solidity
address public immutable accessor;
```

#### kinds <a href="#kinds" id="kinds"></a>

1-15 number to represent the active kinds. 0b0001 = static; 0b0010 = right; 0b0100 = left; 0b1000 = both; E.g. a pool with all 4 modes will have kinds = b1111 = 15

```solidity
uint8 public immutable kinds;
```

#### protocolFeeA <a href="#protocolfeea" id="protocolfeea"></a>

Accumulated tokenA protocol fee.

```solidity
uint128 public protocolFeeA;
```

#### protocolFeeB <a href="#protocolfeeb" id="protocolfeeb"></a>

Accumulated tokenB protocol fee.

```solidity
uint128 public protocolFeeB;
```

#### tickSpacing <a href="#tickspacing" id="tickspacing"></a>

TickSpacing of pool where 1.0001^tickSpacing is the bin width.

```solidity
uint256 public immutable tickSpacing;
```

#### tokenA <a href="#tokena" id="tokena"></a>

Pool tokenA. Address of tokenA is such that tokenA < tokenB.

```solidity
IERC20 public immutable tokenA;
```

#### tokenB <a href="#tokenb" id="tokenb"></a>

Pool tokenB.

```solidity
IERC20 public immutable tokenB;
```

#### lookback <a href="#lookback" id="lookback"></a>

Lookback period of pool in seconds.

```solidity
uint256 public immutable lookback;
```

#### factory <a href="#factory" id="factory"></a>

Deploying factory of the pool and also contract that has ability to set and collect protocol fees for the pool.

```solidity
IMaverickV2Factory public immutable factory;
```

#### tokenAScale <a href="#tokenascale" id="tokenascale"></a>

Most significant bit of scale value is a flag to indicate whether tokenA has more or less than 18 decimals. Scale is used in conjuction with Math.toScale/Math.fromScale functions to convert from token amounts to D18 scale internal pool accounting.

```solidity
uint256 public immutable tokenAScale;
```

#### tokenBScale <a href="#tokenbscale" id="tokenbscale"></a>

Most significant bit of scale value is a flag to indicate whether tokenA has more or less than 18 decimals. Scale is used in conjuction with Math.toScale/Math.fromScale functions to convert from token amounts to D18 scale internal pool accounting.

```solidity
uint256 public immutable tokenBScale;
```

#### lendingFeeRateD18 <a href="#lendingfeerated18" id="lendingfeerated18"></a>

```solidity
uint256 public lendingFeeRateD18;
```

#### bins <a href="#bins" id="bins"></a>

Mapping of Bin objects for the pool. Each Bin is indexed by an incrementing uint32 ID. There are at most 4 bins per tick. Bin state is viewable with getBin().

```solidity
mapping(uint32 => Bin.Instance) internal bins;
```

#### ticks <a href="#ticks" id="ticks"></a>

Mapping of Tick objects for the pool. There are at most 4 bins per tick. Ticks are indexed by their position in the log price domain. The number of ticks is limited by Constants.sol/MAX\_TICK. Tick state is viewable with getTick().

```solidity
mapping(int32 => TickState) internal ticks;
```

#### \_state <a href="#state" id="state"></a>

Dynamic state variables of the pool. Takes up two storage slots.

```solidity
State internal _state;
```

#### \_feeAIn <a href="#feeain" id="feeain"></a>

Fee rate for tokenA in swaps in 18-decimal format.

```solidity
uint256 internal immutable _feeAIn;
```

#### \_feeBIn <a href="#feebin" id="feebin"></a>

Fee rate for tokenB in swaps in 18-decimal format.

```solidity
uint256 internal immutable _feeBIn;
```

### Functions <a href="#functions" id="functions"></a>

#### constructor <a href="#constructor" id="constructor"></a>

Constructor is called by the deployer contract. In the constructor the pool calls back to the deployer to set the pool parameters.

```solidity
constructor();
```

#### addLiquidity <a href="#addliquidity" id="addliquidity"></a>

Add liquidity to a pool. This function allows users to deposit tokens into a liquidity pool.

This function will call `maverickV2AddLiquidityCallback` on the calling contract to collect the tokenA/tokenB payment.

```solidity
function addLiquidity(address recipient, uint256 subaccount, AddLiquidityParams calldata params, bytes calldata data)
    public
    virtual
    returns (uint256 tokenAAmount, uint256 tokenBAmount, uint32[] memory binIds);
```

**Parameters**

| Name         | Type                 | Description                                                                              |
| ------------ | -------------------- | ---------------------------------------------------------------------------------------- |
| `recipient`  | `address`            | The account that will receive credit for the added liquidity.                            |
| `subaccount` | `uint256`            | The account that will receive credit for the added liquidity.                            |
| `params`     | `AddLiquidityParams` | Parameters containing the details for adding liquidity, such as token types and amounts. |
| `data`       | `bytes`              | Bytes information that gets passed to the callback.                                      |

**Returns**

| Name           | Type       | Description                                        |
| -------------- | ---------- | -------------------------------------------------- |
| `tokenAAmount` | `uint256`  | The amount of token A added to the pool.           |
| `tokenBAmount` | `uint256`  | The amount of token B added to the pool.           |
| `binIds`       | `uint32[]` | An array of bin IDs where the liquidity is stored. |

#### migrateBinUpStack <a href="#migratebinupstack" id="migratebinupstack"></a>

Migrate bins up the linked list of merged bins so that its mergeId is the currrent active bin.

Liquidy can only be removed from a bin that is either unmerged or has a mergeId of an unmerged bin. If a bin is merged more than one level deep, it must be migrated up the merge stack to the root bin before liquidity removal.

```solidity
function migrateBinUpStack(uint32 binId, uint32 maxRecursion) public virtual;
```

**Parameters**

| Name           | Type     | Description                                    |
| -------------- | -------- | ---------------------------------------------- |
| `binId`        | `uint32` | The ID of the bin to migrate.                  |
| `maxRecursion` | `uint32` | The maximum recursion depth for the migration. |

#### removeLiquidity <a href="#removeliquidity" id="removeliquidity"></a>

Removes liquidity from the pool.

Liquidy can only be removed from a bin that is either unmerged or has a mergeId of an unmerged bin. If a bin is merged more than one level deep, it must be migrated up the merge stack to the root bin before liquidity removal.

```solidity
function removeLiquidity(address recipient, uint256 subaccount, RemoveLiquidityParams calldata params)
    public
    virtual
    returns (uint256 tokenAOut, uint256 tokenBOut);
```

**Parameters**

| Name         | Type                    | Description                            |
| ------------ | ----------------------- | -------------------------------------- |
| `recipient`  | `address`               | The address to receive the tokens.     |
| `subaccount` | `uint256`               | The subaccount for the recipient.      |
| `params`     | `RemoveLiquidityParams` | The parameters for removing liquidity. |

**Returns**

| Name        | Type      | Description                     |
| ----------- | --------- | ------------------------------- |
| `tokenAOut` | `uint256` | The amount of token A received. |
| `tokenBOut` | `uint256` | The amount of token B received. |

#### swap <a href="#swap" id="swap"></a>

Swap tokenA/tokenB assets in the pool. The swap user has two options for funding their swap.

* The user can push the input token amount to the pool before calling the swap function. In order to avoid having the pool call the callback, the user should pass a zero-length `data` bytes object with the swap call.
* The user can send the input token amount to the pool when the pool calls the `maverickV2SwapCallback` function on the calling contract. That callback has input parameters that specify the token address of the input token, the input and output amounts, and the bytes data sent to the swap function.

If the users elects to do a callback-based swap, the output assets will be sent before the callback is called, allowing the user to execute flash swaps. However, the pool does have reentrancy protection, so a swapper will not be able to interact with the same pool again while they are in the callback function.

```solidity
function swap(address recipient, SwapParams memory params, bytes calldata data)
    public
    virtual
    returns (uint256 amountIn, uint256 amountOut);
```

**Parameters**

| Name        | Type         | Description                                         |
| ----------- | ------------ | --------------------------------------------------- |
| `recipient` | `address`    | The address to receive the output tokens.           |
| `params`    | `SwapParams` | Parameters containing the details of the swap       |
| `data`      | `bytes`      | Bytes information that gets passed to the callback. |

#### setFee <a href="#setfee" id="setfee"></a>

Sets fee for permissioned pools. May only be called by the accessor.

```solidity
function setFee(uint256, uint256) public virtual;
```

#### flashLoan <a href="#flashloan" id="flashloan"></a>

Loan tokenA/tokenB assets from the pool to recipient. The fee rate of a loan is determined by `lendingFeeRateD18`, which is set at the protocol level by the factory. This function calls `maverickV2FlashLoanCallback` on the calling contract. At the end of the callback, the caller must pay back the loan with fee (if there is a fee).

```solidity
function flashLoan(address recipient, uint256 amountA, uint256 amountB, bytes calldata data)
    public
    virtual
    returns (uint128 lendingFeeA, uint128 lendingFeeB);
```

**Parameters**

| Name        | Type      | Description                                         |
| ----------- | --------- | --------------------------------------------------- |
| `recipient` | `address` | The address to receive the loaned tokens.           |
| `amountA`   | `uint256` |                                                     |
| `amountB`   | `uint256` | Loan amount of tokenA sent to recipient.            |
| `data`      | `bytes`   | Bytes information that gets passed to the callback. |

#### adminAction <a href="#adminaction" id="adminaction"></a>

Perform pool admin action; this function can only be called by the pool factory contract. When called by other callers, this function will revert.

```solidity
function adminAction(AdminAction action, uint256 value) external;
```

**Parameters**

| Name     | Type          | Description                                                                             |
| -------- | ------------- | --------------------------------------------------------------------------------------- |
| `action` | `AdminAction` | Selector of admin action from AdminAction enum.                                         |
| `value`  | `uint256`     | Applicable for "setting" admin actions and is the new value of the parameter being set. |

#### \_lockPool <a href="#lockpool" id="lockpool"></a>

Internal function to lock the pool.

```solidity
function _lockPool() internal returns (State memory currentState);
```

#### \_unlockPool <a href="#unlockpool" id="unlockpool"></a>

Internal function to unlock the pool.

```solidity
function _unlockPool() internal;
```

#### getState <a href="#getstate" id="getstate"></a>

External function to get the state of the pool.

```solidity
function getState() external view returns (State memory);
```

#### getCurrentTwa <a href="#getcurrenttwa" id="getcurrenttwa"></a>

External function to get the current time-weighted average price.

```solidity
function getCurrentTwa() external view returns (int256);
```

#### fee <a href="#fee" id="fee"></a>

Pool swap fee for the given direction (A-in or B-in swap) in 18-decimal format. E.g. 0.01e18 is a 1% swap fee.

```solidity
function fee(bool tokenAIn) public view virtual returns (uint256);
```

#### binIdByTickKind <a href="#binidbytickkind" id="binidbytickkind"></a>

ID of bin at input tick position and kind.

```solidity
function binIdByTickKind(int32 tick, uint256 kind) public view returns (uint32 binId);
```

#### getBin <a href="#getbin" id="getbin"></a>

Return state of Bin at input binId.

```solidity
function getBin(uint32 binId) external view returns (BinState memory bin);
```

#### getTick <a href="#gettick" id="gettick"></a>

Return state of Tick at input tick position.

```solidity
function getTick(int32 tick) external view returns (TickState memory _tick);
```

#### balanceOf <a href="#balanceof" id="balanceof"></a>

Retrieves the balance of a user within a bin.

```solidity
function balanceOf(address user, uint256 subaccount, uint32 binId) external view returns (uint128 lpBalance);
```

**Parameters**

| Name         | Type      | Description                  |
| ------------ | --------- | ---------------------------- |
| `user`       | `address` | The user's address.          |
| `subaccount` | `uint256` | The subaccount for the user. |
| `binId`      | `uint32`  | The ID of the bin.           |

#### \_kindSupportedByPool <a href="#kindsupportedbypool" id="kindsupportedbypool"></a>

Bool indicator of whether the input kind is supported by the pool.

```solidity
function _kindSupportedByPool(uint8 kind) internal view returns (bool);
```

#### \_tickSqrtPriceAndLiquidity <a href="#ticksqrtpriceandliquidity" id="ticksqrtpriceandliquidity"></a>

Retrieves the square root price and liquidity of a tick.

```solidity
function _tickSqrtPriceAndLiquidity(int32 tick)
    internal
    view
    returns (uint256 sqrtLowerTickPrice, uint256 sqrtUpperTickPrice, uint256 sqrtPrice, TickData memory output);
```

**Parameters**

| Name   | Type    | Description     |
| ------ | ------- | --------------- |
| `tick` | `int32` | The tick value. |

**Returns**

| Name                 | Type       | Description                              |
| -------------------- | ---------- | ---------------------------------------- |
| `sqrtLowerTickPrice` | `uint256`  | The square root of the lower tick price. |
| `sqrtUpperTickPrice` | `uint256`  | The square root of the upper tick price. |
| `sqrtPrice`          | `uint256`  | The square root price.                   |
| `output`             | `TickData` | The tick data.                           |

#### \_tokenBalance <a href="#tokenbalance" id="tokenbalance"></a>

Get the balance of a given token.

```solidity
function _tokenBalance(IERC20 token) internal view returns (uint128);
```

**Parameters**

| Name    | Type     | Description                               |
| ------- | -------- | ----------------------------------------- |
| `token` | `IERC20` | The IERC20 token to check the balance of. |

**Returns**

| Name     | Type      | Description               |
| -------- | --------- | ------------------------- |
| `<none>` | `uint128` | The balance of the token. |

#### \_checkTokenSolvency <a href="#checktokensolvency" id="checktokensolvency"></a>

```solidity
function _checkTokenSolvency(IERC20 token, uint256 internalBalance) internal view;
```

#### \_getOrCreateBin <a href="#getorcreatebin" id="getorcreatebin"></a>

Get or create a bin and return its ID and storage reference.

```solidity
function _getOrCreateBin(State memory currentState, uint8 kind, int32 tick)
    internal
    returns (uint32 binId, Bin.Instance storage bin);
```

**Parameters**

| Name           | Type    | Description                                         |
| -------------- | ------- | --------------------------------------------------- |
| `currentState` | `State` | The State struct containing the current state data. |
| `kind`         | `uint8` | The uint8 value representing the kind of bin.       |
| `tick`         | `int32` | The int32 value representing the tick.              |

**Returns**

| Name    | Type           | Description                       |
| ------- | -------------- | --------------------------------- |
| `binId` | `uint32`       | The ID of the bin.                |
| `bin`   | `Bin.Instance` | The storage reference to the bin. |

#### \_moveDirection <a href="#movedirection" id="movedirection"></a>

Merges bins and moves them to a new tick.

```solidity
function _moveDirection(MoveData memory moveData) internal;
```

**Parameters**

| Name       | Type       | Description                                                     |
| ---------- | ---------- | --------------------------------------------------------------- |
| `moveData` | `MoveData` | The MoveData struct containing the necessary data for the move. |

#### \_mergeAndDecommissionBin <a href="#mergeanddecommissionbin" id="mergeanddecommissionbin"></a>

Merges a given bin and removes its former tick so that the bin is no longer active.

```solidity
function _mergeAndDecommissionBin(
    uint32 binIdToBeMerged,
    uint32 parentBinId,
    Bin.Instance storage parentBin,
    IMaverickV2Pool.TickState storage parentBinTickState,
    uint8 kind
) internal returns (uint128 binA, uint128 binB, uint128 mergeBinBalance);
```

**Parameters**

| Name                 | Type                        | Description                                                              |
| -------------------- | --------------------------- | ------------------------------------------------------------------------ |
| `binIdToBeMerged`    | `uint32`                    | binId of the bin being merged.                                           |
| `parentBinId`        | `uint32`                    | binId of the parent bin where the merging bin's liquidity is being sent. |
| `parentBin`          | `Bin.Instance`              | Bin object of parent.                                                    |
| `parentBinTickState` | `IMaverickV2Pool.TickState` | Tick object of the parent bin's tick.                                    |
| `kind`               | `uint8`                     | Kind of the bins.                                                        |

#### \_mergeBinsInList <a href="#mergebinsinlist" id="mergebinsinlist"></a>

Merge bins in moveData.mergeBins into firstBin.

```solidity
function _mergeBinsInList(
    Bin.Instance storage firstBin,
    IMaverickV2Pool.TickState storage firstBinTickState,
    MoveData memory moveData
) internal;
```

**Parameters**

| Name                | Type                        | Description                                         |
| ------------------- | --------------------------- | --------------------------------------------------- |
| `firstBin`          | `Bin.Instance`              | The storage reference to the first bin.             |
| `firstBinTickState` | `IMaverickV2Pool.TickState` | The storage reference to the first bin's TickState. |
| `moveData`          | `MoveData`                  | The MoveData struct containing the necessary data.  |

#### \_moveBinToNewTick <a href="#movebintonewtick" id="movebintonewtick"></a>

Move a bin from one tick to another.

```solidity
function _moveBinToNewTick(
    Bin.Instance storage firstBin,
    IMaverickV2Pool.TickState storage startingTickState,
    IMaverickV2Pool.TickState storage endingTickState,
    MoveData memory moveData
) internal;
```

**Parameters**

| Name                | Type                        | Description                                             |
| ------------------- | --------------------------- | ------------------------------------------------------- |
| `firstBin`          | `Bin.Instance`              | The storage reference to the first bin.                 |
| `startingTickState` | `IMaverickV2Pool.TickState` | The storage reference to the starting tick's TickState. |
| `endingTickState`   | `IMaverickV2Pool.TickState` | The storage reference to the ending tick's TickState.   |
| `moveData`          | `MoveData`                  | The MoveData struct containing the necessary data.      |

#### \_getMovementBinsInRange <a href="#getmovementbinsinrange" id="getmovementbinsinrange"></a>

Finds bins of the same kind within the movement search window.

```solidity
function _getMovementBinsInRange(MoveData memory moveData) internal view;
```

#### \_moveBins <a href="#movebins" id="movebins"></a>

Move bins based on TWAP conditions.

Logic looks left and right of the active tick for movement bins. If there is more than one movement bin of the same kind in this multi-tick window, then these bins will get moved to the TWAP tick and merged into to the Bin with the lowest binId.

```solidity
function _moveBins(int32 startingActiveTick, int32 activeTick, int64 lastTwapD8, int64 newTwapD8, int64 boundary)
    internal;
```

**Parameters**

| Name                 | Type    | Description                                                                    |
| -------------------- | ------- | ------------------------------------------------------------------------------ |
| `startingActiveTick` | `int32` | Active tick at the beginning of the swap.                                      |
| `activeTick`         | `int32` | Active tick at the end of the swap.                                            |
| `lastTwapD8`         | `int64` | TWAP at beginning of the swap.                                                 |
| `newTwapD8`          | `int64` | TWAP at end of the swap.                                                       |
| `boundary`           | `int64` | Distance into a tick that a swap has to move in order to cause a bin movement. |

#### \_swapTick <a href="#swaptick" id="swaptick"></a>

Swap tokens at a specific tick.

```solidity
function _swapTick(State memory currentState, Delta.Instance memory delta)
    internal
    returns (Delta.Instance memory newDelta);
```

**Parameters**

| Name           | Type             | Description                                         |
| -------------- | ---------------- | --------------------------------------------------- |
| `currentState` | `State`          | The State struct containing the current state data. |
| `delta`        | `Delta.Instance` | The Delta.Instance struct containing swap data.     |

**Returns**

| Name       | Type             | Description                        |
| ---------- | ---------------- | ---------------------------------- |
| `newDelta` | `Delta.Instance` | The updated Delta.Instance struct. |

#### \_allocateSwapValuesToTick <a href="#allocateswapvaluestotick" id="allocateswapvaluestotick"></a>

Allocate swap values to bins based on token direction and tick.

```solidity
function _allocateSwapValuesToTick(Delta.Instance memory delta, bool tokenAIn, int32 tick) internal;
```

**Parameters**

| Name       | Type             | Description                                               |
| ---------- | ---------------- | --------------------------------------------------------- |
| `delta`    | `Delta.Instance` | The Delta.Instance struct containing swap data.           |
| `tokenAIn` | `bool`           | A boolean indicating whether token A is being swapped in. |
| `tick`     | `int32`          | The int32 value representing the tick.                    |

### Structs <a href="#structs" id="structs"></a>

#### MoveData <a href="#movedata" id="movedata"></a>

Struct for holding data during bin movement.

```solidity
struct MoveData {
    uint8 kind;
    int32 tickSearchStart;
    int32 tickSearchEnd;
    int32 tickLimit;
    int32 firstBinTick;
    uint32 firstBinId;
    uint128 mergeBinBalance;
    uint128 totalReserveA;
    uint128 totalReserveB;
    uint32[MAX_BINS_TO_MERGE] mergeBins;
    uint256 counter;
}
```


# MaverickV2PoolPermissioned

**Inherits:** [MaverickV2Pool](/technical-reference/maverick-v2/v2-contracts/maverick-v2-amm-contracts/maverickv2pool)

### State Variables <a href="#state-variables" id="state-variables"></a>

#### variableFeeAIn <a href="#variablefeeain" id="variablefeeain"></a>

```solidity
uint128 private variableFeeAIn;
```

#### variableFeeBIn <a href="#variablefeebin" id="variablefeebin"></a>

```solidity
uint128 private variableFeeBIn;
```

### Functions <a href="#functions" id="functions"></a>

#### onlyAccessor <a href="#onlyaccessor" id="onlyaccessor"></a>

```solidity
modifier onlyAccessor();
```

#### addLiquidity <a href="#addliquidity" id="addliquidity"></a>

```solidity
function addLiquidity(address user, uint256 subaccount, AddLiquidityParams calldata params, bytes calldata data)
    public
    override
    onlyAccessor
    returns (uint256 tokenAAmount, uint256 tokenBAmount, uint32[] memory binIds);
```

#### migrateBinUpStack <a href="#migratebinupstack" id="migratebinupstack"></a>

```solidity
function migrateBinUpStack(uint32 binId, uint32 maxRecursion) public override onlyAccessor;
```

#### removeLiquidity <a href="#removeliquidity" id="removeliquidity"></a>

```solidity
function removeLiquidity(address recipient, uint256 subaccount, RemoveLiquidityParams calldata params)
    public
    override
    onlyAccessor
    returns (uint256 tokenAOut, uint256 tokenBOut);
```

#### swap <a href="#swap" id="swap"></a>

```solidity
function swap(address recipient, SwapParams memory params, bytes calldata data)
    public
    override
    onlyAccessor
    returns (uint256 amountIn, uint256 amountOut);
```

#### setFee <a href="#setfee" id="setfee"></a>

```solidity
function setFee(uint256 newFeeAIn, uint256 newFeeBIn) public override onlyAccessor;
```

#### fee <a href="#fee" id="fee"></a>

```solidity
function fee(bool tokenAIn) public view override returns (uint256);
```


# Maverick V2 Reward Contracts


# interfaces

* [IMaverickV2IncentiveMatcher](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2incentivematcher)
* [IMaverickV2IncentiveMatcherFactory](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2incentivematcherfactory)
* [IMaverickV2Reward](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2reward)
* [IMaverickV2RewardFactory](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2rewardfactory)
* [IMaverickV2RewardRouter](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2rewardrouter)
* [IMaverickV2RewardVault](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2rewardvault)
* [IMaverickV2VotingEscrowBase](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2votingescrowbase)
* [IMaverickV2VotingEscrow](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2votingescrow)
* [IMaverickV2VotingEscrowFactory](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2votingescrowfactory)
* [IMaverickV2VotingEscrowLens](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2votingescrowlens)
* [IMaverickV2VotingEscrowWSync](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2votingescrowwsync)


# IMaverickV2IncentiveMatcher

### Functions <a href="#functions" id="functions"></a>

#### checkpointData <a href="#checkpointdata" id="checkpointdata"></a>

This function retrieves checkpoint data for a specific epoch.

```solidity
function checkpointData(uint256 epoch)
    external
    view
    returns (uint128 matchBudget, uint128 voteBudget, uint128 totalVote, uint128 totalExternalIncentivesAdded);
```

**Parameters**

| Name    | Type      | Description                                      |
| ------- | --------- | ------------------------------------------------ |
| `epoch` | `uint256` | The epoch for which to retrieve checkpoint data. |

**Returns**

| Name                           | Type      | Description                                                  |
| ------------------------------ | --------- | ------------------------------------------------------------ |
| `matchBudget`                  | `uint128` | The amount of match tokens budgeted for the epoch.           |
| `voteBudget`                   | `uint128` | The amount of vote tokens budgeted for the epoch.            |
| `totalVote`                    | `uint128` | The total number of votes cast in the epoch.                 |
| `totalExternalIncentivesAdded` | `uint128` | The total amount of external incentives added for the epoch. |

#### checkpointRewardData <a href="#checkpointrewarddata" id="checkpointrewarddata"></a>

This function retrieves checkpoint data for a specific reward contract within an epoch.

```solidity
function checkpointRewardData(uint256 epoch, IMaverickV2Reward rewardContract)
    external
    view
    returns (uint128 votesByReward, uint128 externalIncentivesByReward);
```

**Parameters**

| Name             | Type                | Description                                      |
| ---------------- | ------------------- | ------------------------------------------------ |
| `epoch`          | `uint256`           | The epoch for which to retrieve checkpoint data. |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract.              |

**Returns**

| Name                         | Type      | Description                                                                         |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------- |
| `votesByReward`              | `uint128` | The total number of votes cast for the reward contract in the epoch.                |
| `externalIncentivesByReward` | `uint128` | The total amount of external incentives added for the reward contract in the epoch. |

#### isEpoch <a href="#isepoch" id="isepoch"></a>

This function checks if a given epoch is valid.

```solidity
function isEpoch(uint256 epoch) external pure returns (bool _isEpoch);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name       | Type   | Description                                                |
| ---------- | ------ | ---------------------------------------------------------- |
| `_isEpoch` | `bool` | True if the epoch input is a valid epoch, False otherwise. |

#### lastEpoch <a href="#lastepoch" id="lastepoch"></a>

This function retrieves the number of the most recently completed epoch.

```solidity
function lastEpoch() external view returns (uint256 epoch);
```

**Returns**

| Name    | Type      | Description                   |
| ------- | --------- | ----------------------------- |
| `epoch` | `uint256` | The number of the last epoch. |

#### epochIsOver <a href="#epochisover" id="epochisover"></a>

This function checks if a specific epoch has ended.

```solidity
function epochIsOver(uint256 epoch) external view returns (bool isOver);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name     | Type   | Description                                   |
| -------- | ------ | --------------------------------------------- |
| `isOver` | `bool` | True if the epoch has ended, False otherwise. |

#### vetoingIsActive <a href="#vetoingisactive" id="vetoingisactive"></a>

This function checks if the vetoing period is active for a specific epoch.

```solidity
function vetoingIsActive(uint256 epoch) external view returns (bool isActive);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name       | Type   | Description                                            |
| ---------- | ------ | ------------------------------------------------------ |
| `isActive` | `bool` | True if the vetoing period is active, False otherwise. |

#### votingIsActive <a href="#votingisactive" id="votingisactive"></a>

This function checks if the voting period is active for a specific epoch.

```solidity
function votingIsActive(uint256 epoch) external view returns (bool isActive);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name       | Type   | Description                                           |
| ---------- | ------ | ----------------------------------------------------- |
| `isActive` | `bool` | True if the voting period is active, False otherwise. |

#### currentEpoch <a href="#currentepoch" id="currentepoch"></a>

This function retrieves the current epoch number.

```solidity
function currentEpoch() external view returns (uint256 epoch);
```

**Returns**

| Name    | Type      | Description               |
| ------- | --------- | ------------------------- |
| `epoch` | `uint256` | The current epoch number. |

#### votingStart <a href="#votingstart" id="votingstart"></a>

Returns the timestamp when voting starts. This is also the voting snapshot timestamp where the voting power for users is determined for that epoch.

```solidity
function votingStart(uint256 epoch) external pure returns (uint256 start);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

#### addMatchingBudget <a href="#addmatchingbudget" id="addmatchingbudget"></a>

This function allows adding a new budget to the matcher contract.

called by protocol to add base token budget to an epoch that will be used for matching incentives. Can be called anytime before or during the epoch.

```solidity
function addMatchingBudget(uint128 matchBudget, uint128 voteBudget, uint256 epoch) external;
```

**Parameters**

| Name          | Type      | Description                              |
| ------------- | --------- | ---------------------------------------- |
| `matchBudget` | `uint128` | The amount of match tokens to add.       |
| `voteBudget`  | `uint128` | The amount of vote tokens to add.        |
| `epoch`       | `uint256` | The epoch for which the budget is added. |

#### rewardHasVe <a href="#rewardhasve" id="rewardhasve"></a>

This function checks if a specific reward contract has a veToken staking option.

For a rewards contract to be eligible for matching, the rewards contract must have the baseToken's ve contract as a locking option.

```solidity
function rewardHasVe(IMaverickV2Reward rewardContract) external view returns (bool hasVe);
```

**Parameters**

| Name             | Type                | Description                         |
| ---------------- | ------------------- | ----------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract. |

**Returns**

| Name    | Type   | Description                                                                |
| ------- | ------ | -------------------------------------------------------------------------- |
| `hasVe` | `bool` | True if the reward contract has a veToken staking option, False otherwise. |

#### addIncentives <a href="#addincentives" id="addincentives"></a>

This function allows adding a new incentive to the system.

Called by protocol to add incentives to a given rewards contract.

```solidity
function addIncentives(IMaverickV2Reward rewardContract, uint256 amount, uint256 _duration)
    external
    returns (uint256 duration);
```

**Parameters**

| Name             | Type                | Description                                                       |
| ---------------- | ------------------- | ----------------------------------------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract for the incentive.             |
| `amount`         | `uint256`           | The total amount of the incentive.                                |
| `_duration`      | `uint256`           | The duration (in epochs) for which this incentive will be active. |

**Returns**

| Name       | Type      | Description                                                  |
| ---------- | --------- | ------------------------------------------------------------ |
| `duration` | `uint256` | The duration (in epochs) for which this incentive was added. |

#### vote <a href="#vote" id="vote"></a>

This function allows a user to cast a vote for specific reward contracts.

Called by ve token holders to vote for rewards contracts in a given epoch. voteTargets have to be passed in ascending sort order as a unique set of values. weights are relative values that are scales by the user's voting power.

```solidity
function vote(IMaverickV2Reward[] memory voteTargets, uint256[] memory weights) external;
```

**Parameters**

| Name          | Type                  | Description                                                 |
| ------------- | --------------------- | ----------------------------------------------------------- |
| `voteTargets` | `IMaverickV2Reward[]` | An array of addresses for the reward contracts to vote for. |
| `weights`     | `uint256[]`           | An array of weights for each vote target.                   |

#### veto <a href="#veto" id="veto"></a>

This function allows casting a veto on a specific reward contract for an epoch.

Veto a given rewards contract. If a rewards contract is vetoed, it will not receive any matching incentives. Rewards contracts can only be vetoed in the VETO\_PERIOD seconds after the end of the epoch.

```solidity
function veto(IMaverickV2Reward rewardContract) external returns (uint128 vetoPower);
```

**Parameters**

| Name             | Type                | Description                                 |
| ---------------- | ------------------- | ------------------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract to veto. |

**Returns**

| Name        | Type      | Description                                                                   |
| ----------- | --------- | ----------------------------------------------------------------------------- |
| `vetoPower` | `uint128` | The amount of veto power used (based on the user's epoch match contribution). |

#### distribute <a href="#distribute" id="distribute"></a>

This function allows distributing incentives for a specific reward contract in a particular epoch.

Called by any user to distribute matching incentives to a given reward contract for a given epoch. Call is only functional after the vetoing period for the epoch is over.

```solidity
function distribute(IMaverickV2Reward rewardContract, uint256 epoch) external returns (uint256 matchAmount);
```

**Parameters**

| Name             | Type                | Description                                                      |
| ---------------- | ------------------- | ---------------------------------------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract to distribute incentives for. |
| `epoch`          | `uint256`           | The epoch for which to distribute incentives.                    |

**Returns**

| Name          | Type      | Description                                |
| ------------- | --------- | ------------------------------------------ |
| `matchAmount` | `uint256` | The amount of matching tokens distributed. |

#### rolloverExcessBudget <a href="#rolloverexcessbudget" id="rolloverexcessbudget"></a>

This function allows rolling over excess budget from a previous epoch to a new epoch.

*Excess vote match budget amounts that have not been distributed will not rollover and will become permanently locked. To avoid this, a matcher should call distribute on all rewards contracts before calling rollover.*

```solidity
function rolloverExcessBudget(uint256 matchedEpoch, uint256 newEpoch)
    external
    returns (uint256 matchRolloverAmount, uint256 voteRolloverAmount);
```

**Parameters**

| Name           | Type      | Description                                   |
| -------------- | --------- | --------------------------------------------- |
| `matchedEpoch` | `uint256` | The epoch from which to roll over the budget. |
| `newEpoch`     | `uint256` | The epoch to which to roll over the budget.   |

**Returns**

| Name                  | Type      | Description                             |
| --------------------- | --------- | --------------------------------------- |
| `matchRolloverAmount` | `uint256` | The amount of match tokens rolled over. |
| `voteRolloverAmount`  | `uint256` | The amount of vote tokens rolled over.  |

#### EPOCH\_PERIOD <a href="#epoch_period" id="epoch_period"></a>

This function retrieves the epoch period length.

```solidity
function EPOCH_PERIOD() external returns (uint256);
```

#### PRE\_VOTE\_PERIOD <a href="#pre_vote_period" id="pre_vote_period"></a>

This function retrieves the period length of the epoch before voting starts. After an epoch begins, there is a window of time where voting is not possible which is the value this function returns.

```solidity
function PRE_VOTE_PERIOD() external returns (uint256);
```

#### VETO\_PERIOD <a href="#veto_period" id="veto_period"></a>

This function retrieves the vetoing period length.

```solidity
function VETO_PERIOD() external returns (uint256);
```

#### NOTIFY\_PERIOD <a href="#notify_period" id="notify_period"></a>

The function retrieves the notify period length, which is the amount of time in seconds during which the matching reward will be distributed through the rewards contract.

```solidity
function NOTIFY_PERIOD() external returns (uint256);
```

#### baseToken <a href="#basetoken" id="basetoken"></a>

This function retrieves the base token used by the IncentiveMatcher contract.

```solidity
function baseToken() external returns (IERC20);
```

**Returns**

| Name     | Type     | Description                    |
| -------- | -------- | ------------------------------ |
| `<none>` | `IERC20` | The address of the base token. |

#### factory <a href="#factory" id="factory"></a>

This function retrieves the address of the MaverickV2RewardFactory contract.

```solidity
function factory() external returns (IMaverickV2RewardFactory);
```

**Returns**

| Name     | Type                       | Description                                          |
| -------- | -------------------------- | ---------------------------------------------------- |
| `<none>` | `IMaverickV2RewardFactory` | The address of the MaverickV2RewardFactory contract. |

#### veToken <a href="#vetoken" id="vetoken"></a>

This function retrieves the address of the veToken contract.

```solidity
function veToken() external returns (IMaverickV2VotingEscrow);
```

**Returns**

| Name     | Type                      | Description                          |
| -------- | ------------------------- | ------------------------------------ |
| `<none>` | `IMaverickV2VotingEscrow` | The address of the veToken contract. |

#### hasVoted <a href="#hasvoted" id="hasvoted"></a>

This function checks if a specific user has voted in a particular epoch.

```solidity
function hasVoted(address user, uint256 epoch) external returns (bool);
```

**Parameters**

| Name    | Type      | Description              |
| ------- | --------- | ------------------------ |
| `user`  | `address` | The address of the user. |
| `epoch` | `uint256` | The epoch to check.      |

**Returns**

| Name     | Type   | Description                                  |
| -------- | ------ | -------------------------------------------- |
| `<none>` | `bool` | True if the user has voted, False otherwise. |

#### hasVetoed <a href="#hasvetoed" id="hasvetoed"></a>

This function checks if a specific matcher has cast a veto on a reward contract for an epoch.

```solidity
function hasVetoed(address matcher, IMaverickV2Reward rewardContract, uint256 epoch) external returns (bool);
```

**Parameters**

| Name             | Type                | Description                                   |
| ---------------- | ------------------- | --------------------------------------------- |
| `matcher`        | `address`           | The address of the IncentiveMatcher contract. |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract.           |
| `epoch`          | `uint256`           | The epoch to check.                           |

**Returns**

| Name     | Type   | Description                                           |
| -------- | ------ | ----------------------------------------------------- |
| `<none>` | `bool` | True if the matcher has cast a veto, False otherwise. |

#### hasDistributed <a href="#hasdistributed" id="hasdistributed"></a>

This function checks if incentives have been distributed for a specific reward contract in an epoch.

```solidity
function hasDistributed(IMaverickV2Reward rewardContract, uint256 epoch) external returns (bool);
```

**Parameters**

| Name             | Type                | Description                         |
| ---------------- | ------------------- | ----------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract. |
| `epoch`          | `uint256`           | The epoch to check.                 |

**Returns**

| Name     | Type   | Description                                                |
| -------- | ------ | ---------------------------------------------------------- |
| `<none>` | `bool` | True if incentives have been distributed, False otherwise. |

#### epochEnd <a href="#epochend" id="epochend"></a>

This function calculates the end timestamp for a specific epoch.

```solidity
function epochEnd(uint256 epoch) external pure returns (uint256 end);
```

**Parameters**

| Name    | Type      | Description                                         |
| ------- | --------- | --------------------------------------------------- |
| `epoch` | `uint256` | The epoch for which to calculate the end timestamp. |

**Returns**

| Name  | Type      | Description                     |
| ----- | --------- | ------------------------------- |
| `end` | `uint256` | The end timestamp of the epoch. |

#### vetoingEnd <a href="#vetoingend" id="vetoingend"></a>

This function calculates the end timestamp for the vetoing period of a specific epoch.

```solidity
function vetoingEnd(uint256 epoch) external pure returns (uint256 end);
```

**Parameters**

| Name    | Type      | Description                                                        |
| ------- | --------- | ------------------------------------------------------------------ |
| `epoch` | `uint256` | The epoch for which to calculate the vetoing period end timestamp. |

**Returns**

| Name  | Type      | Description                                            |
| ----- | --------- | ------------------------------------------------------ |
| `end` | `uint256` | The end timestamp of the vetoing period for the epoch. |

#### vetoingIsOver <a href="#vetoingisover" id="vetoingisover"></a>

This function checks if the vetoing period is over for a specific epoch.

```solidity
function vetoingIsOver(uint256 epoch) external view returns (bool isOver);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name     | Type   | Description                                                                |
| -------- | ------ | -------------------------------------------------------------------------- |
| `isOver` | `bool` | True if the vetoing period has ended for the given epoch, False otherwise. |

### Events <a href="#events" id="events"></a>

#### BudgetAdded <a href="#budgetadded" id="budgetadded"></a>

```solidity
event BudgetAdded(address matcher, uint256 matchRolloverAmount, uint256 voteRolloverAmount, uint256 epoch);
```

#### BudgetRolledOver <a href="#budgetrolledover" id="budgetrolledover"></a>

```solidity
event BudgetRolledOver(
    address matcher, uint256 matchRolloverAmount, uint256 voteRolloverAmount, uint256 matchedEpoch, uint256 newEpoch
);
```

#### IncentiveAdded <a href="#incentiveadded" id="incentiveadded"></a>

```solidity
event IncentiveAdded(uint256 amount, uint256 epoch, IMaverickV2Reward rewardContract, uint256 duration);
```

#### Vote <a href="#vote-1" id="vote-1"></a>

```solidity
event Vote(address voter, uint256 epoch, IMaverickV2Reward rewardContract, uint256 vote);
```

#### Distribute <a href="#distribute-1" id="distribute-1"></a>

```solidity
event Distribute(uint256 epoch, IMaverickV2Reward rewardContract, IERC20 _baseToken, uint256 matchAmount);
```

#### Veto <a href="#veto-1" id="veto-1"></a>

```solidity
event Veto(address matcher, uint256 epoch, IMaverickV2Reward rewardContract, uint256 amount, uint256 vetoPower);
```

### Errors <a href="#errors" id="errors"></a>

#### IncentiveMatcherInvalidEpoch <a href="#incentivematcherinvalidepoch" id="incentivematcherinvalidepoch"></a>

```solidity
error IncentiveMatcherInvalidEpoch(uint256 epoch);
```

#### IncentiveMatcherNotRewardFactoryContract <a href="#incentivematchernotrewardfactorycontract" id="incentivematchernotrewardfactorycontract"></a>

```solidity
error IncentiveMatcherNotRewardFactoryContract(IMaverickV2Reward rewardContract);
```

#### IncentiveMatcherEpochHasNotEnded <a href="#incentivematcherepochhasnotended" id="incentivematcherepochhasnotended"></a>

```solidity
error IncentiveMatcherEpochHasNotEnded(uint256 currentTime, uint256 epochEnd);
```

#### IncentiveMatcherVotePeriodNotActive <a href="#incentivematchervoteperiodnotactive" id="incentivematchervoteperiodnotactive"></a>

```solidity
error IncentiveMatcherVotePeriodNotActive(uint256 currentTime, uint256 voteStart, uint256 voteEnd);
```

#### IncentiveMatcherVetoPeriodNotActive <a href="#incentivematchervetoperiodnotactive" id="incentivematchervetoperiodnotactive"></a>

```solidity
error IncentiveMatcherVetoPeriodNotActive(uint256 currentTime, uint256 vetoStart, uint256 vetoEnd);
```

#### IncentiveMatcherVetoPeriodHasNotEnded <a href="#incentivematchervetoperiodhasnotended" id="incentivematchervetoperiodhasnotended"></a>

```solidity
error IncentiveMatcherVetoPeriodHasNotEnded(uint256 currentTime, uint256 voteEnd);
```

#### IncentiveMatcherSenderHasAlreadyVoted <a href="#incentivematchersenderhasalreadyvoted" id="incentivematchersenderhasalreadyvoted"></a>

```solidity
error IncentiveMatcherSenderHasAlreadyVoted();
```

#### IncentiveMatcherSenderHasNoVotingPower <a href="#incentivematchersenderhasnovotingpower" id="incentivematchersenderhasnovotingpower"></a>

```solidity
error IncentiveMatcherSenderHasNoVotingPower(address voter, uint256 voteSnapshotTimestamp);
```

#### IncentiveMatcherInvalidTargetOrder <a href="#incentivematcherinvalidtargetorder" id="incentivematcherinvalidtargetorder"></a>

```solidity
error IncentiveMatcherInvalidTargetOrder(IMaverickV2Reward lastReward, IMaverickV2Reward voteReward);
```

#### IncentiveMatcherInvalidVote <a href="#incentivematcherinvalidvote" id="incentivematcherinvalidvote"></a>

```solidity
error IncentiveMatcherInvalidVote(
    IMaverickV2Reward rewardContract, uint256 voteWeights, uint256 totalVoteWeight, uint256 vote
);
```

#### IncentiveMatcherNoExternalIncentivesToDistributed <a href="#incentivematchernoexternalincentivestodistributed" id="incentivematchernoexternalincentivestodistributed"></a>

```solidity
error IncentiveMatcherNoExternalIncentivesToDistributed(IMaverickV2Reward rewardContract, uint256 epoch);
```

#### IncentiveMatcherEpochAlreadyDistributed <a href="#incentivematcherepochalreadydistributed" id="incentivematcherepochalreadydistributed"></a>

```solidity
error IncentiveMatcherEpochAlreadyDistributed(uint256 epoch, IMaverickV2Reward rewardContract);
```

#### IncentiveMatcherEpochHasPassed <a href="#incentivematcherepochhaspassed" id="incentivematcherepochhaspassed"></a>

```solidity
error IncentiveMatcherEpochHasPassed(uint256 epoch);
```

#### IncentiveMatcherRewardDoesNotHaveVeStakingOption <a href="#incentivematcherrewarddoesnothavevestakingoption" id="incentivematcherrewarddoesnothavevestakingoption"></a>

```solidity
error IncentiveMatcherRewardDoesNotHaveVeStakingOption();
```

#### IncentiveMatcherMatcherAlreadyVetoed <a href="#incentivematchermatcheralreadyvetoed" id="incentivematchermatcheralreadyvetoed"></a>

```solidity
error IncentiveMatcherMatcherAlreadyVetoed(address matcher, IMaverickV2Reward rewardContract, uint256 epoch);
```

#### IncentiveMatcherNothingToRollover <a href="#incentivematchernothingtorollover" id="incentivematchernothingtorollover"></a>

```solidity
error IncentiveMatcherNothingToRollover(address matcher, uint256 matchedEpoch);
```


# IMaverickV2IncentiveMatcherFactory

### Functions <a href="#functions" id="functions"></a>

#### incentiveMatcherParameters <a href="#incentivematcherparameters" id="incentivematcherparameters"></a>

```solidity
function incentiveMatcherParameters()
    external
    view
    returns (IERC20 baseToken, IMaverickV2VotingEscrow veToken, IMaverickV2RewardFactory factory);
```

#### veFactory <a href="#vefactory" id="vefactory"></a>

This function retrieves the address of the MaverickV2VotingEscrowFactory contract.

```solidity
function veFactory() external view returns (IMaverickV2VotingEscrowFactory);
```

**Returns**

| Name     | Type                             | Description                                                |
| -------- | -------------------------------- | ---------------------------------------------------------- |
| `<none>` | `IMaverickV2VotingEscrowFactory` | The address of the MaverickV2VotingEscrowFactory contract. |

#### rewardFactory <a href="#rewardfactory" id="rewardfactory"></a>

This function retrieves the address of the MaverickV2RewardFactory contract.

```solidity
function rewardFactory() external view returns (IMaverickV2RewardFactory);
```

**Returns**

| Name     | Type                       | Description                                          |
| -------- | -------------------------- | ---------------------------------------------------- |
| `<none>` | `IMaverickV2RewardFactory` | The address of the MaverickV2RewardFactory contract. |

#### isFactoryIncentiveMatcher <a href="#isfactoryincentivematcher" id="isfactoryincentivematcher"></a>

This function checks if the current contract is a factory contract for IncentiveMatchers.

```solidity
function isFactoryIncentiveMatcher(IMaverickV2IncentiveMatcher incentiveMatcher)
    external
    view
    returns (bool isFactoryContract);
```

**Parameters**

| Name               | Type                          | Description                                                 |
| ------------------ | ----------------------------- | ----------------------------------------------------------- |
| `incentiveMatcher` | `IMaverickV2IncentiveMatcher` | The address of the corresponding IncentiveMatcher contract. |

**Returns**

| Name                | Type   | Description                                                  |
| ------------------- | ------ | ------------------------------------------------------------ |
| `isFactoryContract` | `bool` | True if the contract is a factory contract, False otherwise. |

#### incentiveMatcherForVe <a href="#incentivematcherforve" id="incentivematcherforve"></a>

This function retrieves the address of the IncentiveMatcher contract associated with the current veToken.

```solidity
function incentiveMatcherForVe(IMaverickV2VotingEscrow veToken)
    external
    view
    returns (IMaverickV2IncentiveMatcher incentiveMatcher);
```

**Parameters**

| Name      | Type                      | Description                         |
| --------- | ------------------------- | ----------------------------------- |
| `veToken` | `IMaverickV2VotingEscrow` | The voting escrow token to look up. |

**Returns**

| Name               | Type                          | Description                                                 |
| ------------------ | ----------------------------- | ----------------------------------------------------------- |
| `incentiveMatcher` | `IMaverickV2IncentiveMatcher` | The address of the corresponding IncentiveMatcher contract. |

#### createIncentiveMatcher <a href="#createincentivematcher" id="createincentivematcher"></a>

This function creates a new IncentiveMatcher contract for a given base token. The basetoken is required to have a deployed ve token before incentive matcher can be created. If no ve token exists, this function will revert. A ve token can be created with the ve token factory: `veFactory()`.

```solidity
function createIncentiveMatcher(IERC20 baseToken)
    external
    returns (IMaverickV2VotingEscrow veToken, IMaverickV2IncentiveMatcher incentiveMatcher);
```

**Parameters**

| Name        | Type     | Description                                  |
| ----------- | -------- | -------------------------------------------- |
| `baseToken` | `IERC20` | The base token for the new IncentiveMatcher. |

**Returns**

| Name               | Type                          | Description                                                 |
| ------------------ | ----------------------------- | ----------------------------------------------------------- |
| `veToken`          | `IMaverickV2VotingEscrow`     | The voting escrow token for the IncentiveMatcher.           |
| `incentiveMatcher` | `IMaverickV2IncentiveMatcher` | The address of the newly created IncentiveMatcher contract. |

#### incentiveMatchers <a href="#incentivematchers" id="incentivematchers"></a>

This function retrieves a list of existing IncentiveMatcher contracts.

```solidity
function incentiveMatchers(uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2IncentiveMatcher[] memory returnElements);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `startIndex` | `uint256` | The starting index of the list to retrieve. |
| `endIndex`   | `uint256` | The ending index of the list to retrieve.   |

**Returns**

| Name             | Type                            | Description                                                        |
| ---------------- | ------------------------------- | ------------------------------------------------------------------ |
| `returnElements` | `IMaverickV2IncentiveMatcher[]` | An array of IncentiveMatcher contracts within the specified range. |

#### incentiveMatchersLength <a href="#incentivematcherslength" id="incentivematcherslength"></a>

This function returns the total number of existing IncentiveMatcher contracts.

```solidity
function incentiveMatchersLength() external view returns (uint256 length);
```

#### incentiveMatcherAddress <a href="#incentivematcheraddress" id="incentivematcheraddress"></a>

This function retrieves the address of the IncentiveMatcher contract associated with a given veToken.

```solidity
function incentiveMatcherAddress(IMaverickV2VotingEscrow veToken)
    external
    view
    returns (IMaverickV2IncentiveMatcher incentiveMatcher);
```

**Parameters**

| Name      | Type                      | Description                                                                       |
| --------- | ------------------------- | --------------------------------------------------------------------------------- |
| `veToken` | `IMaverickV2VotingEscrow` | The voting escrow token for which to retrieve the corresponding IncentiveMatcher. |

**Returns**

| Name               | Type                          | Description                                                               |
| ------------------ | ----------------------------- | ------------------------------------------------------------------------- |
| `incentiveMatcher` | `IMaverickV2IncentiveMatcher` | The address of the IncentiveMatcher contract associated with the veToken. |

### Errors <a href="#errors" id="errors"></a>

#### VotingEscrowTokenDoesNotExists <a href="#votingescrowtokendoesnotexists" id="votingescrowtokendoesnotexists"></a>

```solidity
error VotingEscrowTokenDoesNotExists(IERC20 baseToken);
```

### Structs <a href="#structs" id="structs"></a>

#### IncentiveMatcherParameters <a href="#incentivematcherparameters-1" id="incentivematcherparameters-1"></a>

```solidity
struct IncentiveMatcherParameters {
    IERC20 baseToken;
    IMaverickV2VotingEscrow veToken;
    IMaverickV2RewardFactory factory;
}
```

<br>


# IMaverickV2Reward

**Inherits:** [INft](/technical-reference/maverick-v2/v2-contracts/maverick-v2-supplemental-contracts/positionbase/inft), [IMulticall](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/base/imulticall), [IRewardAccounting](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/rewardbase/irewardaccounting)

### Functions <a href="#functions" id="functions"></a>

#### MAX\_DURATION <a href="#max_duration" id="max_duration"></a>

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

#### MIN\_DURATION <a href="#min_duration" id="min_duration"></a>

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

#### UNBOOSTED\_MIN\_TIME\_GAP <a href="#unboosted_min_time_gap" id="unboosted_min_time_gap"></a>

This function retrieves the minimum time gap in seconds that must have elasped between calls to `pushUnboostedToVe()`.

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

#### stakingToken <a href="#stakingtoken" id="stakingtoken"></a>

This function retrieves the address of the token used for staking in this reward contract.

```solidity
function stakingToken() external view returns (IERC20);
```

**Returns**

| Name     | Type     | Description                                |
| -------- | -------- | ------------------------------------------ |
| `<none>` | `IERC20` | The address of the staking token (IERC20). |

#### vault <a href="#vault" id="vault"></a>

This function retrieves the address of the MaverickV2RewardVault contract associated with this reward contract.

```solidity
function vault() external view returns (IMaverickV2RewardVault);
```

**Returns**

| Name     | Type                     | Description                                         |
| -------- | ------------------------ | --------------------------------------------------- |
| `<none>` | `IMaverickV2RewardVault` | The address of the IMaverickV2RewardVault contract. |

#### rewardInfo <a href="#rewardinfo" id="rewardinfo"></a>

This function retrieves information about all available reward tokens for this reward contract.

```solidity
function rewardInfo() external view returns (RewardInfo[] memory info);
```

**Returns**

| Name   | Type           | Description                                                                |
| ------ | -------------- | -------------------------------------------------------------------------- |
| `info` | `RewardInfo[]` | An array of RewardInfo structs containing details about each reward token. |

#### contractInfo <a href="#contractinfo" id="contractinfo"></a>

This function retrieves information about all available reward tokens and overall contract details for this reward contract.

```solidity
function contractInfo() external view returns (RewardInfo[] memory info, ContractInfo memory _contractInfo);
```

**Returns**

| Name            | Type           | Description                                                                |
| --------------- | -------------- | -------------------------------------------------------------------------- |
| `info`          | `RewardInfo[]` | An array of RewardInfo structs containing details about each reward token. |
| `_contractInfo` | `ContractInfo` | A ContractInfo struct containing overall contract details.                 |

#### earned <a href="#earned" id="earned"></a>

This function calculates the total amount of all earned rewards for a specific tokenId across all reward tokens.

```solidity
function earned(uint256 tokenId) external view returns (EarnedInfo[] memory earnedInfo);
```

**Parameters**

| Name      | Type      | Description                                                       |
| --------- | --------- | ----------------------------------------------------------------- |
| `tokenId` | `uint256` | The address of the tokenId for which to calculate earned rewards. |

**Returns**

| Name         | Type           | Description                                                                                      |
| ------------ | -------------- | ------------------------------------------------------------------------------------------------ |
| `earnedInfo` | `EarnedInfo[]` | An array of EarnedInfo structs containing details about earned rewards for each supported token. |

#### earned <a href="#earned-1" id="earned-1"></a>

This function calculates the total amount of earned rewards for a specific tokenId for a particular reward token.

```solidity
function earned(uint256 tokenId, IERC20 rewardTokenAddress) external view returns (uint256);
```

**Parameters**

| Name                 | Type      | Description                                                       |
| -------------------- | --------- | ----------------------------------------------------------------- |
| `tokenId`            | `uint256` | The address of the tokenId for which to calculate earned rewards. |
| `rewardTokenAddress` | `IERC20`  | The address of the specific reward token.                         |

**Returns**

| Name     | Type      | Description                                                        |
| -------- | --------- | ------------------------------------------------------------------ |
| `<none>` | `uint256` | amount The total amount of earned rewards for the specified token. |

#### tokenIndex <a href="#tokenindex" id="tokenindex"></a>

This function retrieves the internal index associated with a specific reward token address.

```solidity
function tokenIndex(IERC20 rewardToken) external view returns (uint8 rewardTokenIndex);
```

**Parameters**

| Name          | Type     | Description                                           |
| ------------- | -------- | ----------------------------------------------------- |
| `rewardToken` | `IERC20` | The address of the reward token to get the index for. |

**Returns**

| Name               | Type    | Description                                                         |
| ------------------ | ------- | ------------------------------------------------------------------- |
| `rewardTokenIndex` | `uint8` | The internal index of the token within the reward contract (uint8). |

#### rewardTokenCount <a href="#rewardtokencount" id="rewardtokencount"></a>

This function retrieves the total number of supported reward tokens in this reward contract.

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

**Returns**

| Name     | Type      | Description                                        |
| -------- | --------- | -------------------------------------------------- |
| `<none>` | `uint256` | count The total number of reward tokens (uint256). |

#### transferAndNotifyRewardAmount <a href="#transferandnotifyrewardamount" id="transferandnotifyrewardamount"></a>

This function transfers a specified amount of reward tokens from the caller to distribute them over a defined duration. The caller will need to approve this rewards contract to make the transfer on the caller's behalf. See `notifyRewardAmount` for details of how the duration is set by the rewards contract.

```solidity
function transferAndNotifyRewardAmount(IERC20 rewardToken, uint256 duration, uint256 amount)
    external
    returns (uint256 _duration);
```

**Parameters**

| Name          | Type      | Description                                                     |
| ------------- | --------- | --------------------------------------------------------------- |
| `rewardToken` | `IERC20`  | The address of the reward token to transfer.                    |
| `duration`    | `uint256` | The duration (in seconds) over which to distribute the rewards. |
| `amount`      | `uint256` | The amount of reward tokens to transfer.                        |

**Returns**

| Name        | Type      | Description                                                           |
| ----------- | --------- | --------------------------------------------------------------------- |
| `_duration` | `uint256` | The duration in seconds that the incentives will be distributed over. |

#### notifyRewardAmount <a href="#notifyrewardamount" id="notifyrewardamount"></a>

This function notifies the vault to distribute a previously transferred amount of reward tokens over a defined duration. (Assumes tokens are already in the contract).

The duration of the distribution may not be the same as the input duration. If this notify amount is less than the amount already pending disbursement, then this new amount will be distributed as the same rate as the existing rate and that will dictate the duration. Alternatively, if the amount is more than the pending disbursement, then the input duration will be honored and all pending disbursement tokens will also be distributed at this newly set rate.

```solidity
function notifyRewardAmount(IERC20 rewardToken, uint256 duration) external returns (uint256 _duration);
```

**Parameters**

| Name          | Type      | Description                                                     |
| ------------- | --------- | --------------------------------------------------------------- |
| `rewardToken` | `IERC20`  | The address of the reward token to distribute.                  |
| `duration`    | `uint256` | The duration (in seconds) over which to distribute the rewards. |

**Returns**

| Name        | Type      | Description                                                           |
| ----------- | --------- | --------------------------------------------------------------------- |
| `_duration` | `uint256` | The duration in seconds that the incentives will be distributed over. |

#### transferAndStake <a href="#transferandstake" id="transferandstake"></a>

This function transfers a specified amount of staking tokens from the caller to the staking `vault()` and stakes them on the recipient's behalf. The user has to approve this reward contract to transfer the staking token on their behalf for this function not to revert.

```solidity
function transferAndStake(uint256 tokenId, uint256 _amount) external returns (uint256 amount, uint256 stakedTokenId);
```

**Parameters**

| Name      | Type      | Description                                         |
| --------- | --------- | --------------------------------------------------- |
| `tokenId` | `uint256` | Nft tokenId to stake for the staked tokens.         |
| `_amount` | `uint256` | The amount of staking tokens to transfer and stake. |

**Returns**

| Name            | Type      | Description                                                                                                               |
| --------------- | --------- | ------------------------------------------------------------------------------------------------------------------------- |
| `amount`        | `uint256` | The amount of staking tokens staked. May differ from input if there were unstaked tokens in the vault prior to this call. |
| `stakedTokenId` | `uint256` | TokenId where liquidity was staked to. This may differ from the input tokenIf if the input `tokenId=0`.                   |

#### stake <a href="#stake" id="stake"></a>

This function stakes the staking tokens to the specified tokenId. If `tokenId=0` is passed in, then this function will look up the caller's tokenIds and stake to the zero-index tokenId. If the user does not yet have a staking NFT tokenId, this function will mint one for the sender and stake to that newly-minted tokenId.

The amount staked is derived by looking at the new balance on the `vault()`. So, for staking to yield a non-zero balance, the user will need to have transfered the `stakingToken()` to the `vault()` prior to calling `stake`. Note, tokens sent to the reward contract instead of the vault will not be stakable and instead will be eligible to be disbursed as rewards to stakers. This is an advanced usage function. If in doubt about the mechanics of staking, use `transferAndStake()` instead.

```solidity
function stake(uint256 tokenId) external returns (uint256 amount, uint256 stakedTokenId);
```

**Parameters**

| Name      | Type      | Description                                       |
| --------- | --------- | ------------------------------------------------- |
| `tokenId` | `uint256` | The address of the tokenId whose tokens to stake. |

**Returns**

| Name            | Type      | Description                                                                                             |
| --------------- | --------- | ------------------------------------------------------------------------------------------------------- |
| `amount`        | `uint256` | The amount of staking tokens staked (uint256).                                                          |
| `stakedTokenId` | `uint256` | TokenId where liquidity was staked to. This may differ from the input tokenIf if the input `tokenId=0`. |

#### unstakeToOwner <a href="#unstaketoowner" id="unstaketoowner"></a>

This function initiates unstaking of a specified amount of staking tokens for the caller and sends them to a recipient.

```solidity
function unstakeToOwner(uint256 tokenId, uint256 amount) external;
```

**Parameters**

| Name      | Type      | Description                                         |
| --------- | --------- | --------------------------------------------------- |
| `tokenId` | `uint256` | The address of the tokenId whose tokens to unstake. |
| `amount`  | `uint256` | The amount of staking tokens to unstake (uint256).  |

#### unstake <a href="#unstake" id="unstake"></a>

This function initiates unstaking of a specified amount of staking tokens on behalf of a specific tokenId and sends them to a recipient.

To unstakeFrom, the caller must have an approval allowance of at least `amount`. Approvals follow the ERC-20 approval/allowance interface.

```solidity
function unstake(uint256 tokenId, address recipient, uint256 amount) external;
```

**Parameters**

| Name        | Type      | Description                                            |
| ----------- | --------- | ------------------------------------------------------ |
| `tokenId`   | `uint256` | The address of the tokenId whose tokens to unstake.    |
| `recipient` | `address` | The address to which the unstaked tokens will be sent. |
| `amount`    | `uint256` | The amount of staking tokens to unstake (uint256).     |

#### getRewardToOwner <a href="#getrewardtoowner" id="getrewardtoowner"></a>

This function retrieves the claimable reward for a specific reward token and stake duration for the caller.

```solidity
function getRewardToOwner(uint256 tokenId, uint8 rewardTokenIndex, uint256 stakeDuration)
    external
    returns (RewardOutput memory rewardOutput);
```

**Parameters**

| Name               | Type      | Description                                                  |
| ------------------ | --------- | ------------------------------------------------------------ |
| `tokenId`          | `uint256` | The address of the tokenId whose reward to claim.            |
| `rewardTokenIndex` | `uint8`   | The internal index of the reward token.                      |
| `stakeDuration`    | `uint256` | The duration (in seconds) for which the rewards were staked. |

**Returns**

| Name           | Type           | Description                                                          |
| -------------- | -------------- | -------------------------------------------------------------------- |
| `rewardOutput` | `RewardOutput` | A RewardOutput struct containing details about the claimable reward. |

#### getRewardToOwnerForExistingVeLockup <a href="#getrewardtoownerforexistingvelockup" id="getrewardtoownerforexistingvelockup"></a>

This function retrieves the claimable reward for a specific reward token, stake duration, and lockup ID for the caller.

```solidity
function getRewardToOwnerForExistingVeLockup(
    uint256 tokenId,
    uint8 rewardTokenIndex,
    uint256 stakeDuration,
    uint256 lockupId
) external returns (RewardOutput memory);
```

**Parameters**

| Name               | Type      | Description                                                  |
| ------------------ | --------- | ------------------------------------------------------------ |
| `tokenId`          | `uint256` | The address of the tokenId whose reward to claim.            |
| `rewardTokenIndex` | `uint8`   | The internal index of the reward token.                      |
| `stakeDuration`    | `uint256` | The duration (in seconds) for which the rewards were staked. |
| `lockupId`         | `uint256` | The unique identifier for the specific lockup (optional).    |

**Returns**

| Name     | Type           | Description                                                                       |
| -------- | -------------- | --------------------------------------------------------------------------------- |
| `<none>` | `RewardOutput` | rewardOutput A RewardOutput struct containing details about the claimable reward. |

#### getRewardForExistingVeLockup <a href="#getrewardforexistingvelockup" id="getrewardforexistingvelockup"></a>

This function retrieves the claimable reward for a specific reward token, stake duration, lockup ID, and sends it to a recipient for a specified tokenId.

If the reward is staked in the corresponding veToken, the `lockupId` lockup will be extended on the veToken contract. Any existing lock on that lockupId will also be extended. To use this function, this reward contract will have to be approved as an extender on the veToken contract.

```solidity
function getRewardForExistingVeLockup(
    uint256 tokenId,
    address recipient,
    uint8 rewardTokenIndex,
    uint256 stakeDuration,
    uint256 lockupId
) external returns (RewardOutput memory);
```

**Parameters**

| Name               | Type      | Description                                                                        |
| ------------------ | --------- | ---------------------------------------------------------------------------------- |
| `tokenId`          | `uint256` | The address of the tokenId whose reward to claim.                                  |
| `recipient`        | `address` | The address to which the claimed reward will be sent.                              |
| `rewardTokenIndex` | `uint8`   | The internal index of the reward token.                                            |
| `stakeDuration`    | `uint256` | The duration (in seconds) for which the rewards will be staked in the ve contract. |
| `lockupId`         | `uint256` | The unique identifier for the specific lockup to extend on the veToken contract.   |

**Returns**

| Name     | Type           | Description                                                                       |
| -------- | -------------- | --------------------------------------------------------------------------------- |
| `<none>` | `RewardOutput` | rewardOutput A RewardOutput struct containing details about the claimable reward. |

#### getReward <a href="#getreward" id="getreward"></a>

This function retrieves the claimable reward for a specific reward token and stake duration for a specified tokenId and sends it to a recipient. If the reward is staked in the corresponding veToken, a new lockup in the ve token will be created.

```solidity
function getReward(uint256 tokenId, address recipient, uint8 rewardTokenIndex, uint256 stakeDuration)
    external
    returns (RewardOutput memory);
```

**Parameters**

| Name               | Type      | Description                                                                        |
| ------------------ | --------- | ---------------------------------------------------------------------------------- |
| `tokenId`          | `uint256` | The address of the tokenId whose reward to claim.                                  |
| `recipient`        | `address` | The address to which the claimed reward will be sent.                              |
| `rewardTokenIndex` | `uint8`   | The internal index of the reward token.                                            |
| `stakeDuration`    | `uint256` | The duration (in seconds) for which the rewards will be staked in the ve contract. |

**Returns**

| Name     | Type           | Description                                                                       |
| -------- | -------------- | --------------------------------------------------------------------------------- |
| `<none>` | `RewardOutput` | rewardOutput A RewardOutput struct containing details about the claimable reward. |

#### tokenList <a href="#tokenlist" id="tokenlist"></a>

This function retrieves a list of all supported tokens in the reward contract.

```solidity
function tokenList(bool includeStakingToken) external view returns (IERC20[] memory tokens);
```

**Parameters**

| Name                  | Type   | Description                                                         |
| --------------------- | ------ | ------------------------------------------------------------------- |
| `includeStakingToken` | `bool` | A flag indicating whether to include the staking token in the list. |

**Returns**

| Name     | Type       | Description                         |
| -------- | ---------- | ----------------------------------- |
| `tokens` | `IERC20[]` | An array of IERC20 token addresses. |

#### veTokenByIndex <a href="#vetokenbyindex" id="vetokenbyindex"></a>

This function retrieves the veToken contract associated with a specific index within the reward contract.

```solidity
function veTokenByIndex(uint8 index) external view returns (IMaverickV2VotingEscrow output);
```

**Parameters**

| Name    | Type    | Description                           |
| ------- | ------- | ------------------------------------- |
| `index` | `uint8` | The index of the veToken to retrieve. |

**Returns**

| Name     | Type                      | Description                                                     |
| -------- | ------------------------- | --------------------------------------------------------------- |
| `output` | `IMaverickV2VotingEscrow` | The IMaverickV2VotingEscrow contract associated with the index. |

#### rewardTokenByIndex <a href="#rewardtokenbyindex" id="rewardtokenbyindex"></a>

This function retrieves the reward token contract associated with a specific index within the reward contract.

```solidity
function rewardTokenByIndex(uint8 index) external view returns (IERC20 output);
```

**Parameters**

| Name    | Type    | Description                                |
| ------- | ------- | ------------------------------------------ |
| `index` | `uint8` | The index of the reward token to retrieve. |

**Returns**

| Name     | Type     | Description                                    |
| -------- | -------- | ---------------------------------------------- |
| `output` | `IERC20` | The IERC20 contract associated with the index. |

#### boostedAmount <a href="#boostedamount" id="boostedamount"></a>

This function calculates the boosted amount an tokenId would receive based on their veToken balance and stake duration.

```solidity
function boostedAmount(uint256 tokenId, IMaverickV2VotingEscrow veToken, uint256 rawAmount, uint256 stakeDuration)
    external
    view
    returns (uint256 earnedAmount, bool asVe);
```

**Parameters**

| Name            | Type                      | Description                                                                      |
| --------------- | ------------------------- | -------------------------------------------------------------------------------- |
| `tokenId`       | `uint256`                 | The address of the tokenId for which to calculate the boosted amount.            |
| `veToken`       | `IMaverickV2VotingEscrow` | The IMaverickV2VotingEscrow contract representing the veToken used for boosting. |
| `rawAmount`     | `uint256`                 | The raw (unboosted) amount.                                                      |
| `stakeDuration` | `uint256`                 | The duration (in seconds) for which the rewards would be staked.                 |

**Returns**

| Name           | Type      | Description                                                                                                                          |
| -------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `earnedAmount` | `uint256` | The boosted amount the tokenId would receive (uint256).                                                                              |
| `asVe`         | `bool`    | A boolean indicating whether the boosted amount is staked in the veToken (true) or is disbursed without ve staking required (false). |

#### pushUnboostedToVe <a href="#pushunboostedtove" id="pushunboostedtove"></a>

This function is used to push unboosted rewards to the veToken contract. This unboosted reward amount is then distributed to the veToken holders. This function will revert if less than `UNBOOSTED_MIN_TIME_GAP()` seconds have passed since the last call.

```solidity
function pushUnboostedToVe(uint8 rewardTokenIndex)
    external
    returns (uint128 amount, uint48 timepoint, uint256 batchIndex);
```

**Parameters**

| Name               | Type    | Description                             |
| ------------------ | ------- | --------------------------------------- |
| `rewardTokenIndex` | `uint8` | The internal index of the reward token. |

**Returns**

| Name         | Type      | Description                                                |
| ------------ | --------- | ---------------------------------------------------------- |
| `amount`     | `uint128` | The amount of unboosted rewards pushed (uint128).          |
| `timepoint`  | `uint48`  | The timestamp associated with the pushed rewards (uint48). |
| `batchIndex` | `uint256` | The batch index for the pushed rewards (uint256).          |

#### mint <a href="#mint" id="mint"></a>

Mints an NFT stake to a user. This NFT will not possesses any assets until a user `stake`s asset to the NFT tokenId as part of a separate call.

```solidity
function mint(address recipient) external returns (uint256 tokenId);
```

**Parameters**

| Name        | Type      | Description                          |
| ----------- | --------- | ------------------------------------ |
| `recipient` | `address` | The address that owns the output NFT |

#### mintToSender <a href="#minttosender" id="minttosender"></a>

Mints an NFT stake to caller. This NFT will not possesses any assets until a user `stake`s asset to the NFT tokenId as part of a separate call.

```solidity
function mintToSender() external returns (uint256 tokenId);
```

### Events <a href="#events" id="events"></a>

#### NotifyRewardAmount <a href="#notifyrewardamount-1" id="notifyrewardamount-1"></a>

```solidity
event NotifyRewardAmount(
    address sender, IERC20 rewardTokenAddress, uint256 amount, uint256 duration, uint256 rewardRate
);
```

#### GetReward <a href="#getreward-1" id="getreward-1"></a>

```solidity
event GetReward(
    address sender,
    uint256 tokenId,
    address recipient,
    uint8 rewardTokenIndex,
    uint256 stakeDuration,
    IERC20 rewardTokenAddress,
    RewardOutput rewardOutput,
    uint256 lockupId
);
```

#### UnStake <a href="#unstake-1" id="unstake-1"></a>

```solidity
event UnStake(
    address sender, uint256 tokenId, uint256 amount, address recipient, uint256 userBalance, uint256 totalSupply
);
```

#### Stake <a href="#stake-1" id="stake-1"></a>

```solidity
event Stake(
    address sender, address supplier, uint256 amount, uint256 tokenId, uint256 userBalance, uint256 totalSupply
);
```

#### AddRewardToken <a href="#addrewardtoken" id="addrewardtoken"></a>

```solidity
event AddRewardToken(IERC20 rewardTokenAddress, uint8 rewardTokenIndex);
```

#### RemoveRewardToken <a href="#removerewardtoken" id="removerewardtoken"></a>

```solidity
event RemoveRewardToken(IERC20 rewardTokenAddress, uint8 rewardTokenIndex);
```

#### ApproveRewardGetter <a href="#approverewardgetter" id="approverewardgetter"></a>

```solidity
event ApproveRewardGetter(uint256 tokenId, address getter);
```

### Errors <a href="#errors" id="errors"></a>

#### RewardDurationOutOfBounds <a href="#rewarddurationoutofbounds" id="rewarddurationoutofbounds"></a>

```solidity
error RewardDurationOutOfBounds(uint256 duration, uint256 minDuration, uint256 maxDuration);
```

#### RewardZeroAmount <a href="#rewardzeroamount" id="rewardzeroamount"></a>

```solidity
error RewardZeroAmount();
```

#### RewardNotValidRewardToken <a href="#rewardnotvalidrewardtoken" id="rewardnotvalidrewardtoken"></a>

```solidity
error RewardNotValidRewardToken(IERC20 rewardTokenAddress);
```

#### RewardNotValidIndex <a href="#rewardnotvalidindex" id="rewardnotvalidindex"></a>

```solidity
error RewardNotValidIndex(uint8 index);
```

#### RewardTokenCannotBeStakingToken <a href="#rewardtokencannotbestakingtoken" id="rewardtokencannotbestakingtoken"></a>

```solidity
error RewardTokenCannotBeStakingToken(IERC20 stakingToken);
```

#### RewardTransferNotSupported <a href="#rewardtransfernotsupported" id="rewardtransfernotsupported"></a>

```solidity
error RewardTransferNotSupported();
```

#### RewardNotApprovedGetter <a href="#rewardnotapprovedgetter" id="rewardnotapprovedgetter"></a>

```solidity
error RewardNotApprovedGetter(uint256 tokenId, address approved, address getter);
```

#### RewardUnboostedTimePeriodNotMet <a href="#rewardunboostedtimeperiodnotmet" id="rewardunboostedtimeperiodnotmet"></a>

```solidity
error RewardUnboostedTimePeriodNotMet(uint256 timestamp, uint256 minTimestamp);
```

### Structs <a href="#structs" id="structs"></a>

#### RewardInfo <a href="#rewardinfo-1" id="rewardinfo-1"></a>

```solidity
struct RewardInfo {
    uint256 finishAt;
    uint256 updatedAt;
    uint256 rewardRate;
    uint256 escrowedReward;
    uint256 rewardPerTokenStored;
    IERC20 rewardToken;
    IMaverickV2VotingEscrow veRewardToken;
    uint128 unboostedAmount;
    uint256 lastUnboostedPushTimestamp;
}
```

#### ContractInfo <a href="#contractinfo-1" id="contractinfo-1"></a>

```solidity
struct ContractInfo {
    string name;
    string symbol;
    uint256 totalSupply;
    IERC20 stakingToken;
}
```

#### EarnedInfo <a href="#earnedinfo" id="earnedinfo"></a>

```solidity
struct EarnedInfo {
    uint256 earned;
    IERC20 rewardToken;
}
```

#### RewardOutput <a href="#rewardoutput" id="rewardoutput"></a>

```solidity
struct RewardOutput {
    uint256 amount;
    bool asVe;
    IMaverickV2VotingEscrow veContract;
}
```


# IMaverickV2RewardFactory

### Functions <a href="#functions" id="functions"></a>

#### createRewardsContract <a href="#createrewardscontract" id="createrewardscontract"></a>

This function creates a new MaverickV2Reward contract associated with a specific stake token contract and set of reward and voting escrow tokens.

```solidity
function createRewardsContract(
    IERC20 stakeToken,
    IERC20[] memory rewardTokens,
    IMaverickV2VotingEscrow[] memory veTokens
) external returns (IMaverickV2Reward rewardsContract);
```

**Parameters**

| Name           | Type                        | Description                                                                                               |
| -------------- | --------------------------- | --------------------------------------------------------------------------------------------------------- |
| `stakeToken`   | `IERC20`                    | Token to be staked in reward contract; e.g. a boosted position contract.                                  |
| `rewardTokens` | `IERC20[]`                  | An array of IERC20 token addresses representing the available reward tokens.                              |
| `veTokens`     | `IMaverickV2VotingEscrow[]` | An array of IMaverickV2VotingEscrow contract addresses representing the associated veTokens for boosting. |

**Returns**

| Name              | Type                | Description                                   |
| ----------------- | ------------------- | --------------------------------------------- |
| `rewardsContract` | `IMaverickV2Reward` | The newly created IMaverickV2Reward contract. |

#### boostedPositionFactory <a href="#boostedpositionfactory" id="boostedpositionfactory"></a>

This function retrieves the address of the MaverickV2BoostedPositionFactory contract.

```solidity
function boostedPositionFactory() external returns (IMaverickV2BoostedPositionFactory);
```

**Returns**

| Name     | Type                                | Description                                                            |
| -------- | ----------------------------------- | ---------------------------------------------------------------------- |
| `<none>` | `IMaverickV2BoostedPositionFactory` | factory The address of the IMaverickV2BoostedPositionFactory contract. |

#### votingEscrowFactory <a href="#votingescrowfactory" id="votingescrowfactory"></a>

This function retrieves the address of the MaverickV2VotingEscrowFactory contract.

```solidity
function votingEscrowFactory() external returns (IMaverickV2VotingEscrowFactory);
```

**Returns**

| Name     | Type                             | Description                                                         |
| -------- | -------------------------------- | ------------------------------------------------------------------- |
| `<none>` | `IMaverickV2VotingEscrowFactory` | factory The address of the IMaverickV2VotingEscrowFactory contract. |

#### isFactoryContract <a href="#isfactorycontract" id="isfactorycontract"></a>

This function checks if a provided IMaverickV2Reward contract is a valid contract created by this factory.

```solidity
function isFactoryContract(IMaverickV2Reward reward) external returns (bool);
```

**Parameters**

| Name     | Type                | Description                              |
| -------- | ------------------- | ---------------------------------------- |
| `reward` | `IMaverickV2Reward` | The IMaverickV2Reward contract to check. |

**Returns**

| Name     | Type   | Description                                                                                         |
| -------- | ------ | --------------------------------------------------------------------------------------------------- |
| `<none>` | `bool` | isFactoryContract True if the contract is a valid factory-created reward contract, False otherwise. |

#### rewardsForStakeToken <a href="#rewardsforstaketoken" id="rewardsforstaketoken"></a>

This function retrieves a list of all MaverickV2Reward contracts associated with a specific staking token contract within a specified range.

```solidity
function rewardsForStakeToken(IERC20 stakeToken, uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2Reward[] memory rewardsContract);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `stakeToken` | `IERC20`  | Lookup token.                               |
| `startIndex` | `uint256` | The starting index of the list to retrieve. |
| `endIndex`   | `uint256` | The ending index of the list to retrieve.   |

**Returns**

| Name              | Type                  | Description                                                                                             |
| ----------------- | --------------------- | ------------------------------------------------------------------------------------------------------- |
| `rewardsContract` | `IMaverickV2Reward[]` | An array of IMaverickV2Reward contracts associated with the BoostedPosition within the specified range. |

#### rewards <a href="#rewards" id="rewards"></a>

This function retrieves a list of all MaverickV2Reward contracts within a specified range.

```solidity
function rewards(uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2Reward[] memory rewardsContract);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `startIndex` | `uint256` | The starting index of the list to retrieve. |
| `endIndex`   | `uint256` | The ending index of the list to retrieve.   |

**Returns**

| Name              | Type                  | Description                                                         |
| ----------------- | --------------------- | ------------------------------------------------------------------- |
| `rewardsContract` | `IMaverickV2Reward[]` | An array of IMaverickV2Reward contracts within the specified range. |

#### boostedPositionRewards <a href="#boostedpositionrewards" id="boostedpositionrewards"></a>

This function retrieves a list of all MaverickV2Reward contracts within a specified range that have a staking token that is a boosted position from the maverick boosted position contract.

```solidity
function boostedPositionRewards(uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2Reward[] memory);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `startIndex` | `uint256` | The starting index of the list to retrieve. |
| `endIndex`   | `uint256` | The ending index of the list to retrieve.   |

**Returns**

| Name     | Type                  | Description                                                                         |
| -------- | --------------------- | ----------------------------------------------------------------------------------- |
| `<none>` | `IMaverickV2Reward[]` | rewardsContract An array of IMaverickV2Reward contracts within the specified range. |

#### nonBoostedPositionRewards <a href="#nonboostedpositionrewards" id="nonboostedpositionrewards"></a>

This function retrieves a list of all MaverickV2Reward contracts within a specified range that have a staking token that is not a boosted position from the maverick boosted position contract.

```solidity
function nonBoostedPositionRewards(uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2Reward[] memory);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `startIndex` | `uint256` | The starting index of the list to retrieve. |
| `endIndex`   | `uint256` | The ending index of the list to retrieve.   |

**Returns**

| Name     | Type                  | Description                                                                         |
| -------- | --------------------- | ----------------------------------------------------------------------------------- |
| `<none>` | `IMaverickV2Reward[]` | rewardsContract An array of IMaverickV2Reward contracts within the specified range. |

### Errors <a href="#errors" id="errors"></a>

#### RewardFactoryNotFactoryBoostedPosition <a href="#rewardfactorynotfactoryboostedposition" id="rewardfactorynotfactoryboostedposition"></a>

```solidity
error RewardFactoryNotFactoryBoostedPosition();
```

#### RewardFactoryTooManyRewardTokens <a href="#rewardfactorytoomanyrewardtokens" id="rewardfactorytoomanyrewardtokens"></a>

```solidity
error RewardFactoryTooManyRewardTokens();
```

#### RewardFactoryRewardAndVeLengthsAreNotEqual <a href="#rewardfactoryrewardandvelengthsarenotequal" id="rewardfactoryrewardandvelengthsarenotequal"></a>

```solidity
error RewardFactoryRewardAndVeLengthsAreNotEqual();
```

#### RewardFactoryInvalidVeBaseTokenPair <a href="#rewardfactoryinvalidvebasetokenpair" id="rewardfactoryinvalidvebasetokenpair"></a>

```solidity
error RewardFactoryInvalidVeBaseTokenPair();
```


# IMaverickV2RewardRouter

**Inherits:** [IMaverickV2LiquidityManager](/technical-reference/maverick-v2/v2-contracts/maverick-v2-supplemental-contracts/interfaces/imaverickv2liquiditymanager)

### Functions <a href="#functions" id="functions"></a>

#### stake <a href="#stake" id="stake"></a>

This function stakes any new staking token balance that are in the `reward.vault()` for a specified recipient tokenId. Passing input `tokenId=0` will cause the stake to mint to either the first tokenId for the caller, or a new NFT tokenId if the sender does not yet have one.

```solidity
function stake(IMaverickV2Reward reward, uint256 tokenId)
    external
    payable
    returns (uint256 amount, uint256 stakedTokenId);
```

**Parameters**

| Name      | Type                | Description                                        |
| --------- | ------------------- | -------------------------------------------------- |
| `reward`  | `IMaverickV2Reward` | The IMaverickV2Reward contract for which to stake. |
| `tokenId` | `uint256`           | Nft tokenId to stake for the staked tokens.        |

**Returns**

| Name            | Type      | Description                                                                                                               |
| --------------- | --------- | ------------------------------------------------------------------------------------------------------------------------- |
| `amount`        | `uint256` | The amount of staking tokens staked. May differ from input if there were unstaked tokens in the vault prior to this call. |
| `stakedTokenId` | `uint256` | TokenId where liquidity was staked to. This may differ from the input tokenId if the input `tokenId=0`.                   |

#### rewardFactory <a href="#rewardfactory" id="rewardfactory"></a>

This function retrieves the address of the MaverickV2RewardFactory contract associated with this contract.

```solidity
function rewardFactory() external view returns (IMaverickV2RewardFactory);
```

#### notifyRewardAmount <a href="#notifyrewardamount" id="notifyrewardamount"></a>

This function transfers a specified amount of reward tokens from the caller to a reward contract and notifies it to distribute them over a defined duration.

```solidity
function notifyRewardAmount(IMaverickV2Reward reward, IERC20 rewardToken, uint256 duration)
    external
    payable
    returns (uint256 _duration);
```

**Parameters**

| Name          | Type                | Description                                                     |
| ------------- | ------------------- | --------------------------------------------------------------- |
| `reward`      | `IMaverickV2Reward` | The IMaverickV2Reward contract to notify.                       |
| `rewardToken` | `IERC20`            | The address of the reward token to transfer.                    |
| `duration`    | `uint256`           | The duration (in seconds) over which to distribute the rewards. |

**Returns**

| Name        | Type      | Description                                                           |
| ----------- | --------- | --------------------------------------------------------------------- |
| `_duration` | `uint256` | The duration in seconds that the incentives will be distributed over. |

#### transferAndStake <a href="#transferandstake" id="transferandstake"></a>

This function transfers a specified amount of staking tokens from the caller, stakes them on the recipient's behalf, and associates them with a specified reward contract.

```solidity
function transferAndStake(IMaverickV2Reward reward, uint256 tokenId, uint256 _amount)
    external
    payable
    returns (uint256 amount, uint256 stakedTokenId);
```

**Parameters**

| Name      | Type                | Description                                         |
| --------- | ------------------- | --------------------------------------------------- |
| `reward`  | `IMaverickV2Reward` | The IMaverickV2Reward contract for which to stake.  |
| `tokenId` | `uint256`           | Nft tokenId to stake for the staked tokens.         |
| `_amount` | `uint256`           | The amount of staking tokens to transfer and stake. |

**Returns**

| Name            | Type      | Description                                                                                                               |
| --------------- | --------- | ------------------------------------------------------------------------------------------------------------------------- |
| `amount`        | `uint256` | The amount of staking tokens staked. May differ from input if there were unstaked tokens in the vault prior to this call. |
| `stakedTokenId` | `uint256` | TokenId where liquidity was staked to. This may differ from the input tokenIf if the input `tokenId=0`.                   |

#### transferAndNotifyRewardAmount <a href="#transferandnotifyrewardamount" id="transferandnotifyrewardamount"></a>

This function transfers a specified amount of reward tokens from the caller and adds them to the reward contract as incentives.

```solidity
function transferAndNotifyRewardAmount(IMaverickV2Reward reward, IERC20 rewardToken, uint256 duration, uint256 amount)
    external
    payable
    returns (uint256 _duration);
```

**Parameters**

| Name          | Type                | Description                                                     |
| ------------- | ------------------- | --------------------------------------------------------------- |
| `reward`      | `IMaverickV2Reward` | The IMaverickV2Reward contract to notify.                       |
| `rewardToken` | `IERC20`            | The address of the reward token to transfer.                    |
| `duration`    | `uint256`           | The duration (in seconds) over which to distribute the rewards. |
| `amount`      | `uint256`           | The amount of staking tokens to stake (uint256).                |

**Returns**

| Name        | Type      | Description                                                           |
| ----------- | --------- | --------------------------------------------------------------------- |
| `_duration` | `uint256` | The duration in seconds that the incentives will be distributed over. |

#### createBoostedPositionAndAddLiquidityAndStake <a href="#createboostedpositionandaddliquidityandstake" id="createboostedpositionandaddliquidityandstake"></a>

This function creates a new BoostedPosition contract, adds liquidity to a pool using the provided parameters, stakes the received LP tokens, and associates them with a specified reward contract.

```solidity
function createBoostedPositionAndAddLiquidityAndStake(
    address recipient,
    IMaverickV2PoolLens.CreateBoostedPositionInputs memory params,
    IERC20[] memory rewardTokens,
    IMaverickV2VotingEscrow[] memory veTokens
)
    external
    payable
    returns (
        IMaverickV2BoostedPosition boostedPosition,
        uint256 mintedLpAmount,
        uint256 tokenAAmount,
        uint256 tokenBAmount,
        uint256 stakeAmount,
        IMaverickV2Reward reward,
        uint256 tokenId
    );
```

**Parameters**

| Name           | Type                                              | Description                                                                                                            |
| -------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `recipient`    | `address`                                         | The address to which the minted LP tokens will be credited.                                                            |
| `params`       | `IMaverickV2PoolLens.CreateBoostedPositionInputs` | A struct containing parameters for creating the BoostedPosition (see IMaverickV2PoolLens.CreateBoostedPositionInputs). |
| `rewardTokens` | `IERC20[]`                                        | An array of IERC20 token addresses representing the available reward tokens for the staked LP position.                |
| `veTokens`     | `IMaverickV2VotingEscrow[]`                       | An array of IMaverickV2VotingEscrow contract addresses representing the veTokens used for boosting.                    |

**Returns**

| Name              | Type                         | Description                                               |
| ----------------- | ---------------------------- | --------------------------------------------------------- |
| `boostedPosition` | `IMaverickV2BoostedPosition` | The created IMaverickV2BoostedPosition contract.          |
| `mintedLpAmount`  | `uint256`                    | The amount of LP tokens minted from the added liquidity.  |
| `tokenAAmount`    | `uint256`                    | The amount of token A deposited for liquidity.            |
| `tokenBAmount`    | `uint256`                    | The amount of token B deposited for liquidity.            |
| `stakeAmount`     | `uint256`                    | The amount of LP tokens staked in the reward contract.    |
| `reward`          | `IMaverickV2Reward`          | The IMaverickV2Reward contract.                           |
| `tokenId`         | `uint256`                    | Token on reward contract where user liquidity was staked. |

#### createBoostedPositionAndAddLiquidityAndStakeToSender <a href="#createboostedpositionandaddliquidityandstaketosender" id="createboostedpositionandaddliquidityandstaketosender"></a>

This function is similar to `createBoostedPositionAndAddLiquidityAndStake` but stakes the minted LP tokens for the caller (msg.sender) instead of a specified recipient.

```solidity
function createBoostedPositionAndAddLiquidityAndStakeToSender(
    IMaverickV2PoolLens.CreateBoostedPositionInputs memory params,
    IERC20[] memory rewardTokens,
    IMaverickV2VotingEscrow[] memory veTokens
)
    external
    payable
    returns (
        IMaverickV2BoostedPosition boostedPosition,
        uint256 mintedLpAmount,
        uint256 tokenAAmount,
        uint256 tokenBAmount,
        uint256 stakeAmount,
        IMaverickV2Reward reward,
        uint256 tokenId
    );
```

**Parameters**

| Name           | Type                                              | Description                                                                                                            |
| -------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `params`       | `IMaverickV2PoolLens.CreateBoostedPositionInputs` | A struct containing parameters for creating the BoostedPosition (see IMaverickV2PoolLens.CreateBoostedPositionInputs). |
| `rewardTokens` | `IERC20[]`                                        | An array of IERC20 token addresses representing the available reward tokens for the staked LP position.                |
| `veTokens`     | `IMaverickV2VotingEscrow[]`                       | An array of IMaverickV2VotingEscrow contract addresses representing the veTokens used for boosting.                    |

**Returns**

| Name              | Type                         | Description                                                            |
| ----------------- | ---------------------------- | ---------------------------------------------------------------------- |
| `boostedPosition` | `IMaverickV2BoostedPosition` | The created IMaverickV2BoostedPosition contract.                       |
| `mintedLpAmount`  | `uint256`                    | The amount of LP tokens minted from the added liquidity.               |
| `tokenAAmount`    | `uint256`                    | The amount of token A deposited for liquidity.                         |
| `tokenBAmount`    | `uint256`                    | The amount of token B deposited for liquidity.                         |
| `stakeAmount`     | `uint256`                    | The amount of LP tokens staked in the reward contract.                 |
| `reward`          | `IMaverickV2Reward`          | The IMaverickV2Reward contract associated with the staked LP position. |
| `tokenId`         | `uint256`                    | Token on reward contract where user liquidity was staked.              |

#### addLiquidityAndMintBoostedPositionAndStake <a href="#addliquidityandmintboostedpositionandstake" id="addliquidityandmintboostedpositionandstake"></a>

This function adds liquidity to a pool using a pre-created BoostedPosition contract, stakes the received LP tokens, and associates them with a specified reward contract.

```solidity
function addLiquidityAndMintBoostedPositionAndStake(
    uint256 tokenId,
    IMaverickV2BoostedPosition boostedPosition,
    bytes memory packedSqrtPriceBreaks,
    bytes[] memory packedArgs,
    IMaverickV2Reward reward
) external payable returns (uint256 mintedLpAmount, uint256 tokenAAmount, uint256 tokenBAmount, uint256 stakeAmount);
```

**Parameters**

| Name                    | Type                         | Description                                                                                                     |
| ----------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `tokenId`               | `uint256`                    | Token on reward contract where liquidity is to be staked.                                                       |
| `boostedPosition`       | `IMaverickV2BoostedPosition` | The IMaverickV2BoostedPosition contract representing the existing boosted position.                             |
| `packedSqrtPriceBreaks` | `bytes`                      | A packed representation of sqrt price breaks for the liquidity range (see IMaverickV2Pool.IAddLiquidityParams). |
| `packedArgs`            | `bytes[]`                    | Additional packed arguments for adding liquidity (see IMaverickV2Pool.IAddLiquidityParams).                     |
| `reward`                | `IMaverickV2Reward`          | The IMaverickV2Reward contract for which to stake the LP tokens.                                                |

**Returns**

| Name             | Type      | Description                                              |
| ---------------- | --------- | -------------------------------------------------------- |
| `mintedLpAmount` | `uint256` | The amount of LP tokens minted from the added liquidity. |
| `tokenAAmount`   | `uint256` | The amount of token A deposited for liquidity.           |
| `tokenBAmount`   | `uint256` | The amount of token B deposited for liquidity.           |
| `stakeAmount`    | `uint256` | The amount of LP tokens staked in the reward contract.   |

#### addLiquidityAndMintBoostedPositionAndStakeToSender <a href="#addliquidityandmintboostedpositionandstaketosender" id="addliquidityandmintboostedpositionandstaketosender"></a>

This function is similar to `addLiquidityAndMintBoostedPositionAndStake` but uses the caller (msg.sender) as the recipient for the minted reward stake.

```solidity
function addLiquidityAndMintBoostedPositionAndStakeToSender(
    uint256 sendersTokenIndex,
    IMaverickV2BoostedPosition boostedPosition,
    bytes memory packedSqrtPriceBreaks,
    bytes[] memory packedArgs,
    IMaverickV2Reward reward
)
    external
    payable
    returns (uint256 mintedLpAmount, uint256 tokenAAmount, uint256 tokenBAmount, uint256 stakeAmount, uint256 tokenId);
```

**Parameters**

| Name                    | Type                         | Description                                                                                                                                  |
| ----------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `sendersTokenIndex`     | `uint256`                    | Token index of sender on the reward contract to mint to. If sender does not have a token already, then this call will mint one for the user. |
| `boostedPosition`       | `IMaverickV2BoostedPosition` | The IMaverickV2BoostedPosition contract representing the existing boosted position.                                                          |
| `packedSqrtPriceBreaks` | `bytes`                      | A packed representation of sqrt price breaks for the liquidity range (see IMaverickV2Pool.IAddLiquidityParams).                              |
| `packedArgs`            | `bytes[]`                    | Additional packed arguments for adding liquidity (see IMaverickV2Pool.IAddLiquidityParams).                                                  |
| `reward`                | `IMaverickV2Reward`          | The IMaverickV2Reward contract for which to stake the LP tokens.                                                                             |

**Returns**

| Name             | Type      | Description                                               |
| ---------------- | --------- | --------------------------------------------------------- |
| `mintedLpAmount` | `uint256` | The amount of LP tokens minted from the added liquidity.  |
| `tokenAAmount`   | `uint256` | The amount of token A deposited for liquidity.            |
| `tokenBAmount`   | `uint256` | The amount of token B deposited for liquidity.            |
| `stakeAmount`    | `uint256` | The amount of LP tokens staked in the reward contract.    |
| `tokenId`        | `uint256` | Token on reward contract where user liquidity was staked. |

#### sync <a href="#sync" id="sync"></a>

This function syncs the balance of a staker's votes on the legacy ve mav contract with the new V2 ve mav contract.

```solidity
function sync(IMaverickV2VotingEscrowWSync ve, address staker, uint256[] memory legacyLockupIndexes)
    external
    returns (uint256[] memory newBalance);
```

**Parameters**

| Name                  | Type                           | Description                                                                   |
| --------------------- | ------------------------------ | ----------------------------------------------------------------------------- |
| `ve`                  | `IMaverickV2VotingEscrowWSync` | The IMaverickV2VotingEscrowWSync contract to interact with.                   |
| `staker`              | `address`                      | The address of the user whose veToken lock may need syncing.                  |
| `legacyLockupIndexes` | `uint256[]`                    | A list of indexes to synchronize from the legacy veMav to the V2 ve contract. |

#### mintTokenInRewardToSender <a href="#minttokeninrewardtosender" id="minttokeninrewardtosender"></a>

```solidity
function mintTokenInRewardToSender(IMaverickV2Reward reward) external payable returns (uint256 tokenId);
```

#### mintTokenInReward <a href="#minttokeninreward" id="minttokeninreward"></a>

```solidity
function mintTokenInReward(IMaverickV2Reward reward, address recipient) external payable returns (uint256 tokenId);
```

<br>


# IMaverickV2RewardVault

### Functions <a href="#functions" id="functions"></a>

#### withdraw <a href="#withdraw" id="withdraw"></a>

This function allows the owner of the reward vault to withdraw a specified amount of staking tokens to a recipient address. If non-owner calls this function, it will revert.

```solidity
function withdraw(address recipient, uint256 amount) external;
```

**Parameters**

| Name        | Type      | Description                                                     |
| ----------- | --------- | --------------------------------------------------------------- |
| `recipient` | `address` | The address to which the withdrawn staking tokens will be sent. |
| `amount`    | `uint256` | The amount of staking tokens to withdraw.                       |

#### owner <a href="#owner" id="owner"></a>

This function retrieves the address of the owner of the reward vault contract.

```solidity
function owner() external view returns (address);
```

#### stakingToken <a href="#stakingtoken" id="stakingtoken"></a>

This function retrieves the address of the ERC20 token used for staking within the reward vault.

```solidity
function stakingToken() external view returns (IERC20);
```

### Errors <a href="#errors" id="errors"></a>

#### RewardVaultUnauthorizedAccount <a href="#rewardvaultunauthorizedaccount" id="rewardvaultunauthorizedaccount"></a>

```solidity
error RewardVaultUnauthorizedAccount(address caller, address owner);
```

<br>


# IMaverickV2VotingEscrowBase

**Inherits:** IVotes, [IHistoricalBalance](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/votingescrowbase/ihistoricalbalance)

### Functions <a href="#functions" id="functions"></a>

#### MIN\_STAKE\_DURATION <a href="#min_stake_duration" id="min_stake_duration"></a>

```solidity
function MIN_STAKE_DURATION() external returns (uint256 duration);
```

#### MAX\_STAKE\_DURATION <a href="#max_stake_duration" id="max_stake_duration"></a>

```solidity
function MAX_STAKE_DURATION() external returns (uint256 duration);
```

#### YEAR\_BASE <a href="#year_base" id="year_base"></a>

```solidity
function YEAR_BASE() external returns (uint256);
```

#### baseToken <a href="#basetoken" id="basetoken"></a>

This function retrieves the address of the ERC20 token used as the base token for staking and rewards.

```solidity
function baseToken() external returns (IERC20);
```

**Returns**

| Name     | Type     | Description                                              |
| -------- | -------- | -------------------------------------------------------- |
| `<none>` | `IERC20` | baseToken The address of the IERC20 base token contract. |

#### startTimestamp <a href="#starttimestamp" id="starttimestamp"></a>

This function retrieves the starting timestamp. This may be used for reward calculations or other time-based logic.

```solidity
function startTimestamp() external returns (uint256 timestamp);
```

#### getLockup <a href="#getlockup" id="getlockup"></a>

This function retrieves the details of a specific lockup for a given staker and lockup index.

```solidity
function getLockup(address staker, uint256 index) external view returns (Lockup memory lockup);
```

**Parameters**

| Name     | Type      | Description                                                         |
| -------- | --------- | ------------------------------------------------------------------- |
| `staker` | `address` | The address of the staker for which to retrieve the lockup details. |
| `index`  | `uint256` | The index of the lockup within the staker's lockup history.         |

**Returns**

| Name     | Type     | Description                                                                              |
| -------- | -------- | ---------------------------------------------------------------------------------------- |
| `lockup` | `Lockup` | A Lockup struct containing details about the lockup (see struct definition for details). |

#### lockupCount <a href="#lockupcount" id="lockupcount"></a>

This function retrieves the total number of lockups associated with a specific staker.

```solidity
function lockupCount(address staker) external view returns (uint256 count);
```

**Parameters**

| Name     | Type      | Description                                                       |
| -------- | --------- | ----------------------------------------------------------------- |
| `staker` | `address` | The address of the staker for which to retrieve the lockup count. |

**Returns**

| Name    | Type      | Description                                 |
| ------- | --------- | ------------------------------------------- |
| `count` | `uint256` | The total number of lockups for the staker. |

#### previewVotes <a href="#previewvotes" id="previewvotes"></a>

This function simulates a lockup scenario, providing details about the resulting lockup structure for a specified amount and duration.

```solidity
function previewVotes(uint128 amount, uint256 duration) external view returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                        |
| ---------- | --------- | ---------------------------------- |
| `amount`   | `uint128` | The amount of tokens to be locked. |
| `duration` | `uint256` | The duration of the lockup period. |

**Returns**

| Name     | Type     | Description                                                                                        |
| -------- | -------- | -------------------------------------------------------------------------------------------------- |
| `lockup` | `Lockup` | A Lockup struct containing details about the simulated lockup (see struct definition for details). |

#### approveExtender <a href="#approveextender" id="approveextender"></a>

This function grants approval for a designated extender contract to manage a specific lockup on behalf of the staker.

```solidity
function approveExtender(address extender, uint256 lockupId) external;
```

**Parameters**

| Name       | Type      | Description                                          |
| ---------- | --------- | ---------------------------------------------------- |
| `extender` | `address` | The address of the extender contract to be approved. |
| `lockupId` | `uint256` | The ID of the lockup for which to grant approval.    |

#### revokeExtender <a href="#revokeextender" id="revokeextender"></a>

This function revokes approval previously granted to an extender contract for managing a specific lockup.

```solidity
function revokeExtender(address extender, uint256 lockupId) external;
```

**Parameters**

| Name       | Type      | Description                                                           |
| ---------- | --------- | --------------------------------------------------------------------- |
| `extender` | `address` | The address of the extender contract whose approval is being revoked. |
| `lockupId` | `uint256` | The ID of the lockup for which to revoke approval.                    |

#### isApprovedExtender <a href="#isapprovedextender" id="isapprovedextender"></a>

This function checks whether a specific account has been approved by a staker to manage a particular lockup through an extender contract.

```solidity
function isApprovedExtender(address account, address extender, uint256 lockupId) external view returns (bool);
```

**Parameters**

| Name       | Type      | Description                                                                                |
| ---------- | --------- | ------------------------------------------------------------------------------------------ |
| `account`  | `address` | The address of the account to check for approval (may be the extender or another account). |
| `extender` | `address` | The address of the extender contract for which to check approval.                          |
| `lockupId` | `uint256` | The ID of the lockup to verify approval for.                                               |

**Returns**

| Name     | Type   | Description                                                                        |
| -------- | ------ | ---------------------------------------------------------------------------------- |
| `<none>` | `bool` | isApproved True if the account is approved for the lockup, False otherwise (bool). |

#### extendForSender <a href="#extendforsender" id="extendforsender"></a>

This function extends the lockup period for the caller (msg.sender) for a specified lockup ID, adding a new duration and amount.

```solidity
function extendForSender(uint256 lockupId, uint256 duration, uint128 amount)
    external
    returns (Lockup memory newLockup);
```

**Parameters**

| Name       | Type      | Description                                      |
| ---------- | --------- | ------------------------------------------------ |
| `lockupId` | `uint256` | The ID of the lockup to be extended.             |
| `duration` | `uint256` | The additional duration to extend the lockup by. |
| `amount`   | `uint128` | The additional amount of tokens to be locked.    |

**Returns**

| Name        | Type     | Description                                                                                             |
| ----------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `newLockup` | `Lockup` | A Lockup struct containing details about the newly extended lockup (see struct definition for details). |

#### extendForAccount <a href="#extendforaccount" id="extendforaccount"></a>

This function extends the lockup period for a specified account, adding a new duration and amount. The caller (msg.sender) must be authorized to manage the lockup through an extender contract.

```solidity
function extendForAccount(address account, uint256 lockupId, uint256 duration, uint128 amount)
    external
    returns (Lockup memory newLockup);
```

**Parameters**

| Name       | Type      | Description                                                |
| ---------- | --------- | ---------------------------------------------------------- |
| `account`  | `address` | The address of the account whose lockup is being extended. |
| `lockupId` | `uint256` | The ID of the lockup to be extended.                       |
| `duration` | `uint256` | The additional duration to extend the lockup by.           |
| `amount`   | `uint128` | The additional amount of tokens to be locked.              |

**Returns**

| Name        | Type     | Description                                                                                             |
| ----------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `newLockup` | `Lockup` | A Lockup struct containing details about the newly extended lockup (see struct definition for details). |

#### merge <a href="#merge" id="merge"></a>

This function merges multiple lockups associated with the caller (msg.sender) into a single new lockup.

```solidity
function merge(uint256[] memory lockupIds) external returns (Lockup memory newLockup);
```

**Parameters**

| Name        | Type        | Description                                              |
| ----------- | ----------- | -------------------------------------------------------- |
| `lockupIds` | `uint256[]` | An array containing the IDs of the lockups to be merged. |

**Returns**

| Name        | Type     | Description                                                                                           |
| ----------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `newLockup` | `Lockup` | A Lockup struct containing details about the newly merged lockup (see struct definition for details). |

#### unstake <a href="#unstake" id="unstake"></a>

This function unstakes the specified lockup ID for the caller (msg.sender), returning the details of the unstaked lockup.

```solidity
function unstake(uint256 lockupId, address to) external returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                                                                                 |
| ---------- | --------- | ------------------------------------------------------------------------------------------- |
| `lockupId` | `uint256` | The ID of the lockup to be unstaked.                                                        |
| `to`       | `address` | The address to which the unstaked tokens should be sent (optional, defaults to msg.sender). |

**Returns**

| Name     | Type     | Description                                                                                       |
| -------- | -------- | ------------------------------------------------------------------------------------------------- |
| `lockup` | `Lockup` | A Lockup struct containing details about the unstaked lockup (see struct definition for details). |

#### unstakeToSender <a href="#unstaketosender" id="unstaketosender"></a>

This function is a simplified version of `unstake` that automatically sends the unstaked tokens to the caller (msg.sender).

```solidity
function unstakeToSender(uint256 lockupId) external returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                          |
| ---------- | --------- | ------------------------------------ |
| `lockupId` | `uint256` | The ID of the lockup to be unstaked. |

**Returns**

| Name     | Type     | Description                                                                                       |
| -------- | -------- | ------------------------------------------------------------------------------------------------- |
| `lockup` | `Lockup` | A Lockup struct containing details about the unstaked lockup (see struct definition for details). |

#### stakeToSender <a href="#staketosender" id="staketosender"></a>

This function stakes a specified amount of tokens for the caller (msg.sender) for a defined duration.

```solidity
function stakeToSender(uint128 amount, uint256 duration) external returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                        |
| ---------- | --------- | ---------------------------------- |
| `amount`   | `uint128` | The amount of tokens to be staked. |
| `duration` | `uint256` | The duration of the lockup period. |

**Returns**

| Name     | Type     | Description                                                                                            |
| -------- | -------- | ------------------------------------------------------------------------------------------------------ |
| `lockup` | `Lockup` | A Lockup struct containing details about the newly created lockup (see struct definition for details). |

#### stake <a href="#stake" id="stake"></a>

This function stakes a specified amount of tokens for a defined duration, allowing the caller (msg.sender) to specify an optional recipient for the staked tokens.

```solidity
function stake(uint128 amount, uint256 duration, address to) external returns (Lockup memory);
```

**Parameters**

| Name       | Type      | Description                                                                                 |
| ---------- | --------- | ------------------------------------------------------------------------------------------- |
| `amount`   | `uint128` | The amount of tokens to be staked.                                                          |
| `duration` | `uint256` | The duration of the lockup period.                                                          |
| `to`       | `address` | The address to which the staked tokens will be credited (optional, defaults to msg.sender). |

**Returns**

| Name     | Type     | Description                                                                                                   |
| -------- | -------- | ------------------------------------------------------------------------------------------------------------- |
| `<none>` | `Lockup` | lockup A Lockup struct containing details about the newly created lockup (see struct definition for details). |

#### incentiveTotals <a href="#incentivetotals" id="incentivetotals"></a>

This function retrieves the total incentive information for a specific ERC-20 token.

```solidity
function incentiveTotals(IERC20 token) external view returns (TokenIncentiveTotals memory);
```

**Parameters**

| Name    | Type     | Description                                                            |
| ------- | -------- | ---------------------------------------------------------------------- |
| `token` | `IERC20` | The address of the ERC20 token for which to retrieve incentive totals. |

**Returns**

| Name     | Type                   | Description                                                                                                               |
| -------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `TokenIncentiveTotals` | totals A TokenIncentiveTotals struct containing details about the token's incentives (see struct definition for details). |

#### incentiveBatchCount <a href="#incentivebatchcount" id="incentivebatchcount"></a>

This function retrieves the total number of created incentive batches.

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

**Returns**

| Name     | Type      | Description                                  |
| -------- | --------- | -------------------------------------------- |
| `<none>` | `uint256` | count The total number of incentive batches. |

#### claimInformation <a href="#claiminformation" id="claiminformation"></a>

This function retrieves claim information for a specific account and incentive batch index.

```solidity
function claimInformation(address account, uint256 batchIndex) external view returns (ClaimInformation memory info);
```

**Parameters**

| Name         | Type      | Description                                                               |
| ------------ | --------- | ------------------------------------------------------------------------- |
| `account`    | `address` | The address of the account for which to retrieve claim information.       |
| `batchIndex` | `uint256` | The index of the incentive batch for which to retrieve claim information. |

**Returns**

| Name   | Type               | Description                                                                                                                          |
| ------ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `info` | `ClaimInformation` | A ClaimInformation struct containing details about the account's claims for the specified batch (see struct definition for details). |

#### claimFromIncentiveBatchAndExtend <a href="#claimfromincentivebatchandextend" id="claimfromincentivebatchandextend"></a>

This function allows claiming rewards from a specific incentive batch while simultaneously extending a lockup with the claimed tokens.

```solidity
function claimFromIncentiveBatchAndExtend(uint256 batchIndex, uint256 lockupId)
    external
    returns (Lockup memory lockup, uint128 claimAmount);
```

**Parameters**

| Name         | Type      | Description                                                   |
| ------------ | --------- | ------------------------------------------------------------- |
| `batchIndex` | `uint256` | The index of the incentive batch from which to claim rewards. |
| `lockupId`   | `uint256` | The ID of the lockup to be extended with the claimed tokens.  |

**Returns**

| Name          | Type      | Description                                                                                                      |
| ------------- | --------- | ---------------------------------------------------------------------------------------------------------------- |
| `lockup`      | `Lockup`  | A Lockup struct containing details about the updated lockup after extension (see struct definition for details). |
| `claimAmount` | `uint128` | The amount of tokens claimed from the incentive batch.                                                           |

#### claimFromIncentiveBatch <a href="#claimfromincentivebatch" id="claimfromincentivebatch"></a>

This function allows claiming rewards from a specific incentive batch, without extending any lockups.

```solidity
function claimFromIncentiveBatch(uint256 batchIndex) external returns (Lockup memory lockup, uint128 claimAmount);
```

**Parameters**

| Name         | Type      | Description                                                   |
| ------------ | --------- | ------------------------------------------------------------- |
| `batchIndex` | `uint256` | The index of the incentive batch from which to claim rewards. |

**Returns**

| Name          | Type      | Description                                                                                                                                |
| ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `lockup`      | `Lockup`  | A Lockup struct containing details about the user's lockup that might have been affected by the claim (see struct definition for details). |
| `claimAmount` | `uint128` | The amount of tokens claimed from the incentive batch.                                                                                     |

#### createIncentiveBatch <a href="#createincentivebatch" id="createincentivebatch"></a>

This function creates a new incentive batch for a specified amount of incentive tokens, timepoint, stake duration, and associated ERC-20 token. An incentive batch is a reward of incentives put up by the caller at a certain timepoint. The incentive batch is claimable by ve holders after the timepoint has passed. The ve holders will receive their incentive pro rata of their vote balance (`pastbalanceOf`) at that timepoint. The incentivizer can specify that users have to stake the resulting incentive for a given `stakeDuration` number of seconds. `stakeDuration` can either be zero, meaning that no staking is required on redemption, or can be a number between `MIN_STAKE_DURATION()` and `MAX_STAKE_DURATION()`.

```solidity
function createIncentiveBatch(uint128 amount, uint48 timepoint, uint128 stakeDuration, IERC20 incentiveToken)
    external
    returns (uint256 index);
```

**Parameters**

| Name             | Type      | Description                                                                                |
| ---------------- | --------- | ------------------------------------------------------------------------------------------ |
| `amount`         | `uint128` | The total amount of incentive tokens to be distributed in the batch.                       |
| `timepoint`      | `uint48`  | The timepoint at which the incentive batch starts accruing rewards.                        |
| `stakeDuration`  | `uint128` | The duration of the lockup period required to be eligible for the incentive batch rewards. |
| `incentiveToken` | `IERC20`  | The address of the ERC20 token used for the incentive rewards.                             |

**Returns**

| Name    | Type      | Description                                     |
| ------- | --------- | ----------------------------------------------- |
| `index` | `uint256` | The index of the newly created incentive batch. |

### Events <a href="#events" id="events"></a>

#### Stake <a href="#stake-1" id="stake-1"></a>

```solidity
event Stake(address indexed user, uint256 lockupId, Lockup);
```

#### Unstake <a href="#unstake-1" id="unstake-1"></a>

```solidity
event Unstake(address indexed user, uint256 lockupId, Lockup);
```

#### ExtenderApproval <a href="#extenderapproval" id="extenderapproval"></a>

```solidity
event ExtenderApproval(address staker, address extender, uint256 lockupId, bool newState);
```

#### ClaimIncentiveBatch <a href="#claimincentivebatch" id="claimincentivebatch"></a>

```solidity
event ClaimIncentiveBatch(uint256 batchIndex, address account, uint256 claimAmount);
```

#### CreateNewIncentiveBatch <a href="#createnewincentivebatch" id="createnewincentivebatch"></a>

```solidity
event CreateNewIncentiveBatch(
    address user, uint256 amount, uint256 timepoint, uint256 stakeDuration, IERC20 incentiveToken
);
```

### Errors <a href="#errors" id="errors"></a>

#### VotingEscrowTransferNotSupported <a href="#votingescrowtransfernotsupported" id="votingescrowtransfernotsupported"></a>

```solidity
error VotingEscrowTransferNotSupported();
```

#### VotingEscrowInvalidAddress <a href="#votingescrowinvalidaddress" id="votingescrowinvalidaddress"></a>

```solidity
error VotingEscrowInvalidAddress(address);
```

#### VotingEscrowInvalidAmount <a href="#votingescrowinvalidamount" id="votingescrowinvalidamount"></a>

```solidity
error VotingEscrowInvalidAmount(uint256);
```

#### VotingEscrowInvalidDuration <a href="#votingescrowinvalidduration" id="votingescrowinvalidduration"></a>

```solidity
error VotingEscrowInvalidDuration(uint256 duration, uint256 minDuration, uint256 maxDuration);
```

#### VotingEscrowInvalidEndTime <a href="#votingescrowinvalidendtime" id="votingescrowinvalidendtime"></a>

```solidity
error VotingEscrowInvalidEndTime(uint256 newEnd, uint256 oldEnd);
```

#### VotingEscrowStakeStillLocked <a href="#votingescrowstakestilllocked" id="votingescrowstakestilllocked"></a>

```solidity
error VotingEscrowStakeStillLocked(uint256 currentTime, uint256 endTime);
```

#### VotingEscrowStakeAlreadRedeemed <a href="#votingescrowstakealreadredeemed" id="votingescrowstakealreadredeemed"></a>

```solidity
error VotingEscrowStakeAlreadRedeemed();
```

#### VotingEscrowNotApprovedExtender <a href="#votingescrownotapprovedextender" id="votingescrownotapprovedextender"></a>

```solidity
error VotingEscrowNotApprovedExtender(address account, address extender, uint256 lockupId);
```

#### VotingEscrowIncentiveAlreadyClaimed <a href="#votingescrowincentivealreadyclaimed" id="votingescrowincentivealreadyclaimed"></a>

```solidity
error VotingEscrowIncentiveAlreadyClaimed(address account, uint256 batchIndex);
```

#### VotingEscrowNoIncentivesToClaim <a href="#votingescrownoincentivestoclaim" id="votingescrownoincentivestoclaim"></a>

```solidity
error VotingEscrowNoIncentivesToClaim(address account, uint256 batchIndex);
```

#### VotingEscrowInvalidExtendIncentiveToken <a href="#votingescrowinvalidextendincentivetoken" id="votingescrowinvalidextendincentivetoken"></a>

```solidity
error VotingEscrowInvalidExtendIncentiveToken(IERC20 incentiveToken);
```

### Structs <a href="#structs" id="structs"></a>

#### Lockup <a href="#lockup" id="lockup"></a>

```solidity
struct Lockup {
    uint128 amount;
    uint128 end;
    uint256 votes;
}
```

#### ClaimInformation <a href="#claiminformation-1" id="claiminformation-1"></a>

```solidity
struct ClaimInformation {
    bool hasClaimed;
    uint128 claimAmount;
    uint256 stakeDuration;
    IERC20 incentiveToken;
}
```

#### TokenIncentiveTotals <a href="#tokenincentivetotals" id="tokenincentivetotals"></a>

```solidity
struct TokenIncentiveTotals {
    uint128 totalIncentives;
    uint128 claimedIncentives;
}
```


# IMaverickV2VotingEscrow

**Inherits:** [IMaverickV2VotingEscrowBase](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2votingescrowbase), IERC20Metadata, IERC6372


# IMaverickV2VotingEscrowFactory

### Functions <a href="#functions" id="functions"></a>

#### legacyVeMav <a href="#legacyvemav" id="legacyvemav"></a>

This function retrieves the address of the legacy Maverick V1 Voting Escrow (veMAV) token. The address will be zero for blockchains where this contract is deployed that do not have a legacy MAV contract deployed.

```solidity
function legacyVeMav() external view returns (IERC20);
```

**Returns**

| Name     | Type     | Description                                               |
| -------- | -------- | --------------------------------------------------------- |
| `<none>` | `IERC20` | legacyVeMav The address of the IERC20 legacy veMav token. |

#### isFactoryToken <a href="#isfactorytoken" id="isfactorytoken"></a>

This function checks whether a provided IMaverickV2VotingEscrow contract address was created by this factory.

```solidity
function isFactoryToken(IMaverickV2VotingEscrow veToken) external view returns (bool);
```

**Parameters**

| Name      | Type                      | Description                                                        |
| --------- | ------------------------- | ------------------------------------------------------------------ |
| `veToken` | `IMaverickV2VotingEscrow` | The address of the IMaverickV2VotingEscrow contract to be checked. |

**Returns**

| Name     | Type   | Description                                                                             |
| -------- | ------ | --------------------------------------------------------------------------------------- |
| `<none>` | `bool` | isFactoryToken True if the veToken was created by this factory, False otherwise (bool). |

#### createVotingEscrow <a href="#createvotingescrow" id="createvotingescrow"></a>

This function creates a new Maverick V2 Voting Escrow (veToken) contract for a specified ERC20 base token.

Once the ve contract is created, it will call `name()` and `symbol()` on the `baseToken`. If those functions do not exist, the ve creation will revert.

```solidity
function createVotingEscrow(IERC20 baseToken) external returns (IMaverickV2VotingEscrow veToken);
```

**Parameters**

| Name        | Type     | Description                                                                       |
| ----------- | -------- | --------------------------------------------------------------------------------- |
| `baseToken` | `IERC20` | The address of the ERC-20 token to be used as the base token for the new veToken. |

**Returns**

| Name      | Type                      | Description                                                        |
| --------- | ------------------------- | ------------------------------------------------------------------ |
| `veToken` | `IMaverickV2VotingEscrow` | The address of the newly created IMaverickV2VotingEscrow contract. |

#### votingEscrows <a href="#votingescrows" id="votingescrows"></a>

This function retrieves a paginated list of existing Maverick V2 Voting Escrow (veToken) contracts within a specified index range.

```solidity
function votingEscrows(uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2VotingEscrow[] memory votingEscrows);
```

**Parameters**

| Name         | Type      | Description                                           |
| ------------ | --------- | ----------------------------------------------------- |
| `startIndex` | `uint256` | The starting index for the desired range of veTokens. |
| `endIndex`   | `uint256` | The ending index for the desired range of veTokens.   |

**Returns**

| Name            | Type                        | Description                                                                                         |
| --------------- | --------------------------- | --------------------------------------------------------------------------------------------------- |
| `votingEscrows` | `IMaverickV2VotingEscrow[]` | An array of IMaverickV2VotingEscrow addresses representing the veTokens within the specified range. |

#### votingEscrowsLength <a href="#votingescrowslength" id="votingescrowslength"></a>

This function retrieves the total number of deployed Maverick V2 Voting Escrow (veToken) contracts.

```solidity
function votingEscrowsLength() external view returns (uint256 count);
```

**Returns**

| Name    | Type      | Description                   |
| ------- | --------- | ----------------------------- |
| `count` | `uint256` | The total number of veTokens. |

#### votingEscrowAddress <a href="#votingescrowaddress" id="votingescrowaddress"></a>

This function retrieves the address of the existing Maverick V2 Voting Escrow (veToken) contract associated with a specific ERC20 base token.

```solidity
function votingEscrowAddress(IERC20 baseToken) external view returns (IMaverickV2VotingEscrow veToken);
```

**Parameters**

| Name        | Type     | Description                                                                     |
| ----------- | -------- | ------------------------------------------------------------------------------- |
| `baseToken` | `IERC20` | The address of the ERC-20 base token for which to retrieve the veToken address. |

**Returns**

| Name      | Type                      | Description                                                                                                             |
| --------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `veToken` | `IMaverickV2VotingEscrow` | The address of the IMaverickV2VotingEscrow contract associated with the base token, or the zero address if none exists. |

#### baseTokenParameter <a href="#basetokenparameter" id="basetokenparameter"></a>

This function retrieves the default base token used for creating new voting escrow contracts. This state variable is only used temporarily when a new veToken is deployed.

```solidity
function baseTokenParameter() external returns (IERC20);
```

**Returns**

| Name     | Type     | Description                                             |
| -------- | -------- | ------------------------------------------------------- |
| `<none>` | `IERC20` | baseToken The address of the default ERC-20 base token. |

### Errors <a href="#errors" id="errors"></a>

#### VotingEscrowTokenAlreadyExists <a href="#votingescrowtokenalreadyexists" id="votingescrowtokenalreadyexists"></a>

```solidity
error VotingEscrowTokenAlreadyExists(IERC20 baseToken, IMaverickV2VotingEscrow veToken);
```

<br>


# IMaverickV2VotingEscrowLens

### Functions <a href="#functions" id="functions"></a>

#### claimInformation <a href="#claiminformation" id="claiminformation"></a>

This function retrieves paginated claim information for a specific account and claim index range within a provided Maverick V2 Voting Escrow (veToken) contract.

```solidity
function claimInformation(IMaverickV2VotingEscrow ve, address account, uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2VotingEscrow.ClaimInformation[] memory returnElements);
```

**Parameters**

| Name         | Type                      | Description                                                                                  |
| ------------ | ------------------------- | -------------------------------------------------------------------------------------------- |
| `ve`         | `IMaverickV2VotingEscrow` | The address of the IMaverickV2VotingEscrow contract for which to retrieve claim information. |
| `account`    | `address`                 | The address of the account for which to retrieve claim information.                          |
| `startIndex` | `uint256`                 | The starting index for the desired range of claims.                                          |
| `endIndex`   | `uint256`                 | The ending index for the desired range of claims.                                            |

**Returns**

| Name             | Type                                         | Description                                                                                                                                                 |
| ---------------- | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `returnElements` | `IMaverickV2VotingEscrow.ClaimInformation[]` | An array of `IMaverickV2VotingEscrow.ClaimInformation` structs containing details about claimable rewards for the specified account within the index range. |

#### syncInformation <a href="#syncinformation" id="syncinformation"></a>

This function retrieves paginated information on the lockup synchronization status for legacy ve mav.

```solidity
function syncInformation(IMaverickV2VotingEscrowWSync ve, address staker, uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2VotingEscrow.Lockup[] memory legacyLockups, uint256[] memory syncedBalances);
```

**Parameters**

| Name         | Type                           | Description                                                            |
| ------------ | ------------------------------ | ---------------------------------------------------------------------- |
| `ve`         | `IMaverickV2VotingEscrowWSync` | The address of the ve contract for which to retrieve sync information. |
| `staker`     | `address`                      | The address of the user for whom to retrieve sync information.         |
| `startIndex` | `uint256`                      | The starting index for the desired range of legacy lockups.            |
| `endIndex`   | `uint256`                      | The ending index for the desired range of legacy lockups.              |

**Returns**

| Name             | Type                               | Description                                                                                                                     |
| ---------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `legacyLockups`  | `IMaverickV2VotingEscrow.Lockup[]` | An array of `IMaverickV2VotingEscrow.Lockup` structs containing details about the user's legacy lockups within the index range. |
| `syncedBalances` | `uint256[]`                        | An array of uint256 values representing the synced balances corresponding to the legacy lockups.                                |

#### getLockups <a href="#getlockups" id="getlockups"></a>

This function retrieves paginated lockup information for a specific account and lockup index range within a provided Maverick V2 Voting Escrow (veToken) contract.

```solidity
function getLockups(IMaverickV2VotingEscrow ve, address staker, uint256 startIndex, uint256 endIndex)
    external
    view
    returns (IMaverickV2VotingEscrow.Lockup[] memory returnElements);
```

**Parameters**

| Name         | Type                      | Description                                                                                   |
| ------------ | ------------------------- | --------------------------------------------------------------------------------------------- |
| `ve`         | `IMaverickV2VotingEscrow` | The address of the IMaverickV2VotingEscrow contract for which to retrieve lockup information. |
| `staker`     | `address`                 | The address of the account for which to retrieve lockup information.                          |
| `startIndex` | `uint256`                 | The starting index for the desired range of lockups.                                          |
| `endIndex`   | `uint256`                 | The ending index for the desired range of lockups.                                            |

**Returns**

| Name             | Type                               | Description                                                                                                                                 |
| ---------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `returnElements` | `IMaverickV2VotingEscrow.Lockup[]` | An array of `IMaverickV2VotingEscrow.Lockup` structs containing details about the lockups within the specified index range for the account. |

<br>


# IMaverickV2VotingEscrowWSync

### Functions <a href="#functions" id="functions"></a>

#### MIN\_SYNC\_DURATION <a href="#min_sync_duration" id="min_sync_duration"></a>

This function retrieves the minimum lockup duration required for a legacy lockup to be eligible for synchronization.

```solidity
function MIN_SYNC_DURATION() external pure returns (uint256 minSyncDuration);
```

**Returns**

| Name              | Type      | Description                          |
| ----------------- | --------- | ------------------------------------ |
| `minSyncDuration` | `uint256` | The minimum allowed lockup end time. |

#### legacyVeMav <a href="#legacyvemav" id="legacyvemav"></a>

This function retrieves the address of the legacy Maverick V1 Voting Escrow (veMav) token.

```solidity
function legacyVeMav() external view returns (IERC20);
```

**Returns**

| Name     | Type     | Description                                               |
| -------- | -------- | --------------------------------------------------------- |
| `<none>` | `IERC20` | legacyVeMav The address of the IERC20 legacy veMav token. |

#### syncBalances <a href="#syncbalances" id="syncbalances"></a>

This function retrieves the synced balance for a specific legacy lockup index of a user.

```solidity
function syncBalances(address staker, uint256 legacyLockupIndex) external view returns (uint256 balance);
```

**Parameters**

| Name                | Type      | Description                                                              |
| ------------------- | --------- | ------------------------------------------------------------------------ |
| `staker`            | `address` | The address of the user for whom to retrieve the synced balance.         |
| `legacyLockupIndex` | `uint256` | The index of the legacy lockup for which to retrieve the synced balance. |

**Returns**

| Name      | Type      | Description                                           |
| --------- | --------- | ----------------------------------------------------- |
| `balance` | `uint256` | The synced balance associated with the legacy lockup. |

#### sync <a href="#sync" id="sync"></a>

This function synchronizes a specific legacy lockup index for a user within the contract. If the legacy lockup.end is not at least `block.timestamp + MIN_SYNC_DURATION()`, this function will revert.

```solidity
function sync(address staker, uint256 legacyLockupIndex) external returns (uint256 newBalance);
```

**Parameters**

| Name                | Type      | Description                                                  |
| ------------------- | --------- | ------------------------------------------------------------ |
| `staker`            | `address` | The address of the user for whom to perform synchronization. |
| `legacyLockupIndex` | `uint256` | The index of the legacy lockup to be synchronized.           |

**Returns**

| Name         | Type      | Description                                                 |
| ------------ | --------- | ----------------------------------------------------------- |
| `newBalance` | `uint256` | The new balance resulting from the synchronization process. |

### Events <a href="#events" id="events"></a>

#### Sync <a href="#sync-1" id="sync-1"></a>

```solidity
event Sync(address staker, uint256 legacyLockupIndex, uint256 newBalance);
```

### Errors <a href="#errors" id="errors"></a>

#### VotingEscrowLockupEndTooShortToSync <a href="#votingescrowlockupendtooshorttosync" id="votingescrowlockupendtooshorttosync"></a>

```solidity
error VotingEscrowLockupEndTooShortToSync(uint256 legacyLockupEnd, uint256 minimumLockupEnd);
```

<br>


# libraries

* [IncentiveMatcherDeployer](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/libraries/incentivematcherdeployer)
* [RewardDeployer](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/libraries/rewarddeployer)
* [VotingEscrowDeployer](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/libraries/votingescrowdeployer)
* [VotingEscrowWSyncDeployer](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/libraries/votingescrowwsyncdeployer)


# IncentiveMatcherDeployer

### Functions <a href="#functions" id="functions"></a>

#### deploy <a href="#deploy" id="deploy"></a>

```solidity
function deploy(IMaverickV2VotingEscrow veToken, IMaverickV2RewardFactory factory)
    external
    returns (IMaverickV2IncentiveMatcher incentiveMatcher);
```

#### incentiveMatcherBytecodeHash <a href="#incentivematcherbytecodehash" id="incentivematcherbytecodehash"></a>

```solidity
function incentiveMatcherBytecodeHash() external pure returns (bytes32);
```

<br>


# RewardDeployer

### Functions <a href="#functions" id="functions"></a>

#### deploy <a href="#deploy" id="deploy"></a>

```solidity
function deploy(
    string memory name_,
    string memory symbol_,
    IERC20 _stakingToken,
    IERC20[] memory rewardTokens,
    IMaverickV2VotingEscrow[] memory veTokens
) external returns (IMaverickV2Reward reward);
```

<br>


# VotingEscrowDeployer

### Functions <a href="#functions" id="functions"></a>

#### deploy <a href="#deploy" id="deploy"></a>

```solidity
function deploy(IERC20 baseToken, string memory name, string memory symbol)
    external
    returns (IMaverickV2VotingEscrow votingEscrow);
```

#### votingEscrowBytecodeHash <a href="#votingescrowbytecodehash" id="votingescrowbytecodehash"></a>

```solidity
function votingEscrowBytecodeHash(string memory name, string memory symbol) external pure returns (bytes32);
```

<br>


# VotingEscrowWSyncDeployer

### Functions <a href="#functions" id="functions"></a>

#### deploy <a href="#deploy" id="deploy"></a>

```solidity
function deploy(IERC20 baseToken, string memory name, string memory symbol)
    external
    returns (IMaverickV2VotingEscrow votingEscrow);
```

#### votingEscrowBytecodeHash <a href="#votingescrowbytecodehash" id="votingescrowbytecodehash"></a>

```solidity
function votingEscrowBytecodeHash(string memory name, string memory symbol) external pure returns (bytes32);
```

<br>


# rewardbase

* [IRewardAccounting](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/rewardbase/irewardaccounting)
* [RewardAccounting](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/rewardbase/rewardaccounting)


# IRewardAccounting

### Functions <a href="#functions" id="functions"></a>

#### stakeBalanceOf <a href="#stakebalanceof" id="stakebalanceof"></a>

Balance of stake for a given `tokenId` account.

```solidity
function stakeBalanceOf(uint256 tokenId) external view returns (uint256 balance);
```

#### stakeTotalSupply <a href="#staketotalsupply" id="staketotalsupply"></a>

Sum of all balances across all tokenIds.

```solidity
function stakeTotalSupply() external view returns (uint256 supply);
```

### Errors <a href="#errors" id="errors"></a>

#### InsufficientBalance <a href="#insufficientbalance" id="insufficientbalance"></a>

```solidity
error InsufficientBalance(uint256 tokenId, uint256 currentBalance, uint256 value);
```

<br>


# RewardAccounting

**Inherits:** [IRewardAccounting](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/rewardbase/irewardaccounting)

Provides ERC20-like functions for minting, burning, balance tracking and total supply. Tracking is based on a tokenId user index instead of an address.

### State Variables <a href="#state-variables" id="state-variables"></a>

#### \_stakeBalances <a href="#stakebalances" id="stakebalances"></a>

```solidity
mapping(uint256 account => uint256) private _stakeBalances;
```

#### \_stakeTotalSupply <a href="#staketotalsupply" id="staketotalsupply"></a>

```solidity
uint256 private _stakeTotalSupply;
```

### Functions <a href="#functions" id="functions"></a>

#### stakeBalanceOf <a href="#stakebalanceof" id="stakebalanceof"></a>

Balance of stake for a given `tokenId` account.

```solidity
function stakeBalanceOf(uint256 tokenId) public view returns (uint256 balance);
```

#### stakeTotalSupply <a href="#staketotalsupply" id="staketotalsupply"></a>

Sum of all balances across all tokenIds.

```solidity
function stakeTotalSupply() public view returns (uint256 supply);
```

#### \_mintStake <a href="#mintstake" id="mintstake"></a>

Mint to staking account for a tokenId account.

```solidity
function _mintStake(uint256 tokenId, uint256 value) internal;
```

#### \_burnStake <a href="#burnstake" id="burnstake"></a>

Burn from staking account for a tokenId account.

```solidity
function _burnStake(uint256 tokenId, uint256 value) internal;
```

<br>


# votingescrowbase

* [HistoricalBalance](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/votingescrowbase/historicalbalance)
* [IHistoricalBalance](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/votingescrowbase/ihistoricalbalance)
* [ILegacyVeMav](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/votingescrowbase/ilegacyvemav)
* [VotingEscrow](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/votingescrowbase/votingescrow)


# HistoricalBalance

**Inherits:** ERC20Votes, [IHistoricalBalance](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/votingescrowbase/ihistoricalbalance)

Adds support for tracking historical balance on ERC20Votes (not just historical voting power) and adds support for contributing and retrieving incentives pro-rata of historical balanceOf.

Uses a timestamp-based clock for checkpoints as opposed to the default OZ implementation that is blocknumber based.

### State Variables <a href="#state-variables" id="state-variables"></a>

#### \_balanceOfCheckpoints <a href="#balanceofcheckpoints" id="balanceofcheckpoints"></a>

```solidity
mapping(address account => Checkpoints.Trace208) private _balanceOfCheckpoints;
```

### Functions <a href="#functions" id="functions"></a>

#### getPastBalanceOf <a href="#getpastbalanceof" id="getpastbalanceof"></a>

This function retrieves the historical balance of an account at a specific point in time.

```solidity
function getPastBalanceOf(address account, uint256 timepoint) public view returns (uint256 balance);
```

**Parameters**

| Name        | Type      | Description                                                                                                    |
| ----------- | --------- | -------------------------------------------------------------------------------------------------------------- |
| `account`   | `address` | The address of the account for which to retrieve the historical balance.                                       |
| `timepoint` | `uint256` | The timepoint (block number or timestamp depending on implementation) at which to query the balance (uint256). |

**Returns**

| Name      | Type      | Description                                            |
| --------- | --------- | ------------------------------------------------------ |
| `balance` | `uint256` | The balance of the account at the specified timepoint. |

#### \_update <a href="#update" id="update"></a>

```solidity
function _update(address from, address to, uint256 amount) internal virtual override;
```

#### clock <a href="#clock" id="clock"></a>

```solidity
function clock() public view override returns (uint48);
```

#### CLOCK\_MODE <a href="#clock_mode" id="clock_mode"></a>

Machine-readable description of the clock as specified in ERC-6372.

```solidity
function CLOCK_MODE() public pure override returns (string memory);
```

#### \_\_push <a href="#push" id="push"></a>

```solidity
function __push(Checkpoints.Trace208 storage store, function(uint208, uint208) view returns (uint208) op, uint208 delta)
    private
    returns (uint208, uint208);
```

#### \_\_add <a href="#add" id="add"></a>

```solidity
function __add(uint208 a, uint208 b) private pure returns (uint208);
```

#### \_\_subtract <a href="#subtract" id="subtract"></a>

```solidity
function __subtract(uint208 a, uint208 b) private pure returns (uint208);
```

<br>


# IHistoricalBalance

### Functions <a href="#functions" id="functions"></a>

#### getPastBalanceOf <a href="#getpastbalanceof" id="getpastbalanceof"></a>

This function retrieves the historical balance of an account at a specific point in time.

```solidity
function getPastBalanceOf(address account, uint256 timepoint) external view returns (uint256 balance);
```

**Parameters**

| Name        | Type      | Description                                                                                          |
| ----------- | --------- | ---------------------------------------------------------------------------------------------------- |
| `account`   | `address` | The address of the account for which to retrieve the historical balance.                             |
| `timepoint` | `uint256` | The timepoint (block number or timestamp depending on implementation) at which to query the balance. |

**Returns**

| Name      | Type      | Description                                            |
| --------- | --------- | ------------------------------------------------------ |
| `balance` | `uint256` | The balance of the account at the specified timepoint. |


# ILegacyVeMav

### Functions <a href="#functions" id="functions"></a>

#### epoch <a href="#epoch" id="epoch"></a>

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

#### lockups <a href="#lockups" id="lockups"></a>

```solidity
function lockups(address staker, uint256 legacyLockupIndex)
    external
    view
    returns (IMaverickV2VotingEscrow.Lockup memory);
```

#### lockupCount <a href="#lockupcount" id="lockupcount"></a>

```solidity
function lockupCount(address staker) external view returns (uint256 count);
```

#### mav <a href="#mav" id="mav"></a>

```solidity
function mav() external view returns (IERC20);
```

<br>


# VotingEscrow

**Inherits:** [HistoricalBalance](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/votingescrowbase/historicalbalance),[ IMaverickV2VotingEscrowBase](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2votingescrowbase), ReentrancyGuard, [Multicall](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/base/multicall)

Provides staking, vote power history, vote delegation. The balance received for staking (and thus the voting power) goes up exponentially by the end of the staked period.

### State Variables <a href="#state-variables" id="state-variables"></a>

#### YEAR\_BASE <a href="#year_base" id="year_base"></a>

```solidity
uint256 public constant YEAR_BASE = 1.5e18;
```

#### startTimestamp <a href="#starttimestamp" id="starttimestamp"></a>

This function retrieves the starting timestamp. This may be used for reward calculations or other time-based logic.

```solidity
uint256 public immutable startTimestamp;
```

#### MIN\_STAKE\_DURATION <a href="#min_stake_duration" id="min_stake_duration"></a>

```solidity
uint256 public constant MIN_STAKE_DURATION = 4 weeks;
```

#### MAX\_STAKE\_DURATION <a href="#max_stake_duration" id="max_stake_duration"></a>

```solidity
uint256 public constant MAX_STAKE_DURATION = 4 * (365 days);
```

#### \_lockups <a href="#lockups" id="lockups"></a>

```solidity
mapping(address => Lockup[]) internal _lockups;
```

#### \_extenders <a href="#extenders" id="extenders"></a>

```solidity
mapping(address => mapping(address => mapping(uint256 => bool))) internal _extenders;
```

#### baseToken <a href="#basetoken" id="basetoken"></a>

This function retrieves the address of the ERC20 token used as the base token for staking and rewards.

```solidity
IERC20 public immutable baseToken;
```

### Functions <a href="#functions" id="functions"></a>

#### constructor <a href="#constructor" id="constructor"></a>

```solidity
constructor(string memory __name, string memory __symbol) ERC20(__name, __symbol) EIP712(__name, "1");
```

#### \_stake <a href="#stake" id="stake"></a>

Internal function that stakes an amount for a duration to an address.

This function validates that `to` is not the zero address and that the duration is within bounds.

Function also does a transferFrom for the base token amount. This requires that the sender approve this ve contract to be able to transfer tokens for the sender.

```solidity
function _stake(uint128 amount, uint256 duration, address to, uint256 lockupId)
    internal
    nonReentrant
    returns (Lockup memory lockup);
```

#### \_unstake <a href="#unstake" id="unstake"></a>

Internal function that unstakes an account's lockup.

This function validates that the lockup has not already been claimed and does burn the account's voting votes.

But the function does not transfer the baseTokens to the staker. That transfer operation must be executed seperately as appropiate.

This function also does not validate that the lockup end time has passed nor does it validate that `account` has permissions to unstake this lockupId.

```solidity
function _unstake(address account, uint256 lockupId) internal returns (Lockup memory lockup);
```

#### \_extend <a href="#extend" id="extend"></a>

Internal function that extends an account's lockup.

This function validates that the lockup has not already been claimed.

This function also does not validate that the `account` has permissions to unstake this lockupId.

```solidity
function _extend(address account, uint256 lockupId, uint256 duration, uint128 amount)
    internal
    returns (Lockup memory newLockup);
```

#### stake <a href="#stake" id="stake"></a>

This function stakes a specified amount of tokens for a defined duration, allowing the caller (msg.sender) to specify an optional recipient for the staked tokens.

```solidity
function stake(uint128 amount, uint256 duration, address to) public returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                                                                                 |
| ---------- | --------- | ------------------------------------------------------------------------------------------- |
| `amount`   | `uint128` | The amount of tokens to be staked.                                                          |
| `duration` | `uint256` | The duration of the lockup period.                                                          |
| `to`       | `address` | The address to which the staked tokens will be credited (optional, defaults to msg.sender). |

**Returns**

| Name     | Type     | Description                                                                                            |
| -------- | -------- | ------------------------------------------------------------------------------------------------------ |
| `lockup` | `Lockup` | A Lockup struct containing details about the newly created lockup (see struct definition for details). |

#### stakeToSender <a href="#staketosender" id="staketosender"></a>

This function stakes a specified amount of tokens for the caller (msg.sender) for a defined duration.

```solidity
function stakeToSender(uint128 amount, uint256 duration) public virtual returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                        |
| ---------- | --------- | ---------------------------------- |
| `amount`   | `uint128` | The amount of tokens to be staked. |
| `duration` | `uint256` | The duration of the lockup period. |

**Returns**

| Name     | Type     | Description                                                                                            |
| -------- | -------- | ------------------------------------------------------------------------------------------------------ |
| `lockup` | `Lockup` | A Lockup struct containing details about the newly created lockup (see struct definition for details). |

#### unstake <a href="#unstake" id="unstake"></a>

This function unstakes the specified lockup ID for the caller (msg.sender), returning the details of the unstaked lockup.

```solidity
function unstake(uint256 lockupId, address to) public nonReentrant returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                                                                                 |
| ---------- | --------- | ------------------------------------------------------------------------------------------- |
| `lockupId` | `uint256` | The ID of the lockup to be unstaked.                                                        |
| `to`       | `address` | The address to which the unstaked tokens should be sent (optional, defaults to msg.sender). |

**Returns**

| Name     | Type     | Description                                                                                       |
| -------- | -------- | ------------------------------------------------------------------------------------------------- |
| `lockup` | `Lockup` | A Lockup struct containing details about the unstaked lockup (see struct definition for details). |

#### unstakeToSender <a href="#unstaketosender" id="unstaketosender"></a>

This function is a simplified version of `unstake` that automatically sends the unstaked tokens to the caller (msg.sender).

```solidity
function unstakeToSender(uint256 lockupId) public returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                          |
| ---------- | --------- | ------------------------------------ |
| `lockupId` | `uint256` | The ID of the lockup to be unstaked. |

**Returns**

| Name     | Type     | Description                                                                                       |
| -------- | -------- | ------------------------------------------------------------------------------------------------- |
| `lockup` | `Lockup` | A Lockup struct containing details about the unstaked lockup (see struct definition for details). |

#### merge <a href="#merge" id="merge"></a>

This function merges multiple lockups associated with the caller (msg.sender) into a single new lockup.

```solidity
function merge(uint256[] memory lockupIds) public returns (Lockup memory newLockup);
```

**Parameters**

| Name        | Type        | Description                                              |
| ----------- | ----------- | -------------------------------------------------------- |
| `lockupIds` | `uint256[]` | An array containing the IDs of the lockups to be merged. |

**Returns**

| Name        | Type     | Description                                                                                           |
| ----------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `newLockup` | `Lockup` | A Lockup struct containing details about the newly merged lockup (see struct definition for details). |

#### extendForSender <a href="#extendforsender" id="extendforsender"></a>

This function extends the lockup period for the caller (msg.sender) for a specified lockup ID, adding a new duration and amount.

```solidity
function extendForSender(uint256 lockupId, uint256 duration, uint128 amount)
    public
    virtual
    returns (Lockup memory newLockup);
```

**Parameters**

| Name       | Type      | Description                                      |
| ---------- | --------- | ------------------------------------------------ |
| `lockupId` | `uint256` | The ID of the lockup to be extended.             |
| `duration` | `uint256` | The additional duration to extend the lockup by. |
| `amount`   | `uint128` | The additional amount of tokens to be locked.    |

**Returns**

| Name        | Type     | Description                                                                                             |
| ----------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `newLockup` | `Lockup` | A Lockup struct containing details about the newly extended lockup (see struct definition for details). |

#### extendForAccount <a href="#extendforaccount" id="extendforaccount"></a>

This function extends the lockup period for a specified account, adding a new duration and amount. The caller (msg.sender) must be authorized to manage the lockup through an extender contract.

```solidity
function extendForAccount(address account, uint256 lockupId, uint256 duration, uint128 amount)
    public
    returns (Lockup memory newLockup);
```

**Parameters**

| Name       | Type      | Description                                                |
| ---------- | --------- | ---------------------------------------------------------- |
| `account`  | `address` | The address of the account whose lockup is being extended. |
| `lockupId` | `uint256` | The ID of the lockup to be extended.                       |
| `duration` | `uint256` | The additional duration to extend the lockup by.           |
| `amount`   | `uint128` | The additional amount of tokens to be locked.              |

**Returns**

| Name        | Type     | Description                                                                                             |
| ----------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `newLockup` | `Lockup` | A Lockup struct containing details about the newly extended lockup (see struct definition for details). |

#### approveExtender <a href="#approveextender" id="approveextender"></a>

This function grants approval for a designated extender contract to manage a specific lockup on behalf of the staker.

```solidity
function approveExtender(address extender, uint256 lockupId) public;
```

**Parameters**

| Name       | Type      | Description                                          |
| ---------- | --------- | ---------------------------------------------------- |
| `extender` | `address` | The address of the extender contract to be approved. |
| `lockupId` | `uint256` | The ID of the lockup for which to grant approval.    |

#### revokeExtender <a href="#revokeextender" id="revokeextender"></a>

This function revokes approval previously granted to an extender contract for managing a specific lockup.

```solidity
function revokeExtender(address extender, uint256 lockupId) public;
```

**Parameters**

| Name       | Type      | Description                                                           |
| ---------- | --------- | --------------------------------------------------------------------- |
| `extender` | `address` | The address of the extender contract whose approval is being revoked. |
| `lockupId` | `uint256` | The ID of the lockup for which to revoke approval.                    |

#### isApprovedExtender <a href="#isapprovedextender" id="isapprovedextender"></a>

This function checks whether a specific account has been approved by a staker to manage a particular lockup through an extender contract.

```solidity
function isApprovedExtender(address account, address extender, uint256 lockupId) public view returns (bool);
```

**Parameters**

| Name       | Type      | Description                                                                                |
| ---------- | --------- | ------------------------------------------------------------------------------------------ |
| `account`  | `address` | The address of the account to check for approval (may be the extender or another account). |
| `extender` | `address` | The address of the extender contract for which to check approval.                          |
| `lockupId` | `uint256` | The ID of the lockup to verify approval for.                                               |

**Returns**

| Name     | Type   | Description                                                                        |
| -------- | ------ | ---------------------------------------------------------------------------------- |
| `<none>` | `bool` | isApproved True if the account is approved for the lockup, False otherwise (bool). |

#### \_checkApprovedExtender <a href="#checkapprovedextender" id="checkapprovedextender"></a>

```solidity
function _checkApprovedExtender(address account, uint256 lockupId) internal view;
```

#### \_checkDuration <a href="#checkduration" id="checkduration"></a>

```solidity
function _checkDuration(uint256 duration) internal pure;
```

#### previewVotes <a href="#previewvotes" id="previewvotes"></a>

This function simulates a lockup scenario, providing details about the resulting lockup structure for a specified amount and duration.

```solidity
function previewVotes(uint128 amount, uint256 duration) public view returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                        |
| ---------- | --------- | ---------------------------------- |
| `amount`   | `uint128` | The amount of tokens to be locked. |
| `duration` | `uint256` | The duration of the lockup period. |

**Returns**

| Name     | Type     | Description                                                                                        |
| -------- | -------- | -------------------------------------------------------------------------------------------------- |
| `lockup` | `Lockup` | A Lockup struct containing details about the simulated lockup (see struct definition for details). |

#### getLockup <a href="#getlockup" id="getlockup"></a>

This function retrieves the details of a specific lockup for a given staker and lockup index.

```solidity
function getLockup(address staker, uint256 index) public view returns (Lockup memory lockup);
```

**Parameters**

| Name     | Type      | Description                                                         |
| -------- | --------- | ------------------------------------------------------------------- |
| `staker` | `address` | The address of the staker for which to retrieve the lockup details. |
| `index`  | `uint256` | The index of the lockup within the staker's lockup history.         |

**Returns**

| Name     | Type     | Description                                                                              |
| -------- | -------- | ---------------------------------------------------------------------------------------- |
| `lockup` | `Lockup` | A Lockup struct containing details about the lockup (see struct definition for details). |

#### lockupCount <a href="#lockupcount" id="lockupcount"></a>

This function retrieves the total number of lockups associated with a specific staker.

```solidity
function lockupCount(address staker) public view returns (uint256 count);
```

**Parameters**

| Name     | Type      | Description                                                       |
| -------- | --------- | ----------------------------------------------------------------- |
| `staker` | `address` | The address of the staker for which to retrieve the lockup count. |

**Returns**

| Name    | Type      | Description                                 |
| ------- | --------- | ------------------------------------------- |
| `count` | `uint256` | The total number of lockups for the staker. |

#### transfer <a href="#transfer" id="transfer"></a>

Transfers of voting balances are not allowed. This function will revert.

```solidity
function transfer(address, uint256) public pure override returns (bool);
```

#### transferFrom <a href="#transferfrom" id="transferfrom"></a>

Transfers of voting balances are not allowed. This function will revert.

```solidity
function transferFrom(address, address, uint256) public pure override returns (bool);
```

<br>


# MaverickV2IncentiveMatcher

**Inherits:** [IMaverickV2IncentiveMatcher](/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/interfaces/imaverickv2incentivematcher), ReentrancyGuard, [Multicall](/technical-reference/maverick-v2/v2-contracts/maverick-v2-common-contracts/base/multicall)

IncentiveMatcher contract is deployed along with a ve token by the ve token factory. This contract allows protocols to provide matching incentives to Maverick BPs and allows ve holders to vote their token to increase the match in a BP. IncentiveMatcher has a concept of a matching epoch and the following actors:

* BP incentive adder
* Matching budget adder
* Voter

The lifecycle of an epoch is as follows:

* Anytime before or during an epoch, any party can permissionlessly add a matching and/or voting incentive budget to an epoch. These incentives will boost incentives added to any BPs during the epoch.
* During the epoch any party can permissionlessly add incentives to BPs. These incentives are eligible to be boosted through matching and voting.
* During the voting portion of the epoch, any ve holder can cast their ve vote for eligible BPs.
* At the end of the epoch, there is a vetoing period where any user who provided matching incentive budget can choose to veto a BP from being matched by their portion of the matching budget.
* At the end of the vetoing period, the matching rewards are elgible for distribution. Any user can permissionlessly call `distribute` for a given BP and epoch. This call will compute the matching boost for the BP and then send the BP reward contract the matching amount, which will in turn distribute the reward to the BP LPs.

### State Variables <a href="#state-variables" id="state-variables"></a>

#### EPOCH\_PERIOD <a href="#epoch_period" id="epoch_period"></a>

This function retrieves the epoch period length.

```solidity
uint256 public constant EPOCH_PERIOD = 1 days;
```

#### PRE\_VOTE\_PERIOD <a href="#pre_vote_period" id="pre_vote_period"></a>

This function retrieves the period length of the epoch before voting starts. After an epoch begins, there is a window of time where voting is not possible which is the value this function returns.

```solidity
uint256 public constant PRE_VOTE_PERIOD = 12 hours;
```

#### VETO\_PERIOD <a href="#veto_period" id="veto_period"></a>

This function retrieves the vetoing period length.

```solidity
uint256 public constant VETO_PERIOD = 5 hours;
```

#### NOTIFY\_PERIOD <a href="#notify_period" id="notify_period"></a>

The function retrieves the notify period length, which is the amount of time in seconds during which the matching reward will be distributed through the rewards contract.

```solidity
uint256 public constant NOTIFY_PERIOD = 14 days;
```

#### baseToken <a href="#basetoken" id="basetoken"></a>

This function retrieves the base token used by the IncentiveMatcher contract.

```solidity
IERC20 public immutable baseToken;
```

#### factory <a href="#factory" id="factory"></a>

This function retrieves the address of the MaverickV2RewardFactory contract.

```solidity
IMaverickV2RewardFactory public immutable factory;
```

#### veToken <a href="#vetoken" id="vetoken"></a>

This function retrieves the address of the veToken contract.

```solidity
IMaverickV2VotingEscrow public immutable veToken;
```

#### hasVoted <a href="#hasvoted" id="hasvoted"></a>

This function checks if a specific user has voted in a particular epoch.

```solidity
mapping(address user => mapping(uint256 epoch => bool)) public hasVoted;
```

#### hasDistributed <a href="#hasdistributed" id="hasdistributed"></a>

This function checks if incentives have been distributed for a specific reward contract in an epoch.

```solidity
mapping(IMaverickV2Reward reward => mapping(uint256 epoch => bool)) public hasDistributed;
```

#### hasVetoed <a href="#hasvetoed" id="hasvetoed"></a>

This function checks if a specific matcher has cast a veto on a reward contract for an epoch.

```solidity
mapping(address matcher => mapping(IMaverickV2Reward reward => mapping(uint256 epoch => bool))) public hasVetoed;
```

#### checkpoints <a href="#checkpoints" id="checkpoints"></a>

```solidity
mapping(uint256 epoch => CheckpointData) private checkpoints;
```

### Functions <a href="#functions" id="functions"></a>

#### constructor <a href="#constructor" id="constructor"></a>

```solidity
constructor();
```

#### checkEpoch <a href="#checkepoch" id="checkepoch"></a>

Epoch Checkers and Helpers

```solidity
modifier checkEpoch(uint256 epoch);
```

#### checkpointRewardData <a href="#checkpointrewarddata" id="checkpointrewarddata"></a>

This function retrieves checkpoint data for a specific reward contract within an epoch.

```solidity
function checkpointRewardData(uint256 epoch, IMaverickV2Reward rewardContract)
    public
    view
    checkEpoch(epoch)
    returns (uint128 votesByReward, uint128 externalIncentivesByReward);
```

**Parameters**

| Name             | Type                | Description                                      |
| ---------------- | ------------------- | ------------------------------------------------ |
| `epoch`          | `uint256`           | The epoch for which to retrieve checkpoint data. |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract.              |

**Returns**

| Name                         | Type      | Description                                                                         |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------- |
| `votesByReward`              | `uint128` | The total number of votes cast for the reward contract in the epoch.                |
| `externalIncentivesByReward` | `uint128` | The total amount of external incentives added for the reward contract in the epoch. |

#### checkpointData <a href="#checkpointdata" id="checkpointdata"></a>

This function retrieves checkpoint data for a specific epoch.

```solidity
function checkpointData(uint256 epoch)
    public
    view
    checkEpoch(epoch)
    returns (uint128 matchBudget, uint128 voteBudget, uint128 totalVote, uint128 totalExternalIncentivesAdded);
```

**Parameters**

| Name    | Type      | Description                                      |
| ------- | --------- | ------------------------------------------------ |
| `epoch` | `uint256` | The epoch for which to retrieve checkpoint data. |

**Returns**

| Name                           | Type      | Description                                                  |
| ------------------------------ | --------- | ------------------------------------------------------------ |
| `matchBudget`                  | `uint128` | The amount of match tokens budgeted for the epoch.           |
| `voteBudget`                   | `uint128` | The amount of vote tokens budgeted for the epoch.            |
| `totalVote`                    | `uint128` | The total number of votes cast in the epoch.                 |
| `totalExternalIncentivesAdded` | `uint128` | The total amount of external incentives added for the epoch. |

#### isEpoch <a href="#isepoch" id="isepoch"></a>

This function checks if a given epoch is valid.

```solidity
function isEpoch(uint256 epoch) public pure returns (bool _isEpoch);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name       | Type   | Description                                                |
| ---------- | ------ | ---------------------------------------------------------- |
| `_isEpoch` | `bool` | True if the epoch input is a valid epoch, False otherwise. |

#### epochIsOver <a href="#epochisover" id="epochisover"></a>

This function checks if a specific epoch has ended.

```solidity
function epochIsOver(uint256 epoch) public view returns (bool isOver);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name     | Type   | Description                                   |
| -------- | ------ | --------------------------------------------- |
| `isOver` | `bool` | True if the epoch has ended, False otherwise. |

#### vetoingIsActive <a href="#vetoingisactive" id="vetoingisactive"></a>

This function checks if the vetoing period is active for a specific epoch.

```solidity
function vetoingIsActive(uint256 epoch) public view returns (bool isActive);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name       | Type   | Description                                            |
| ---------- | ------ | ------------------------------------------------------ |
| `isActive` | `bool` | True if the vetoing period is active, False otherwise. |

#### votingIsActive <a href="#votingisactive" id="votingisactive"></a>

This function checks if the voting period is active for a specific epoch.

```solidity
function votingIsActive(uint256 epoch) public view returns (bool isActive);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name       | Type   | Description                                           |
| ---------- | ------ | ----------------------------------------------------- |
| `isActive` | `bool` | True if the voting period is active, False otherwise. |

#### vetoingIsOver <a href="#vetoingisover" id="vetoingisover"></a>

This function checks if the vetoing period is over for a specific epoch.

```solidity
function vetoingIsOver(uint256 epoch) public view returns (bool isOver);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name     | Type   | Description                                                                |
| -------- | ------ | -------------------------------------------------------------------------- |
| `isOver` | `bool` | True if the vetoing period has ended for the given epoch, False otherwise. |

#### votingStart <a href="#votingstart" id="votingstart"></a>

Returns the timestamp when voting starts. This is also the voting snapshot timestamp where the voting power for users is determined for that epoch.

```solidity
function votingStart(uint256 epoch) public pure returns (uint256 start);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

#### epochEnd <a href="#epochend" id="epochend"></a>

This function calculates the end timestamp for a specific epoch.

```solidity
function epochEnd(uint256 epoch) public pure returns (uint256 end);
```

**Parameters**

| Name    | Type      | Description                                         |
| ------- | --------- | --------------------------------------------------- |
| `epoch` | `uint256` | The epoch for which to calculate the end timestamp. |

**Returns**

| Name  | Type      | Description                     |
| ----- | --------- | ------------------------------- |
| `end` | `uint256` | The end timestamp of the epoch. |

#### vetoingEnd <a href="#vetoingend" id="vetoingend"></a>

This function calculates the end timestamp for the vetoing period of a specific epoch.

```solidity
function vetoingEnd(uint256 epoch) public pure returns (uint256 end);
```

**Parameters**

| Name    | Type      | Description                                                        |
| ------- | --------- | ------------------------------------------------------------------ |
| `epoch` | `uint256` | The epoch for which to calculate the vetoing period end timestamp. |

**Returns**

| Name  | Type      | Description                                            |
| ----- | --------- | ------------------------------------------------------ |
| `end` | `uint256` | The end timestamp of the vetoing period for the epoch. |

#### currentEpoch <a href="#currentepoch" id="currentepoch"></a>

This function retrieves the current epoch number.

```solidity
function currentEpoch() public view returns (uint256 epoch);
```

**Returns**

| Name    | Type      | Description               |
| ------- | --------- | ------------------------- |
| `epoch` | `uint256` | The current epoch number. |

#### lastEpoch <a href="#lastepoch" id="lastepoch"></a>

This function retrieves the number of the most recently completed epoch.

```solidity
function lastEpoch() public view returns (uint256 epoch);
```

**Returns**

| Name    | Type      | Description                   |
| ------- | --------- | ----------------------------- |
| `epoch` | `uint256` | The number of the last epoch. |

#### rewardHasVe <a href="#rewardhasve" id="rewardhasve"></a>

This function checks if a specific reward contract has a veToken staking option.

```solidity
function rewardHasVe(IMaverickV2Reward rewardContract) public view returns (bool);
```

**Parameters**

| Name             | Type                | Description                         |
| ---------------- | ------------------- | ----------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract. |

**Returns**

| Name     | Type   | Description                                                                      |
| -------- | ------ | -------------------------------------------------------------------------------- |
| `<none>` | `bool` | hasVe True if the reward contract has a veToken staking option, False otherwise. |

#### \_addBudget <a href="#addbudget" id="addbudget"></a>

User Actions

```solidity
function _addBudget(uint128 matchBudget, uint128 voteBudget, uint256 epoch) private;
```

#### addMatchingBudget <a href="#addmatchingbudget" id="addmatchingbudget"></a>

This function allows adding a new budget to the matcher contract.

```solidity
function addMatchingBudget(uint128 matchBudget, uint128 voteBudget, uint256 epoch)
    public
    checkEpoch(epoch)
    nonReentrant;
```

**Parameters**

| Name          | Type      | Description                              |
| ------------- | --------- | ---------------------------------------- |
| `matchBudget` | `uint128` | The amount of match tokens to add.       |
| `voteBudget`  | `uint128` | The amount of vote tokens to add.        |
| `epoch`       | `uint256` | The epoch for which the budget is added. |

#### addIncentives <a href="#addincentives" id="addincentives"></a>

This function allows adding a new incentive to the system.

```solidity
function addIncentives(IMaverickV2Reward rewardContract, uint256 amount, uint256 _duration)
    public
    nonReentrant
    returns (uint256 duration);
```

**Parameters**

| Name             | Type                | Description                                                       |
| ---------------- | ------------------- | ----------------------------------------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract for the incentive.             |
| `amount`         | `uint256`           | The total amount of the incentive.                                |
| `_duration`      | `uint256`           | The duration (in epochs) for which this incentive will be active. |

**Returns**

| Name       | Type      | Description                                                  |
| ---------- | --------- | ------------------------------------------------------------ |
| `duration` | `uint256` | The duration (in epochs) for which this incentive was added. |

#### \_inVetoPeriodCheck <a href="#invetoperiodcheck" id="invetoperiodcheck"></a>

```solidity
function _inVetoPeriodCheck(uint256 epoch) internal view;
```

#### \_inVotePeriodCheck <a href="#invoteperiodcheck" id="invoteperiodcheck"></a>

```solidity
function _inVotePeriodCheck(uint256 epoch) internal view;
```

#### vote <a href="#vote" id="vote"></a>

This function allows a user to cast a vote for specific reward contracts.

```solidity
function vote(IMaverickV2Reward[] memory voteTargets, uint256[] memory weights) external nonReentrant;
```

**Parameters**

| Name          | Type                  | Description                                                 |
| ------------- | --------------------- | ----------------------------------------------------------- |
| `voteTargets` | `IMaverickV2Reward[]` | An array of addresses for the reward contracts to vote for. |
| `weights`     | `uint256[]`           | An array of weights for each vote target.                   |

#### veto <a href="#veto" id="veto"></a>

This function allows casting a veto on a specific reward contract for an epoch.

```solidity
function veto(IMaverickV2Reward rewardContract) public returns (uint128 vetoPower);
```

**Parameters**

| Name             | Type                | Description                                 |
| ---------------- | ------------------- | ------------------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract to veto. |

**Returns**

| Name        | Type      | Description                                                                   |
| ----------- | --------- | ----------------------------------------------------------------------------- |
| `vetoPower` | `uint128` | The amount of veto power used (based on the user's epoch match contribution). |

#### \_checkVetoPeriodEnded <a href="#checkvetoperiodended" id="checkvetoperiodended"></a>

```solidity
function _checkVetoPeriodEnded(uint256 epoch) internal view;
```

#### distribute <a href="#distribute" id="distribute"></a>

This function allows distributing incentives for a specific reward contract in a particular epoch.

```solidity
function distribute(IMaverickV2Reward rewardContract, uint256 epoch)
    public
    checkEpoch(epoch)
    nonReentrant
    returns (uint256 matchAmount);
```

**Parameters**

| Name             | Type                | Description                                                      |
| ---------------- | ------------------- | ---------------------------------------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract to distribute incentives for. |
| `epoch`          | `uint256`           | The epoch for which to distribute incentives.                    |

**Returns**

| Name          | Type      | Description                                |
| ------------- | --------- | ------------------------------------------ |
| `matchAmount` | `uint256` | The amount of matching tokens distributed. |

#### rolloverExcessBudget <a href="#rolloverexcessbudget" id="rolloverexcessbudget"></a>

This function allows rolling over excess budget from a previous epoch to a new epoch.

Excess vote match budget amounts that have not been distributed will not rollover and will become permanently locked. To avoid this, a matcher should call distribute on all rewards contracts before calling rollover.

```solidity
function rolloverExcessBudget(uint256 matchedEpoch, uint256 newEpoch)
    public
    checkEpoch(matchedEpoch)
    checkEpoch(newEpoch)
    returns (uint256 matchRolloverAmount, uint256 voteRolloverAmount);
```

**Parameters**

| Name           | Type      | Description                                   |
| -------------- | --------- | --------------------------------------------- |
| `matchedEpoch` | `uint256` | The epoch from which to roll over the budget. |
| `newEpoch`     | `uint256` | The epoch to which to roll over the budget.   |

**Returns**

| Name                  | Type      | Description                             |
| --------------------- | --------- | --------------------------------------- |
| `matchRolloverAmount` | `uint256` | The amount of match tokens rolled over. |
| `voteRolloverAmount`  | `uint256` | The amount of vote tokens rolled over.  |

### Structs <a href="#structs" id="structs"></a>

#### MatchPair <a href="#matchpair" id="matchpair"></a>

```solidity
struct MatchPair {
    uint128 matchBudget;
    uint128 voteBudget;
}
```

#### CheckpointData <a href="#checkpointdata-1" id="checkpointdata-1"></a>

```solidity
struct CheckpointData {
    uint128 matchBudget;
    uint128 voteBudget;
    uint128 totalVote;
    uint128 totalExternalIncentivesAdded;
    uint128 voteRollover;
    mapping(IMaverickV2Reward => uint128) votesByReward;
    mapping(IMaverickV2Reward => uint128) externalIncentivesByReward;
    mapping(address => MatchPair) matcherAmounts;
}
```




---

[Next Page](/llms-full.txt/1)

