> For the complete documentation index, see [llms.txt](https://docs.supernova.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.supernova.xyz/technical-amm-documentation.md).

# Technical AMM Documentation

### Project Context

### Overview

Supernova is a ve(3,3) DEX built on Ethereum, forking from Blackhole and incorporating multiple AMM types:

* Basic Pools: Uniswap V2-style constant product pools
* Concentrated Pools: Algebra DEX-based range AMM

Supernova uses a vote-escrow model with $NOVA and $veNOVA to align liquidity incentives and long-term governance, with auto-voting capabilities.

***

### Pool Types

#### Basic Pools

**Basic Volatile Pools**

* AMM Model: Constant product formula x \* y = k
* Use Case: Token pairs with high volatility and uncorrelated prices

**Basic Stable Pools**

* AMM Model: Stable-swap invariant (inspired by Curve)  x³y + y³x ≥ k
* Formula: Custom implementation that flattens the price curve around 1:1 to reduce slippage on similarly priced tokens
* Use Case: Pairs like USDC/USDT, stablecoins, and synthetics

**Common Features:**

* Fee Structure: Flat LP fee, configurable by pool (e.g., 0.5% default)
* Routing Logic: Integrated with Supernova router to handle swaps across both pool types

**Key Highlights:**

* Volatile pools for broader DeFi assets
* Stable pools for low-slippage stablecoin swaps
* Low gas cost and composable architecture
* TWAP oracles and on-chain price feeds

***

#### Concentrated Pools (Algebra Integral’s modular architecture)

* **AMM Model**: Customizable tick-based range liquidity AMM
* **Fee Structure**: Static and Dynamic fee model

Key Features:

* Efficient capital use with narrow-range liquidity

***

### AMM Architecture&#x20;

#### Router Layer

* Unified router handles route discovery and execution
* Multi-hop support across Algebra and Uniswap V2 pools
* Implements price impact protection, slippage checks, and gas optimizations

#### Liquidity Positions

Basic Pools

* Staked: Earn protocol emissions, and fees contribute to the pool's gauge.
* Unstaked: Earn the generated fees.

Concentrated Pools

* Staked: Receive protocol emissions for positions within the active liquidity range. Fees contribute to the pool's gauge.
* Unstaked: Receive neither fees nor emissions. Fees contribute to the pool’s gauge.

***

### ve(3,3) Architecture&#x20;

#### Voting & Incentives

* Uses ve(3,3) mechanism (vote-escrowed $NOVA)
* Weekly epochs where veNFT holders vote on pools to receive emissions
* Epoch flips on Thursday at 00:00 UTC every week
* First Epoch Flip - TBD

#### Emissions

* Emissions to pools are based on vote weights

***

### Technical Details

#### Derive Pool addresses&#x20;

**Basic Pool:**

{% code overflow="wrap" %}

```
bytes32 salt = keccak256(abi.encodePacked(token0, token1, stable)); // notice salt includes stable as well, 3 parameters
pair = address(new Pair{salt: salt}(factory, token0, token1, stable));
```

{% endcode %}

**Concentrated Pool:**&#x20;

{% code overflow="wrap" %}

```
function computePoolAddress(address token0, address token1) public view override returns (address pool) {
    pool = address(uint160(uint256(keccak256(abi.encodePacked(hex'ff', poolDeployer, keccak256(abi.encode(token0, token1)), POOL_INIT_CODE_HASH)))));
  }
 bytes32 public constant POOL_INIT_CODE_HASH = 0xeaa3eea3233916c82fe1281a51bd9cde844b7c4673c0714ca0028a57f5634752;
```

{% endcode %}

<br>

#### Custom Pool Deployer Contracts<br>

<table data-header-hidden><thead><tr><th width="310.0625"></th><th></th></tr></thead><tbody><tr><td>CustomPoolDeployer tick1</td><td>0xc815b4e0abae3155f8f4f9e404f17c9fa6928eb8</td></tr><tr><td>CustomPoolDeployer tick 10</td><td>0x1c798614ef4c6a8f8a1aab25785714933e59e963</td></tr><tr><td>CustomPoolDeployer tick 50</td><td>0x44acd9579650d300ebbeac2e483b97fdcacdddc0</td></tr><tr><td>CustomPoolDeployer tick 100</td><td>0xd7b7cc843331cbdc857d5e7615d320b8b4ac090e</td></tr><tr><td>CustomPoolDeployer tick 200</td><td>0x42f5ecd6497d42e093de05bec73e33ceb82493da</td></tr></tbody></table>

#### Sampling

**Basic Pool**

* There is a function in PairContract called getAmountOut
* It takes Amount in and token in and returns the amount for the second token<br>

**Concentrated Pool**

* Contract: QuoterV2
* Function: quoteExactInputSingle
* Takes below input:

{% code overflow="wrap" %}

```
address tokenIn;
address tokenOut;
address deployer;
uint256 amountIn;
uint160 limitSqrtPrice;
```

{% endcode %}

* deployer will be different for different tick\_spacing(mentioned above)
* limitSqrtPrice: The price limit of the pool that cannot be exceeded by the swap

#### Settling&#x20;

**Non native tokens**

* Contract: RouterV2
* Function: swapExactTokensForTokens
* Params:

```
uint amountIn,
uint amountOutMin,
IRouter.route[] calldata routes,
address to,
uint deadline
```

* Router:

```
address pair;
address from;
address to;
bool stable;
bool concentrated;
address receiver;
```

**Native Tokens**

* Contract: RouterV2
* Function: swapExactETHForTokens
* Params:

{% code overflow="wrap" %}

```
uint amountOutMin, IRouter.route[] calldata routes, address to, uint deadline

```

{% endcode %}

* Router

```
address pair;
address from;
address to;
bool stable;
bool concentrated;
address receiver;

```

**FOT Tokens**

* Contract: RouterV2
* Function: swapExactTokensForTokensSupportingFeeOnTransferTokens
* Params:

```
uint amountIn,
uint amountOutMin,
IRouter.route[] calldata routes,
address to,
uint deadline
```

* Router

```
address pair;
address from;
address to;
bool stable;
bool concentrated;
address receiver;


```

* Gauge addresses for a pool

The GaugeManager contract includes a function called gauges that returns the corresponding gauge address when provided with a pool address.

GaugeManager Address: 0x19a410046afc4203aece5fbfc7a6ac1a4f517ae2

<br>

* Stake NFT for emissions

You can deposit the NFT by calling the deposit function with the tokenid on the gauge contract associated with the respective pool.

### Mainnet Contract Addresses

<table data-header-hidden><thead><tr><th width="301.53125"></th><th></th></tr></thead><tbody><tr><td>Contract Name</td><td>Address</td></tr><tr><td>superNova</td><td>0x00da8466b296e382e5da2bf20962d0cb87200c78</td></tr><tr><td>PermissionsRegistry</td><td>0x344eec31c725187cd026db73ed8805e72967c28d</td></tr><tr><td>PairGenerator</td><td>0x42a7a5baafb1818da3a39ce1b97a58799d69bbb8</td></tr><tr><td>PairFactory</td><td>0x5aef44edfc5a7edd30826c724ea12d7be15bdc30</td></tr><tr><td>VotingBalanceLogic</td><td>0xed686a5b0bf0df5c97f8eabd1b776ae399319847</td></tr><tr><td>VeArtProxyUpgradeable</td><td>0x87e3982313661a08cb1f0bb9de472eb407397551</td></tr><tr><td>GaugeFactory</td><td>0x66647a19452e98e98a9f479883f241e33016adb0</td></tr><tr><td>GaugeFactoryCL</td><td>0x8d38206e38ec86b14530186aa36cc3b1ed8cd674</td></tr><tr><td>VoterFactoryLib</td><td>0xbd08f4d76ca903cc922ec14fcfef90d4e1a95278</td></tr><tr><td>GaugeManager</td><td>0x19a410046afc4203aece5fbfc7a6ac1a4f517ae2</td></tr><tr><td>VoterV3</td><td>0x1c7bf2532dfa34eeea02c3759e0ca8d87b1d8171</td></tr><tr><td>BribeFactoryV3</td><td>0xeb37f11c573ab01358d5fefb10f5de2b4237344c</td></tr><tr><td>AlgebraPoolAPIStorage</td><td>0x3d219d5089331f6bf99cb20b9b199ab3b429337a</td></tr><tr><td>AlgebraPoolAPI</td><td>0x0ee8553a64edf161b3daa6907a4ff45b0a12ea59</td></tr><tr><td>RouterHelper</td><td>0xd8377aea61c4c4d43bf0588956f4e861720803c6</td></tr><tr><td>RouterV2</td><td>0xbFAe8E87053309fDe07ab3cA5f4B5345f8e3058f</td></tr><tr><td>BlackholePairAPIV2</td><td>0x2B9FC4714589544Aa1e0a75596c611a1364963Dc</td></tr><tr><td>RewardsDistributor</td><td>0xb3410a30af5033af822b8ea5ad3bd0a19490ea97</td></tr><tr><td>VeNFTAPI</td><td>0x85dc70913e49e5ebd888ada03034e3be109e5881</td></tr><tr><td>SuperNovaClaims</td><td>0x313fdfcc9f19a90748072baec39d786d34961309</td></tr><tr><td>TokenAPI</td><td>0x227534a66e521cfd95abb9e65c48d69ae5810b31</td></tr><tr><td>PairBootStrapper</td><td>0x7f8f2b6d0b0aae8e95221ce90b5c26b128c1cb66</td></tr><tr><td>TokenHandler</td><td>0xa1154fe44a3d5c740644b9028e4d68fd876de201</td></tr><tr><td>MinterUpgradeable</td><td>0xfe29ea1348f0990273db5e19ad521e45acda84a2</td></tr><tr><td>VotingEscrow</td><td>0x4c3e7640b3e3a39a2e5d030a0c1412d80fee1d44</td></tr><tr><td>CustomPoolDeployer</td><td>0x2493b36759fb77e40ef863ca59807a9d7689af4a</td></tr></tbody></table>

####

#### Algebra Contracts

<br>

<table data-header-hidden><thead><tr><th width="319.69140625"></th><th></th></tr></thead><tbody><tr><td>Name</td><td>Address</td></tr><tr><td>poolDeployer</td><td>0x45bc0f9855a626743d57d37d989f3b9462deba45</td></tr><tr><td>factory</td><td>0x44b7fbd4d87149efa5347c451e74b9fd18e89c55</td></tr><tr><td>vaultFactory</td><td>0xafc0497f052a3b5274659308d0b875271c03038d</td></tr><tr><td>entryPoint</td><td>0xb86a85acf0e658e4d3ac02c9fac3e122e5831288</td></tr><tr><td>tickLens</td><td>0x4e6a86199fc06adbf1ff59634c1a806116a7d6c9</td></tr><tr><td>quoter</td><td>0xf9439cd803dcb11fa574bcc8421207f89b529e41</td></tr><tr><td>quoterV2</td><td>0x8217550d36823b1194b58562dac55d7fe8efb727</td></tr><tr><td>swapRouter</td><td>0x72d63a5b080e1b89cc93f9b9f50cbfa5e291c8ac</td></tr><tr><td>nftDescriptor</td><td>0xabca00f6e3fb9fe4c8adbecc5f2daffe8c851045</td></tr><tr><td>nonfungiblePositionManager</td><td>0x00d5bbd0fe275efee371a2b34d0a4b95b0c8aaaa</td></tr><tr><td>BasePluginV3Factory</td><td>0xdbfd67d12cadb8925c1417ff3638693f2bf99b97</td></tr><tr><td>SecurityRegistry</td><td>0x454e62e725ad5a47931043f7e6369cfbb879bdfd</td></tr><tr><td>PluginV3Deployer</td><td>0x48012a780779f12b27f0f7f558cab5511d92eee3</td></tr><tr><td>FeeDiscountRegistry</td><td>0x31eda5529b8f219243e8248eff368bc36a3f5975</td></tr><tr><td>NonfungibleTokenPositionDescriptor</td><td>0xf9bc949bab0969ec4e32d725d9ffab226ab6535c</td></tr><tr><td>AlgebraInterfaceMulticall</td><td>0xc9ba2ef71d4c5ca59b426c4c3dae6aeabe041f18</td></tr><tr><td>AlgebraEternalFarming</td><td>0x1e862624eda92b8fe532c16253356d17dd70a337</td></tr><tr><td>FarmingCenter</td><td>0x428ea5b4ac84ab687851e6a2688411bdbd6c91af</td></tr></tbody></table>

#### Custom Pool Deployer Contracts

<br>

<table data-header-hidden><thead><tr><th width="296.28125"></th><th></th></tr></thead><tbody><tr><td>CustomPoolDeployer tick1</td><td>0xc815b4e0abae3155f8f4f9e404f17c9fa6928eb8</td></tr><tr><td>CustomPoolDeployer tick 10</td><td>0x1c798614ef4c6a8f8a1aab25785714933e59e963</td></tr><tr><td>CustomPoolDeployer tick 50</td><td>0x44acd9579650d300ebbeac2e483b97fdcacdddc0</td></tr><tr><td>CustomPoolDeployer tick 100</td><td>0xd7b7cc843331cbdc857d5e7615d320b8b4ac090e</td></tr><tr><td>CustomPoolDeployer tick 200</td><td>0x42f5ecd6497d42e093de05bec73e33ceb82493da</td></tr></tbody></table>

<br>

basic graph link - <https://api.goldsky.com/api/public/project_cm8gyxv0x02qv01uphvy69ey6/subgraphs/sn-basic-pools-mainnet/basicsnmainnet/gn>

algerba graph link - <https://api.goldsky.com/api/public/project_cm8gyxv0x02qv01uphvy69ey6/subgraphs/core/algebrasnmainnet/gn>

\ <br>

### Testnet Contract Addresses

<br>

<table data-header-hidden><thead><tr><th width="288.24609375"></th><th></th></tr></thead><tbody><tr><td>Contract Name</td><td>Address</td></tr><tr><td>superNova</td><td>0xb2Ef7B653DbeD27E36c005091c6112F181E3b29a</td></tr><tr><td>PermissionsRegistry</td><td>0x0a3CeF5FC2Ed55AC8C72c2A8a727b4EcCeC884ae</td></tr><tr><td>PairGenerator</td><td>0x60FBea626B5DbB2aa3aAC5595dE04dc56AAa9FA5</td></tr><tr><td>PairFactory</td><td>0xA55647E1476533742324e9D1b04Fd22EE2fb9395</td></tr><tr><td>VotingBalanceLogic</td><td>0x36DE4600a37caD52Ed8CadAfB16f94494CCcA47e</td></tr><tr><td>VeArtProxyUpgradeable</td><td>0xF12E1158b6e7C13f97910478e7f2297214C87592</td></tr><tr><td>GaugeFactory</td><td>0xf7EB780846AF098d7CAE9B6775fAC5150944C1eF</td></tr><tr><td>GaugeFactoryCL</td><td>0x319E1BBE86853E68d44C99481F1B649a1d872E68</td></tr><tr><td>VoterFactoryLib</td><td>0x9f8749212E000Baa58E8B47ABb231876fEB8f4fE</td></tr><tr><td>GaugeManager</td><td>0xc5DEdBf267f6099758552601451CAf649597C411</td></tr><tr><td>VoterV3</td><td>0x9408d319d01c858E130c14Fd6ae4ca8de2157D86</td></tr><tr><td>BribeFactoryV3</td><td>0xE6caF7f584Fd99A9957b23e3c9C1686d6D0190dc</td></tr><tr><td>AlgebraPoolAPIStorage</td><td>0x1886Ff6cC5CFC5ef1AD32b7E2e8711Ec7F431aC2</td></tr><tr><td>AlgebraPoolAPI</td><td>0x9f52E2b043ed71c7E58168B8Ba0D433410A40AF3</td></tr><tr><td>RouterHelper</td><td>0x9228fd7d15E5c8C59e0DCA895B157E11870FFA42</td></tr><tr><td>RouterV2</td><td>0x6284fe70EAf5B74b0b1F3d17E83843115d6029c6</td></tr><tr><td>BlackholePairAPIV2</td><td>0xAc5D47BdC6CE689DDbccA70dC8c74E7262742459</td></tr><tr><td>RewardsDistributor</td><td>0x9b7aB771AA60096F3D27E441ECE968809ADDAC6c</td></tr><tr><td>VeNFTAPI</td><td>0x0802E33C458891BEA1Cd2994d86DB25BE78a07b7</td></tr><tr><td>SuperNovaClaims</td><td>0xDE818029FCE704ce2a5eCD6d20d6BeB3B7fe8885</td></tr><tr><td>TokenAPI</td><td>0x07C81982Bb618D0f461425Bc19d8e5e690626318</td></tr><tr><td>PairBootStrapper</td><td>0x823DA2c4372B493bf04d62F71B5fDF99011a7c7d</td></tr><tr><td>TokenHandler</td><td>0xC534a17E0B8DefB5Eb9c57fB9875836Bff7679d9</td></tr><tr><td>MinterUpgradeable</td><td>0xc89aE099c28a86151B7d0708fB7EF6D1c02228D1</td></tr><tr><td>VotingEscrow</td><td>0x13cb217885Ec53F3A52d114FC7A66A3357875254</td></tr><tr><td>CustomPoolDeployer</td><td>0xE1Bb451c7026fCaF5b9F6f728e9a281a2B467763</td></tr></tbody></table>

####

#### Algebra Contracts

<br>

<table data-header-hidden><thead><tr><th width="299.75"></th><th></th></tr></thead><tbody><tr><td>Name</td><td>Address</td></tr><tr><td>poolDeployer</td><td>0xED638309E8639c4Bc7dFC8f2F8BACc7F07ED338F</td></tr><tr><td>factory</td><td>0xFc58e73C2F9Fc8e6C711654575faE6c2fd3b2237</td></tr><tr><td>vaultFactory</td><td>0x63e0729C49b490c510231af7f11B840E55b097eB</td></tr><tr><td>BasePluginV1Factory</td><td>0xebf6f5Ef7dC16b94bc37b01F4c58AFFd9fe418da</td></tr><tr><td>wrapped</td><td>0xfff9976782d46cc05630d1f6ebab18b2324d6b14</td></tr><tr><td>entryPoint</td><td>0xdab3c086f0194974994Facd60eD303FC2589ee98</td></tr><tr><td>tickLens</td><td>0xdD7F4e3DF68247c8391719c0Dc4d60De6a48EC57</td></tr><tr><td>quoter</td><td>0x597C84e1Cca9754A46F5d825a0A0FF89b98E07F0</td></tr><tr><td>quoterV2</td><td>0x37C793Ed76D336AfaA44698c42b8383C22847f71</td></tr><tr><td>swapRouter</td><td>0x9C19A37D2C66300c5b8f7219D2D5EBb95230dD49</td></tr><tr><td>nftDescriptor</td><td>0xF943F74c243dE7cc25352fFE77745Df8Aa331944</td></tr><tr><td>proxy</td><td>0xF6E3A9ABeA6Cb56A7bd8F750f2Cb8Fa7A84AAD98</td></tr><tr><td>admin</td><td>0xf6DACcfe3d9E8370d7DF84654ab2D893804B7D0B</td></tr><tr><td>nonfungiblePositionManager</td><td>0xb0764222392298BE9F538C464Aaa1C6c3fa971aC</td></tr><tr><td>mcall</td><td>0x327BbcCBA12b19bf428A213F88c499328f43a76A</td></tr><tr><td>eternal</td><td>0xd6Ca86BF3FA1d43766f9cf1335C96fA8BEAb0122</td></tr><tr><td>fc</td><td>0x00b07Ca11a9F97cdA5B4419a013E5CA71CA2b26F</td></tr><tr><td>BasePluginV3Factory</td><td>0xfCD46Fc0D003115D433bD994442495956f18765e</td></tr><tr><td>SecurityRegistry</td><td>0x88506a980D4A639D8e3eA2Ab98d6E888841D6724</td></tr><tr><td>PluginV3Deployer</td><td>0x01f4b84e8720c5171044C3A86c3993a5B0973C2b</td></tr><tr><td>FeeDiscountRegistry</td><td>0x8b9568B5a4A7B1EFA3d53F71C6cf3ea108428aeA</td></tr></tbody></table>

###
