# Liquidity routing

**Work in progress**

This page is currently being updated - thank you for your understanding.

Maker contracts can be set to utilize a [router](/dev/quick-links/glossary.md#router) in order to manage [outbound](/dev/quick-links/glossary.md#outbound) and [inbound](/dev/quick-links/glossary.md#inbound) tokens reserves of [offer owners](/dev/quick-links/glossary.md#offer-owner). Routers' interface are constrained by the `AbstractRouter` contract and use [hooks](/dev/quick-links/glossary.md#hook) to customize the public functions described below.

**Modifiers**

Function modifier `onlyMakers` requires that only an approved maker contract can call this functions. Modifier `onlyAdmin` requires function caller to be the admin of the router. Modifier `makerOrAdmin` is a disjunction of both the above requirements.

### Useful routers[​](https://old.docs.mangrove.exchange/developers/strat-lib/technical-references/router#useful-routers) <a href="#useful-routers" id="useful-routers"></a>

#### `SimpleRouter`[​](https://old.docs.mangrove.exchange/developers/strat-lib/technical-references/router#simplerouter) <a href="#simplerouter" id="simplerouter"></a>

The [`SimpleRouter` contract](/dev/strat-lib/technical-references/api-preferences/strats/src/strategies/routeurs/simplerouter.md) provides a (simple) router instance. We illustrate the usage of the main router functions through it.

#### `SmartRouter`[​](https://old.docs.mangrove.exchange/developers/strat-lib/technical-references/router#smartrouter) <a href="#smartrouter" id="smartrouter"></a>

The [`SmartRouter` contract](https://github.com/mangrovedao/mangrove-strats/blob/feat/smartRouter/src/strategies/routers/SmartRouter.sol) is an implementation, and must not be called directly. It delegates pull and push logic implementation to arbitrary contracts that implement the [`AbstractRoutingLogic` interface](https://github.com/mangrovedao/mangrove-strats/blob/feat/smartRouter/src/strategies/routing_logic/abstract/AbstractRoutingLogic.sol). It implements `SimpleRouter` as its default route.

When requested to do so, the [ProxyFactory](https://github.com/mangrovedao/mangrove-strats/blob/develop/src/strategies/routers/RouterProxyFactory.sol) deploys a RouterProxy. It is created specifically for the caller, and will forward all the push/pull calls to the SmartRouter, which forward those to the corresponding routing logic (ex: AaveLogic).

Thefore, the push/pull functions are delegated from the *Proxy > SmartRouter > RoutingLogic*. The Proxy contract basically works like an intelligent router.

<figure><img src="https://old.docs.mangrove.exchange/img/assets/routers_workflow.png" alt=""><figcaption></figcaption></figure>

### Liquidity flows[​](https://old.docs.mangrove.exchange/developers/strat-lib/technical-references/router#liquidity-flows) <a href="#liquidity-flows" id="liquidity-flows"></a>

Routers receive requests from approved [maker contracts](/dev/quick-links/glossary.md#maker-contract) (see [gatekeeping](#gatekeeping)). Request can be either to manage inbound (offer taker's payment) or outbound cash flow.

#### Push request[​](https://old.docs.mangrove.exchange/developers/strat-lib/technical-references/router#push-request) <a href="#push-request" id="push-request"></a>

src/strategies/routers/abstract/AbstractRouter.sol

```
///@notice pushes assets from calling's maker contract to a reserve
///@param token is the asset the maker is pushing
///@param reserveId determines the location of the reserve (router implementation dependent).
///@param amount is the amount of asset that should be transferred from the calling maker contract
///@return pushed fraction of `amount` that was successfully pushed to reserve.
function push(IERC20 token, address reserveId, uint amount) external onlyBound returns (uint pushed) {
```

[See entire file on GitHub](https://github.com/mangrovedao/mangrove-strats/blob/a265abeb96a053e386d346c7c9e431878382749c/src/strategies/routers/abstract/AbstractRouter.sol#L64-L69)

* **Input**:
  * `token` is the asset the maker contract wishes to push
  * `reserveId` is the address of the offer owner whose funds are being pushed
  * `amount` is the amount of asset that should be transferred from the calling maker contract
* **Output**: fraction of `amount` that was successfully `pushed` to offer owner's `reserveId`.
* **Usage**: transfer funds from the maker contracts to an offer owner's reserve. For instance if the reserve is an account on a lender, the router will have a custom `push` that will take care of calling the proper deposit function.
* **SimpleRouter behavior**: transfer funds from `msg.sender` to `reserveId`. Returns 0 if transfer failed, returns `amount` otherwise.

#### Pull request[​](https://old.docs.mangrove.exchange/developers/strat-lib/technical-references/router#pull-request) <a href="#pull-request" id="pull-request"></a>

src/strategies/routers/abstract/AbstractRouter.sol

```
///@notice pulls liquidity from the reserve and sends it to the calling maker contract.
///@param token is the ERC20 managing the pulled asset
///@param reserveId identifies the fund owner (router implementation dependent).
///@param amount of `token` the maker contract wishes to pull from its reserve
///@param strict when the calling maker contract accepts to receive more funds from reserve than required (this may happen for gas optimization)
///@return pulled the amount that was successfully pulled.
function pull(IERC20 token, address reserveId, uint amount, bool strict) external onlyBound returns (uint pulled) {
```

[See entire file on GitHub](https://github.com/mangrovedao/mangrove-strats/blob/a265abeb96a053e386d346c7c9e431878382749c/src/strategies/routers/abstract/AbstractRouter.sol#L43-L49)

* **Input**:
  * `token` is the asset the maker contract wishes to pull
  * `reserveId` is the address of the offer owner where the funds need to be pulled from
  * `amount` is the amount of asset that should be transferred from `reserveId` to the calling maker contract
  * `strict` is used when the calling maker contract accepts to receive more funds from reserve than required (this may happen for gas optimization)
* **Output**: fraction of `amount` that was successfully `pulled` to `msg.sender`.
* **Usage**: transfer funds from an offer owner's reserve to the calling maker contracts. For instance if the reserve is an account on a lender, the router will have a custom `pull` that will take care of calling the proper redeem function.
* **SimpleRouter behavior**: transfer funds from `reserveId` to `msg.sender`. Returns 0 if transfer failed, returns `amount` otherwise.

### Gatekeeping[​](https://old.docs.mangrove.exchange/developers/strat-lib/technical-references/router#gatekeeping) <a href="#gatekeeping" id="gatekeeping"></a>

#### Binding a router to a maker contract[​](https://old.docs.mangrove.exchange/developers/strat-lib/technical-references/router#binding-a-router-to-a-maker-contract) <a href="#binding-a-router-to-a-maker-contract" id="binding-a-router-to-a-maker-contract"></a>

src/strategies/routers/abstract/AbstractRouter.sol

```
///@notice pulls liquidity from the reserve and sends it to the calling maker contract.
///@param token is the ERC20 managing the pulled asset
///@param reserveId identifies the fund owner (router implementation dependent).
///@param amount of `token` the maker contract wishes to pull from its reserve
///@param strict when the calling maker contract accepts to receive more funds from reserve than required (this may happen for gas optimization)
///@return pulled the amount that was successfully pulled.
function pull(IERC20 token, address reserveId, uint amount, bool strict) external onlyBound returns (uint pulled) {
```

[See entire file on GitHub](https://github.com/mangrovedao/mangrove-strats/blob/a265abeb96a053e386d346c7c9e431878382749c/src/strategies/routers/abstract/AbstractRouter.sol#L43-L49)

Function approves `makerContract` as a user of the router. The [`unbind`](https://github.com/mangrovedao/mangrove-strats/blob/a265abeb96a053e386d346c7c9e431878382749c/src/strategies/routers/abstract/AbstractRouter.sol#L110-L113) function can be called to revoke the approval.

#### Router activation[​](https://old.docs.mangrove.exchange/developers/strat-lib/technical-references/router#router-activation) <a href="#router-activation" id="router-activation"></a>

src/strategies/routers/abstract/AbstractRouter.sol

```
///@notice performs necessary approval to activate router function on a particular asset
///@param token the asset one wishes to use the router for
function activate(IERC20 token) external boundOrAdmin {
```

[See entire file on GitHub](https://github.com/mangrovedao/mangrove-strats/blob/a265abeb96a053e386d346c7c9e431878382749c/src/strategies/routers/abstract/AbstractRouter.sol#L138-L140)

* **Usage**: performs all router centric approvals that are necessary to route `token` liquidity. For instance a router using a lender might need to approve the lender for transferring `token` in deposit calls.
* **SimpleRouter behavior**: SimpleRouter does not need to approve any contract, and `activate` is a no-op in that context.

#### Router checklist[​](https://old.docs.mangrove.exchange/developers/strat-lib/technical-references/router#router-checklist) <a href="#router-checklist" id="router-checklist"></a>

src/strategies/routers/abstract/AbstractRouter.sol

```
///@notice allows a makerContract to verify it is ready to use `this` router for a particular reserve
///@dev `checkList` returns normally if all needed approval are strictly positive. It reverts otherwise with a reason.
///@param token is the asset (and possibly its overlyings) whose approval must be checked
///@param reserveId of the tokens that are being pulled
function checkList(IERC20 token, address reserveId) external view {
```

[See entire file on GitHub](https://github.com/mangrovedao/mangrove-strats/blob/a265abeb96a053e386d346c7c9e431878382749c/src/strategies/routers/abstract/AbstractRouter.sol#L121-L125)

* **Usage**: verifies that the router has performed and received all the necessary approvals to route `token` liquidity for offer owner's `reserveId`. The function throws with a reason when the first missing approval is detected.
* **SimpleRouter behavior**: it verifies that `reserveId` has approved the router for `token` transfer. Does not throw if offer owner's `reserveId` is the router itself.

**Plug and play routing**

Since routers are autonomous smart contracts, it is possible to modify an offer logic without redeploying the corresponding maker contracts. The `setRouter` function of all library based maker contracts can be used to set a new router. By setting a new router for the maker contract, you are indirectly modifying the offer logic of the contract. However the gas requirement of the offer logic is impacted by the router's design. To cope with this, routers provide the `routerGaseq()` function that returns the amount of gas that is necessary to cover a call to `pull` and `push`.

Note that maker contracts' view `offerGasreq` returns the sum of the offer logic's raw [`gasreq`](/dev/quick-links/glossary.md#gasreq) (without taking router into account) and the router specific `gasreq`


---

# Agent Instructions: Querying This Documentation

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

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

```
GET https://docs.mangrove.exchange/dev/strat-lib/technical-references/liquidity-routing.md?ask=<question>
```

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

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