docs: wip and format

This commit is contained in:
ignacio.pena@coinfabrik.com
2025-05-08 12:40:36 -03:00
parent db691e1bfd
commit 7068bdde01

View File

@@ -4,13 +4,14 @@
The `self-listing-helper-v3a` contract enables the creation of trading pools on the ALEX DEX through two distinct mechanisms: a permissioned flow and a permissionless flow.
In the **permissioned flow**, pre-approved tokens can create pools by following a guided process through the ALEX UI. These tokens must be whitelisted and have sufficient anchor token liquidity.
In the **permissioned flow**, pre-approved tokens can create pools by following a guided process through the ALEX UI. These tokens must be whitelisted and have sufficient anchor token liquidity. Each pool must pair a pre-approved anchor token (`token-x`) with a user-provided token (`token-y`), which is the asset being newly listed.
In the **permissionless flow**, any user can list a new token by deploying a wrapper contract that matches an approved template. The contract includes a verification system to ensure the integrity of the deployment: it reconstructs and validates the original contract transaction using Merkle proofs and block data, confirming that the wrapper is trustworthy.
In the **permissionless flow**, any user can list a new token (`token-y`) by deploying a wrapper contract that matches an approved template. The pool is formed against an existing, governance-approved `token-x`. The contract includes a verification system to ensure the integrity of the deployment: it reconstructs and validates the original contract transaction using Merkle proofs and block data, confirming that the wrapper is trustworthy.
Once verification succeeds, the token is dynamically approved and a pool is created.
The contract also supports:
- Liquidity locking or burning for pool integrity
- On-chain parameter configuration (fees, oracles, thresholds)
- Governance-controlled token approvals
@@ -22,7 +23,7 @@ This dual approach gives projects the flexibility to choose between a guided lis
### Public Features
#### `create`
#### `create`
This function initiates the creation of a liquidity pool between two pre-approved tokens. It is used in the **permissioned listing** flow, where the listing token (`token-y`) has already been approved by governance or whitelisted in the system.
@@ -31,6 +32,7 @@ The function first runs validation checks via `pre-check`, which ensures the anc
Next, it verifies that the listing token has a reserve in the `amm-vault-v2-01` contract, which serves as a proxy for its approval status.
If all validations pass, the function calls `post-check`, which:
- Creates the new pool on `amm-pool-v2-01`
- Configures its parameters (fees, thresholds, oracle)
- Applies LP token lock or burn rules via `liquidity-locker` if requested
@@ -39,9 +41,9 @@ The function emits a print log with the full pool configuration for transparency
##### Parameters
| Name | Type |
|------------------|------------|
| `request-details`| `{ token-x-trait: <ft-trait>, token-y-trait: <ft-trait>, factor: uint, bal-x: uint, bal-y: uint, fee-rate-x: uint, fee-rate-y: uint, max-in-ratio: uint, max-out-ratio: uint, threshold-x: uint, threshold-y: uint, oracle-enabled: bool, oracle-average: uint, start-block: uint, lock: (buff 1) }` |
| Name | Type |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `request-details` | `{ token-x-trait: <ft-trait>, token-y-trait: <ft-trait>, factor: uint, bal-x: uint, bal-y: uint, fee-rate-x: uint, fee-rate-y: uint, max-in-ratio: uint, max-out-ratio: uint, threshold-x: uint, threshold-y: uint, oracle-enabled: bool, oracle-average: uint, start-block: uint, lock: (buff 1) }` |
#### `create2`
@@ -50,6 +52,7 @@ This function allows the creation of a new liquidity pool using a token that has
Before calling this function, the user must deploy a wrapper contract for the listing token (`token-y`) that matches an approved template. The contract must then be verified on-chain by submitting proof of deployment.
The function begins by validating the request with `pre-check`. It then calls `verify-deploy`, which:
- Reconstructs the transaction ID based on the deployment parameters
- Validates that the contract was mined using a Merkle proof and block data
- Ensures the code matches the wrapper template stored in this contract
@@ -60,46 +63,49 @@ Finally, `post-check` is executed to create the pool and configure its parameter
##### Parameters
| Name | Type |
|------------------|------------|
| `request-details`| `{ token-x-trait: <ft-trait>, token-y-trait: <ft-trait>, factor: uint, bal-x: uint, bal-y: uint, fee-rate-x: uint, fee-rate-y: uint, max-in-ratio: uint, max-out-ratio: uint, threshold-x: uint, threshold-y: uint, oracle-enabled: bool, oracle-average: uint, start-block: uint, lock: (buff 1) }` |
| `verify-params` | `{ nonce: (buff 8), fee-rate: (buff 8), signature: (buff 65), contract: principal, token-y: principal, proof: { tx-index: uint, hashes: (list 14 (buff 32)), tree-depth: uint }, tx-block-height: uint, block-header-without-signer-signatures: (buff 712) }` |
| Name | Type |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `request-details` | `{ token-x-trait: <ft-trait>, token-y-trait: <ft-trait>, factor: uint, bal-x: uint, bal-y: uint, fee-rate-x: uint, fee-rate-y: uint, max-in-ratio: uint, max-out-ratio: uint, threshold-x: uint, threshold-y: uint, oracle-enabled: bool, oracle-average: uint, start-block: uint, lock: (buff 1) }` |
| `verify-params` | `{ nonce: (buff 8), fee-rate: (buff 8), signature: (buff 65), contract: principal, token-y: principal, proof: { tx-index: uint, hashes: (list 14 (buff 32)), tree-depth: uint }, tx-block-height: uint, block-header-without-signer-signatures: (buff 712) }` |
#### `lock-liquidity`
This function locks a specified amount of LP tokens for a given pool. It is typically used immediately after a pool is created, when the creator chooses to lock the initial liquidity as a trust signal for other users.
Internally, it calls the `lock-liquidity` function of the external `.liquidity-locker` contract. That contract:
Internally, it calls the `lock-liquidity` function of the external `liquidity-locker` contract. That contract:
- Transfers the LP tokens from the caller to its own custody
- Records the locked amount and sets an unlock block height (default: ~6 months)
##### Parameters
| Name | Type |
|------------|--------|
| `amount` | `uint` |
| `pool-id` | `uint` |
| Name | Type |
| --------- | ------ |
| `amount` | `uint` |
| `pool-id` | `uint` |
#### `burn-liquidity`
This function allows the caller to burn a specified amount of LP tokens from a given pool. It is one of the options available when configuring the pool after creation, typically used to make the initial liquidity permanently inaccessible.
Internally, it calls the `burn-liquidity` function of the external `.liquidity-locker` contract. That contract:
Internally, it calls the `burn-liquidity` function of the external `liquidity-locker` contract. That contract:
- Calls the `burn-fixed` function on the pool contract to destroy the LP tokens
- Updates the internal `burnt-liquidity` record for that pool
##### Parameters
| Name | Type |
|------------|--------|
| `amount` | `uint` |
| `pool-id` | `uint` |
| Name | Type |
| --------- | ------ |
| `amount` | `uint` |
| `pool-id` | `uint` |
#### `claim-liquidity`
This function allows users to reclaim their previously locked LP tokens after the lock period has expired.
Internally, it calls the `claim-liquidity` function from the external `liquidity-locker` contract. That contract:
- Checks that the caller has a non-zero locked amount
- Verifies that the current block is past the `end-burn-block` set during locking
- Transfers the LP tokens back to the user
@@ -107,13 +113,14 @@ Internally, it calls the `claim-liquidity` function from the external `liquidity
##### Parameters
| Name | Type |
|------------|--------|
| `pool-id` | `uint` |
| Name | Type |
| --------- | ------ |
| `pool-id` | `uint` |
### Governance Features
#### `is-dao-or-extension`
This standard protocol function checks whether a caller (`tx-sender`) is the DAO executor or an authorized extension, delegating the extensions check to the `executor-dao` contract.
#### `approve-token-x`
@@ -124,8 +131,8 @@ This function updates the `approved-token-x` map, enabling the protocol to defin
##### Parameters
| Name | Type |
|------------|-----------|
| Name | Type |
| ---------- | ----------- |
| `token` | `principal` |
| `approved` | `bool` |
| `min-x` | `uint` |
@@ -139,7 +146,7 @@ This value is stored locally in the contract and passed as an argument to the `s
##### Parameters
| Name | Type |
|------------------|--------|
| ---------------- | ------ |
| `new-fee-rebate` | `uint` |
#### `set-wrapped-token-template`
@@ -150,9 +157,9 @@ The `wrapped-token-template` is a list of code segments (as ASCII strings) that
##### Parameters
| Name | Type |
|----------------|--------------------------------------|
| `new-template` | `(list 20 (string-ascii 5000))` |
| Name | Type |
| -------------- | ------------------------------- |
| `new-template` | `(list 20 (string-ascii 5000))` |
### Getters
@@ -160,9 +167,9 @@ The `wrapped-token-template` is a list of code segments (as ASCII strings) that
##### Parameters
| Name | Type |
|-----------|------------|
| `token-x` | `principal`|
| Name | Type |
| --------- | ----------- |
| `token-x` | `principal` |
#### `get-fee-rebate`
@@ -172,34 +179,34 @@ The `wrapped-token-template` is a list of code segments (as ASCII strings) that
##### Parameters
| Name | Type |
|----------|------------|
| `owner` | `principal`|
| `pool-id`| `uint` |
| Name | Type |
| --------- | ----------- |
| `owner` | `principal` |
| `pool-id` | `uint` |
#### `get-locked-liquidity-for-pool-or-default`
##### Parameters
| Name | Type |
|----------|------|
| `pool-id`|`uint`|
| Name | Type |
| --------- | ------ |
| `pool-id` | `uint` |
#### `get-burnt-liquidity-or-default`
##### Parameters
| Name | Type |
|----------|------|
| `pool-id`|`uint`|
| Name | Type |
| --------- | ------ |
| `pool-id` | `uint` |
#### `get-wrapped-token-contract-code`
##### Parameters
| Name | Type |
|---------|------------|
| `token` | `principal`|
| Name | Type |
| ------- | ----------- |
| `token` | `principal` |
### Relevant internal functions
@@ -208,6 +215,7 @@ The `wrapped-token-template` is a list of code segments (as ASCII strings) that
This private function performs validations prior to pool creation in both permissioned and permissionless flows.
It verifies that:
- The `token-x` is approved and has sufficient balance (`bal-x`).
- A pool with the given pair and factor does not already exist (in either order).
- The provided `lock` parameter is valid (`NONE`, `LOCK`, or `BURN`).
@@ -216,8 +224,8 @@ It retrieves the approval and minimum balance requirements from the internal `ap
##### Parameters
| Name | Type |
|-------------------|----------------------------------------------------|
| Name | Type |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `request-details` | `{ token-x-trait: <ft-trait>, token-y-trait: <ft-trait>, factor: uint, bal-x: uint, bal-y: uint, fee-rate-x: uint, fee-rate-y: uint, max-in-ratio: uint, max-out-ratio: uint, threshold-x: uint, threshold-y: uint, oracle-enabled: bool, oracle-average: uint, start-block: uint, lock: (buff 1) }` |
#### `post-check`
@@ -225,16 +233,80 @@ It retrieves the approval and minimum balance requirements from the internal `ap
This private function finalizes pool creation by initializing the AMM pool and applying additional configuration parameters.
It performs the following actions:
- Calls the `create-pool` function from the external `.amm-pool-v2-01` contract to initialize the pool with the provided liquidity amounts.
- If the `lock` parameter is set to `LOCK`, it calls `lock-liquidity` from the `.liquidity-locker` contract to lock the initial LP tokens.
- If the `lock` is `BURN`, it calls `burn-liquidity` from the `.liquidity-locker` contract instead.
- Applies pool parameters like fee rates, max ratios, thresholds, oracle settings, and the `start-block` by calling their respective setter functions in the `.amm-pool-v2-01` contract.
- Finally, it applies the global fee rebate for the pool by calling `set-fee-rebate` from the external `.amm-registry-v2-01` contract.
- If the `lock` parameter is set to `LOCK`, it calls `lock-liquidity` from the `liquidity-locker` contract to lock the initial LP tokens.
- If the `lock` is `BURN`, it calls `burn-liquidity` from the `liquidity-locker` contract instead.
- Applies pool parameters like fee rates, max ratios, thresholds, oracle settings, and the `start-block` by calling their respective setter functions in the `amm-pool-v2-01` contract.
- Finally, it applies the global fee rebate for the pool by calling `set-fee-rebate` from the external `amm-registry-v2-01` contract.
This function is used after both `create` and `create2` to complete the pool setup.
##### Parameters
| Name | Type |
|-------------------|----------------------------------------------------|
| Name | Type |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `request-details` | `{ token-x-trait: <ft-trait>, token-y-trait: <ft-trait>, factor: uint, bal-x: uint, bal-y: uint, fee-rate-x: uint, fee-rate-y: uint, max-in-ratio: uint, max-out-ratio: uint, threshold-x: uint, threshold-y: uint, oracle-enabled: bool, oracle-average: uint, start-block: uint, lock: (buff 1) }` |
## Storage
### `wrapped-token-template`
| Data | Type |
| -------- | ----------------------------- |
| Variable | `list 20 (string-ascii 5000)` |
A list of strings that together define the expected code template for a valid wrapper token contract. Each entry represents a fragment of the full contract body, and the full code is reconstructed by concatenating these parts with the listed token's contract address.
This template is used during permissionless pool creation (`create2`) to verify that a wrapper contract deployed by a user matches the expected safe implementation.
### `approved-token-x`
| Data | Type |
| ---- | ---------------------------------------------- |
| Map | `principal => { approved: bool, min-x: uint }` |
A map that stores the approval status and minimum liquidity threshold for tokens used as `token-x` (anchor token) in pool creation. This validation is applied in both permissioned and permissionless listing flows.
### `fee-rebate`
| Data | Type |
| -------- | ------ |
| Variable | `uint` |
A global rebate value that is assigned to newly created pools. This value is passed to the `amm-registry-v2-01` contract during pool setup, where it determines the protocol fee discount applied to the pool.
### `wrap-token-map`
| Data | Type |
| ---- | ------------------------ |
| Map | `principal => principal` |
A map that links a listed token (`token-y`) to its corresponding verified wrapper contract.
It is only populated during the permissionless listing flow, once the deployment proof is validated.
This allows the AMM system to recognize and route trades through the correct wrapper contract.
## Contract calls
- `executor-dao`: calls are made to verify whether a certain contract-caller is designated as an extension.
- `liquidity-locker`: this contract is used to manage post-creation liquidity settings. It allows the contract to lock, burn, or later claim LP tokens based on the pool creators configuration.
- `clarity-stacks`: this contract is used to verify that a token wrapper contract was properly deployed on the Stacks blockchain. It ensures the deployment was mined and included in a valid block.
- `clarity-stacks-helper`: this contract is called to convert a Clarity string into its consensus-encoded buffer format.
- `amm-vault-v2-01`: this contract is called to verify that `token-y` has reserves before pool creation and to approve it in the permissionless listing flow after successful wrapper verification.
- `amm-pool-v2-01`: this contract is used to validate pool existence, create new trading pools, and configure pool parameters such as fees, slippage thresholds, oracles, and start block.
- `amm-registry-v2-01`: this contract is called during pool creation to assign the fee rebate configuration for the newly created pool.
## Errors
| Error Name | Value |
| ------------------------------- | ------------- |
| `err-not-authorised` | `(err u1000)` |
| `err-token-not-approved` | `(err u1002)` |
| `err-insufficient-balance` | `(err u1003)` |
| `err-pool-exists` | `(err u1004)` |
| `err-invalid-lock-parameter` | `(err u1005)` |
| `err-invalid-length-nonce` | `(err u2000)` |
| `err-invalid-length-fee` | `(err u2001)` |
| `err-invalid-length-signature` | `(err u2002)` |
| `err-invalid-principal-version` | `(err u2003)` |
| `err-principal-not-contract` | `(err u2004)` |