working version, before optimalization
This commit is contained in:
103
florida/doc/AERODROME_CL_INTEGRATION.md
Normal file
103
florida/doc/AERODROME_CL_INTEGRATION.md
Normal file
@ -0,0 +1,103 @@
|
||||
# Aerodrome Slipstream (CLP) Integration Guide
|
||||
|
||||
This document details the specific technical requirements for integrating **Aerodrome Slipstream** (Concentrated Liquidity) pools into a Uniswap V3-compatible bot. Aerodrome Slipstream is a fork of Uniswap V3 (via Velodrome V2) but introduces critical ABI and logic changes that cause standard implementations to fail.
|
||||
|
||||
## 1. Key Differences from Uniswap V3
|
||||
|
||||
| Feature | Standard Uniswap V3 | Aerodrome Slipstream |
|
||||
| :--- | :--- | :--- |
|
||||
| **Factory Pool Lookup** | `getPool(tokenA, tokenB, fee)` | `getPool(tokenA, tokenB, tickSpacing)` |
|
||||
| **NPM Mint Parameter** | `uint24 fee` | `int24 tickSpacing` |
|
||||
| **NPM Mint Struct** | `MintParams { ..., deadline }` | `MintParams { ..., deadline, sqrtPriceX96 }` |
|
||||
| **Pool Identification** | Fee Tier (e.g., 500, 3000) | Tick Spacing (e.g., 1, 100) |
|
||||
|
||||
## 2. ABI Modifications
|
||||
|
||||
To interact with the Aerodrome `NonfungiblePositionManager` (NPM), you must use a modified ABI. The standard Uniswap V3 NPM ABI will result in revert errors during encoding.
|
||||
|
||||
### MintParams Struct
|
||||
The `MintParams` struct in the `mint` function input must be defined as follows:
|
||||
|
||||
```json
|
||||
{
|
||||
"components": [
|
||||
{"internalType": "address", "name": "token0", "type": "address"},
|
||||
{"internalType": "address", "name": "token1", "type": "address"},
|
||||
{"internalType": "int24", "name": "tickSpacing", "type": "int24"}, // CHANGED from uint24 fee
|
||||
{"internalType": "int24", "name": "tickLower", "type": "int24"},
|
||||
{"internalType": "int24", "name": "tickUpper", "type": "int24"},
|
||||
{"internalType": "uint256", "name": "amount0Desired", "type": "uint256"},
|
||||
{"internalType": "uint256", "name": "amount1Desired", "type": "uint256"},
|
||||
{"internalType": "uint256", "name": "amount0Min", "type": "uint256"},
|
||||
{"internalType": "uint256", "name": "amount1Min", "type": "uint256"},
|
||||
{"internalType": "address", "name": "recipient", "type": "address"},
|
||||
{"internalType": "uint256", "name": "deadline", "type": "uint256"},
|
||||
{"internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160"} // ADDED
|
||||
],
|
||||
"internalType": "struct INonfungiblePositionManager.MintParams",
|
||||
"name": "params",
|
||||
"type": "tuple"
|
||||
}
|
||||
```
|
||||
|
||||
## 3. Python Implementation Strategy
|
||||
|
||||
### A. Configuration
|
||||
When defining the pool configuration, use the **Tick Spacing** value (e.g., 100) where you would normally put the Fee.
|
||||
|
||||
```python
|
||||
"AERODROME_BASE_CL": {
|
||||
"NAME": "Aerodrome SlipStream (Base) - WETH/USDC",
|
||||
"NPM_ADDRESS": "0x827922686190790b37229fd06084350E74485b72", # Aerodrome NPM
|
||||
"POOL_FEE": 100, # Actual TickSpacing (e.g., 100 for volatile, 1 for stable)
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### B. Logic Changes (`clp_manager.py`)
|
||||
|
||||
1. **ABI Selection:** Dynamically switch between Standard and Aerodrome ABIs based on the target DEX.
|
||||
2. **Parameter Construction:** When calling `mint`, check if the target is Aerodrome. If so, append `0` (for `sqrtPriceX96`) to the arguments tuple.
|
||||
|
||||
```python
|
||||
# Pseudo-code for Mint Call
|
||||
base_params = [
|
||||
token0, token1,
|
||||
tick_spacing, # Passed as int24
|
||||
tick_lower, tick_upper,
|
||||
amount0, amount1,
|
||||
amount0_min, amount1_min,
|
||||
recipient,
|
||||
deadline
|
||||
]
|
||||
|
||||
if is_aerodrome:
|
||||
base_params.append(0) # sqrtPriceX96 must be present and 0 for existing pools
|
||||
|
||||
npm_contract.functions.mint(tuple(base_params)).transact(...)
|
||||
```
|
||||
|
||||
### C. Swap Router
|
||||
Aerodrome Slipstream's **SwapRouter** (`0xbe6D...`) uses the `SwapRouter01` ABI style (includes `deadline` in `ExactInputSingleParams`), whereas standard Uniswap V3 on Base often uses `SwapRouter02` (no deadline).
|
||||
|
||||
* **Tip:** For simplicity, you can use the **Standard Uniswap V3 Router** (`0x2626...`) on Base to swap tokens (WETH/USDC) even if you are providing liquidity on Aerodrome, provided the tokens are standard. This avoids ABI headaches with the Aerodrome Router if you only need simple swaps.
|
||||
|
||||
## 4. Troubleshooting Common Errors
|
||||
|
||||
* **`('execution reverted', 'no data')`**:
|
||||
* **Cause 1:** Passing `fee` (uint24) instead of `tickSpacing` (int24).
|
||||
* **Cause 2:** Missing `sqrtPriceX96` parameter in the struct.
|
||||
* **Cause 3:** Tick range (`tickLower`, `tickUpper`) not aligned to the pool's `tickSpacing` (e.g., must be multiples of 100).
|
||||
* **`BadFunctionCallOutput` / `InsufficientDataBytes`**:
|
||||
* **Cause:** Using the wrong Contract Address for the chain (e.g., using Mainnet NPM address on Base).
|
||||
* **Cause:** Calling `factory()` on a contract that doesn't have it (wrong ABI or Proxy).
|
||||
|
||||
## 5. Addresses (Base)
|
||||
|
||||
| Contract | Address |
|
||||
| :--- | :--- |
|
||||
| **Aerodrome NPM** | `0x827922686190790b37229fd06084350E74485b72` |
|
||||
| **Aerodrome Factory** | `0x5e7BB104d84c7CB9B682AaC2F3d509f5F406809A` |
|
||||
| **Uniswap V3 NPM** | `0xC36442b4a4522E871399CD717aBDD847Ab11FE88` |
|
||||
| **WETH** | `0x4200000000000000000000000000000000000006` |
|
||||
| **USDC** | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` |
|
||||
Reference in New Issue
Block a user