---
# System prepended metadata

title: The AMM

---

# The AMM

## System Overview

![](https://i.imgur.com/0ieYPGn.png)

## Sequence Diagrams

![](https://i.imgur.com/YIska9k.png)

![](https://i.imgur.com/WkhOQ27.jpg)

## Swaps 

| Entypoint| Internal f() call| User defined |
| -------- | -------- | -------- |
| (default) Swap     | calcOutGivenIn()     | tokenOutMin     |
|  Flash Swap | calcInGivenOut()     | tokenInMax    |
|  Flash Loan |   calcFlashLoanFee()   | tokenInMax    |

## Pool Hooks

* onSwapInitiated: eg. freeze cTez price
* onSwapFinalized: eg. update on-chain price aggregator
* onJoinPoolFinalized
* onExitPoolFinalized
* onFlashSwapInitiated
* onFlashSwapFinalized
* ...


## Storage for a BasePool

```
type token = (tokenId, tokenAddress);
// FA1.2 type token = tokenAddress;

type asset = {
    denorm: nat,
    balance: nat
}

type storage = {
    assets: Big_map(token, asset),
    totalSupply: nat,
    controller: address, // consider router
    poolHooksContract: address
}
```

## Parameters for liquidity bootstrapping (custom pools)

#### Permission settings

```
const permissions = {
        canPauseSwapping: false,
        canChangeSwapFee: false,
        canChangeWeights: true,
        canAddRemoveTokens: false,
        canWhitelistLPs: false,
        canChangeCap: false,
};
```

#### Storage for custom pool


```
type config = {
    minWeight: nat,
    maxWeight: nat,
    minBalance: nat,
    maxBalance: nat,
}

type token = (tokenId, tokenAddress);
// FA1.2 type token = tokenAddress;

type asset = {
    startBlock: nat,
    endBlock: nat,
    startWeight: nat,
    endWeight: nat,
    denorm: nat,
    balance: nat
}

type storage = {
    config: config,
    permissions: permissions,
    assets: Big_map(token, asset),
    totalSupply: nat,
    controller: address, // consider router
    poolHooksContract: address
}
```

#### Setting the weights

Essential to use the google sheet and estimate demand. The price needs to "drop" continously, otherwise a big purchase can push out the other participants, because the price is not dropping for the rest of the sale (eg. 1/3 of the sale time goes to waste).

> Q: What is the estimated demand?

Denormalized weights max is `50`, but it is recommended to go to lower numbers, such as `40`. Eg. 36/(36+4) MVK and 4/(36+4) USDC. That is 90%/10%. Being close to 50 pushes it to edge cases where weights might fail.

#### Swap Fee

This is there because despite being a system against front-running, people still try. Common practice is to set a fee as high as 2% (max is 10%), and drop it throughout the sale. This deters arbs (arbitraitors).


#### Methods to be called

After passing all config options to the smart contract, the sale starts by calling `updateWeightsGradually(endWeights, startBlock, endBlock)`. 

`pokeWeights()` to udpate weights.

Calling `updateWeightsGradually()` after the sale has started, requires the controller to add or remove tokens (zero-sum).

