Publication
Partagez vos connaissances.
How to Create a Liquidity Pool in Sui Move?
I'm building a DeFi protocol on Sui and need to implement a basic liquidity pool (like Uniswap-style AMM) in Move. I'm struggling with:
- Storing LP tokens – How to handle dynamic supply and balances?
- Deposits/Withdrawals – Ensuring atomic swaps and proper math.
- Fee mechanism – Where to deduct fees without breaking invariants?
- Frontrunning protection – Is there a built-in way to handle slippage?
What I've tried:
- Basic two-token pool using Table for balances.
- Manual LP mint/burn logic.
- Fixed 0.3% fee on swaps.
Issues encountered:
- "Arithmetic overflow" when calculating liquidity.
- Reentrancy risks – Can Sui Move prevent this?
- LP token accuracy – Decimals handling feels hacky.
Questions:
- What’s the correct architecture for a Sui liquidity pool?
- How to implement safe math for swaps/deposits?
- Are there Sui-specific optimizations (vs. EVM AMMs)?
- How to make the pool composable with other DeFi protocols?
- Sui
Réponses
11. Structure de base Le modèle centré sur l'objet de Sui nécessite :
Objet du pool : stocke les réserves, les données des jetons LP et la configuration.
Jeton LP : un
move
module dex::amm {
use sui::balance;
use sui::coin;
use sui::math;
use sui::tx_context;
struct Pool<phantom X, phantom Y> has key {
id: UID,
reserve_x: Balance<X>,
reserve_y: Balance<Y>,
lp_supply: Balance<LP<X, Y>>,
fee_bps: u64, // e.g., 30 = 0.3%
}
struct LP<phantom X, phantom Y> has store {} // LP token type
2. Logique de dépôt (ajout de liquidités) Étapes clés :
Prenez des jetons d'entrée.
Fabriquez des jetons LP proportionnellement.
Mettez à jour les réserves de manière atomique.
move
public fun add_liquidity<X, Y>(
pool: &mut Pool<X, Y>,
x: Coin<X>,
y: Coin<Y>,
ctx: &mut TxContext
): Coin<LP<X, Y>> {
let x_val = coin::value(&x);
let y_val = coin::value(&y);
assert!(x_val > 0 && y_val > 0, EINVALID_AMOUNT);
// Calculate LP tokens to mint (geometric mean)
let lp_amount = if (balance::supply(&pool.lp_supply) == 0) {
math::sqrt(x_val * y_val) // Initial mint
} else {
min(
(x_val * balance::supply(&pool.lp_supply)) / balance::value(&pool.reserve_x),
(y_val * balance::supply(&pool.lp_supply)) / balance::value(&pool.reserve_y)
)
};
// Update reserves
balance::join(&mut pool.reserve_x, coin::into_balance(x));
balance::join(&mut pool.reserve_y, coin::into_balance(y));
// Mint LP tokens
balance::increase_supply(&mut pool.lp_supply, lp_amount)
}
3. Swap Logic (avec frais)
move
public fun swap_x_to_y<X, Y>(
pool: &mut Pool<X, Y>,
dx: Coin<X>,
min_dy: u64,
ctx: &mut TxContext
): Coin<Y> {
let dx_val = coin::value(&dx);
let fee = dx_val * pool.fee_bps / 10_000;
let dx_after_fee = dx_val - fee;
// Constant product formula
let dy_val = (dx_after_fee * balance::value(&pool.reserve_y)) /
(balance::value(&pool.reserve_x) + dx_after_fee);
assert!(dy_val >= min_dy, EINSUFFICIENT_OUTPUT);
// Update reserves
balance::join(&mut pool.reserve_x, coin::into_balance(dx));
balance::withdraw(&mut pool.reserve_y, dy_val)
}
4. Optimisations clés Avantages de la suie :
Pas de réadmission : le modèle de propriété de Move l'empêche.
Transactions par lots : utilisez les fonctions de saisie pour les opérations en plusieurs étapes.
Champs dynamiques : stockez des données supplémentaires (par exemple, des oracles TWAP) sur l'objet du pool.
5. Pièges et solutions courants Débordement : utilisez les fonctions math : :checked_* pour l'arithmétique.
Arrondissement LP : stockez des quantités fractionnaires via u128 en interne.
En tête de liste :
Exiger min_dy dans les swaps (défini par le frontend).
Utilisez TxContext : :epoch () pour vérifier les délais.
Connaissez-vous la réponse ?
Veuillez vous connecter et la partager.
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
Gagne ta part de 1000 Sui
Gagne des points de réputation et obtiens des récompenses pour avoir aidé la communauté Sui à se développer.
- Pourquoi BCS exige-t-il un ordre de champs exact pour la désérialisation alors que les structures Move ont des champs nommés ?53
- « Erreurs de vérification de sources multiples » dans les publications du module Sui Move - Résolution automatique des erreurs42
- Échec de la transaction Sui : objets réservés pour une autre transaction24
- Comment les contraintes de capacité interagissent-elles avec les champs dynamiques dans des collections hétérogènes ?04