> ## Documentation Index
> Fetch the complete documentation index at: https://docs.biconomy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Provider contract

> The contract that holds your inventory. Deploy BasicMMProvider, or implement IMMProvider on a contract you already have.

Your inventory lives in a contract you own that implements `IMMProvider`. The executor calls it to settle each fill.

```solidity theme={null}
interface IMMProvider {
    function signer() external view returns (address);
    function previewSwap(address tokenIn, address tokenOut, uint256 amountIn, uint256 anchorPrice)
        external view returns (uint256 amountOut);
    function executeSwap(address tokenIn, address tokenOut, uint256 amountIn, uint256 anchorPrice, uint256 amountOut, address receiver)
        external returns (uint256 delivered);
}
```

| Function           | Called by                                 | Must                                                                                                                 |
| ------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `signer()`         | executor, on every fill                   | return the address that signs your ladders (EOA or EIP-1271 contract)                                                |
| `previewSwap(...)` | Biconomy, offchain, before routing to you | return what `executeSwap` would deliver for the same inputs, or `0` to decline                                       |
| `executeSwap(...)` | executor only                             | pull `amountIn` of `tokenIn` from the executor, send `amountOut` of `tokenOut` to `receiver`, return the amount sent |

## executeSwap parameters

| Parameter           | Value                                                                                                                   |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `tokenIn`           | token the taker pays                                                                                                    |
| `tokenOut`          | token you deliver                                                                                                       |
| `amountIn`          | amount the executor has approved you to pull with `transferFrom`                                                        |
| `anchorPrice`       | average price of this fill, `amountOut * 1e18 / amountIn`. Optional input for contracts that price from their own state |
| `amountOut`         | amount your signed ladder pays for `amountIn`, computed by the executor from your stored ladder                         |
| `receiver`          | address that receives `tokenOut`                                                                                        |
| returns `delivered` | amount of `tokenOut` sent to `receiver`                                                                                 |

The executor computes `amountOut` only from a ladder your key signed, within its size, expiry and protections. Delivering less than `amountOut` makes the trade revert on the taker's `minAmountOut`.

## Deploy BasicMMProvider

[`BasicMMProvider.sol`](https://github.com/bcnmy/propamm-protocol-docs/blob/main/docs/examples/BasicMMProvider.sol) is the reference implementation. It accepts fills from the executor only and pays `amountOut`.

| Constructor argument | Value                                                               |
| -------------------- | ------------------------------------------------------------------- |
| `signer`             | address that signs your ladders                                     |
| `executor`           | the executor address, see [Addresses](/propamm/reference/addresses) |
| `owner`              | admin address; use a multisig in production                         |

| Dependency                                                                                                  | Path                                         |
| ----------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| [`IMMProvider.sol`](https://github.com/bcnmy/propamm-protocol-docs/blob/main/docs/examples/IMMProvider.sol) | `src/interfaces/IMMProvider.sol`             |
| `BasicMMProvider.sol`                                                                                       | `src/periphery/examples/BasicMMProvider.sol` |
| [solady](https://github.com/Vectorized/solady)                                                              | `forge install vectorized/solady`            |

| Owner function                 | Effect                                                                            |
| ------------------------------ | --------------------------------------------------------------------------------- |
| `setSigner(address)`           | Changes the signing key. Ladders signed by the old key stop filling.              |
| `setApprovedExecutor(address)` | Changes which contract may call `executeSwap`. Any other address stops all fills. |
| `withdraw(token, amount, to)`  | Moves inventory out.                                                              |

## Implement IMMProvider on an existing contract

If your inventory already sits in a contract, add the three functions to it.

| Requirement      | Detail                                                                  |
| ---------------- | ----------------------------------------------------------------------- |
| Caller check     | `executeSwap` reverts unless `msg.sender` is the executor               |
| Pull input       | `transferFrom(executor, address(this), amountIn)` on `tokenIn`          |
| Pay output       | transfer `amountOut` of `tokenOut` to `receiver` and return it          |
| Preview          | `previewSwap` matches `executeSwap` for the same inputs, or returns `0` |
| Optional ceiling | revert when `amountOut` exceeds a per-fill limit you set                |
