Skip to content

Commit

Permalink
Generate LP name and symbol from coin symbols with new limit sizes (#92)
Browse files Browse the repository at this point in the history
* generate lp_name and lp_symbol from coin symbols

* remove unused constants, add docs to new const

* pseudocode for docs in generate symbol

* more docs

* change symbols

* fix tests
  • Loading branch information
mkurnikov authored and borispovod committed Sep 20, 2022
1 parent 557fe22 commit 1d4d3b6
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 36 deletions.
59 changes: 40 additions & 19 deletions sources/libs/coin_helper.move
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
/// The `CoinHelper` module contains helper funcs to work with `AptosFramework::Coin` module.
module liquidswap::coin_helper {
use std::option;
use std::string::{Self, String, bytes};
use std::vector;
use std::string::{Self, String};

use aptos_framework::coin;
use aptos_std::comparator::{Self, Result};
use aptos_std::type_info;

use liquidswap::curves::is_stable;
use liquidswap::math;

// Errors codes.

/// When both coins have same names and can't be ordered.
Expand All @@ -17,13 +19,8 @@ module liquidswap::coin_helper {
const ERR_IS_NOT_COIN: u64 = 3001;

// Constants.

/// When both coin names are equal.
const EQUAL: u8 = 0;
/// When coin `X` name is less than coin `Y` name.
const LESS_THAN: u8 = 1;
/// When coin `X` name is greater than coin `X` name.
const GREATER_THAN: u8 = 2;
/// Length of symbol prefix to be used in LP coin symbol.
const SYMBOL_PREFIX_LENGTH: u64 = 4;

/// Check if provided generic `CoinType` is a coin.
public fun assert_is_coin<CoinType>() {
Expand Down Expand Up @@ -70,16 +67,40 @@ module liquidswap::coin_helper {
option::extract(&mut coin::supply<CoinType>())
}

/// Generate LP coin name for pair `X`/`Y`.
/// Returns generated symbol and name (`symbol<X>()` + "-" + `symbol<Y>()`).
/// Generate LP coin name and symbol for pair `X`/`Y` and curve `Curve`.
/// ```
///
/// (curve_name, curve_symbol) = when(curve) {
/// is Uncorrelated -> (""(no symbol), "-U")
/// is Stable -> ("*", "-S")
/// }
/// name = "LiquidLP-" + symbol<X>() + "-" + symbol<Y>() + curve_name;
/// symbol = symbol<X>()[0:4] + "-" + symbol<Y>()[0:4] + curve_symbol;
/// ```
/// For example, for `LP<BTC, USDT, Uncorrelated>`,
/// the result will be `(b"LiquidLP-BTC-USDT+", b"BTC-USDT+")`
public fun generate_lp_name_and_symbol<X, Y, Curve>(): (String, String) {
let symbol = b"LP-";
vector::append(&mut symbol, *bytes(&coin::symbol<X>()));
vector::push_back(&mut symbol, 0x2d);
vector::append(&mut symbol, *bytes(&coin::symbol<Y>()));
vector::push_back(&mut symbol, 0x2d);
vector::append(&mut symbol, type_info::struct_name(&type_info::type_of<Curve>()));

(string::utf8(b"Liquidswap LP"), string::utf8(symbol))
let lp_name = string::utf8(b"");
string::append_utf8(&mut lp_name, b"LiquidLP-");
string::append(&mut lp_name, coin::symbol<X>());
string::append_utf8(&mut lp_name, b"-");
string::append(&mut lp_name, coin::symbol<Y>());

let lp_symbol = string::utf8(b"");
string::append(&mut lp_symbol, coin_symbol_prefix<X>());
string::append_utf8(&mut lp_symbol, b"-");
string::append(&mut lp_symbol, coin_symbol_prefix<Y>());

let (curve_name, curve_symbol) = if (is_stable<Curve>()) (b"-S", b"*") else (b"-U", b"");
string::append_utf8(&mut lp_name, curve_name);
string::append_utf8(&mut lp_symbol, curve_symbol);

(lp_name, lp_symbol)
}

fun coin_symbol_prefix<CoinType>(): String {
let symbol = coin::symbol<CoinType>();
let prefix_length = math::min_u64(string::length(&symbol), SYMBOL_PREFIX_LENGTH);
string::sub_string(&symbol, 0, prefix_length)
}
}
4 changes: 4 additions & 0 deletions sources/libs/math.move
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,8 @@ module liquidswap::math {
};
res
}

public fun min_u64(a: u64, b: u64): u64 {
if (a < b) a else b
}
}
6 changes: 3 additions & 3 deletions sources/swap/liquidity_pool.move
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ module liquidswap::liquidity_pool {
use liquidswap::stable_curve;
use liquidswap::lp_account;
use liquidswap_lp::lp_coin::LP;
use std::string::utf8;

// Error codes.

Expand Down Expand Up @@ -107,11 +106,12 @@ module liquidswap::liquidity_pool {
let pool_cap = borrow_global<PoolAccountCapability>(@liquidswap);
let pool_account = account::create_signer_with_capability(&pool_cap.signer_cap);

let (lp_name, lp_symbol) = coin_helper::generate_lp_name_and_symbol<X, Y, Curve>();
let (lp_burn_cap, lp_freeze_cap, lp_mint_cap) =
coin::initialize<LP<X, Y, Curve>>(
&pool_account,
utf8(b"Liquidswap LP"),
utf8(b"LP"),
lp_name,
lp_symbol,
6,
true
);
Expand Down
87 changes: 79 additions & 8 deletions tests/coin_helper_tests.move
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
#[test_only]
module liquidswap::coin_helper_tests {
use std::string::utf8;
use std::string::{utf8, String};

use aptos_framework::coin;
use aptos_framework::genesis;
use aptos_std::comparator;

use liquidswap::coin_helper;
use liquidswap::curves::Uncorrelated;
use test_coin_admin::test_coins::{Self, BTC, USDT};
use liquidswap::curves::{Uncorrelated, Stable};
use test_coin_admin::test_coins::{Self, BTC, USDT, create_coin_admin};

fun register_coins_for_lp_names(
btc_name: vector<u8>,
btc_symbol: vector<u8>,
usdt_name: vector<u8>,
usdt_symbol: vector<u8>
) {
let coin_admin = create_coin_admin();
let (coin1_burn_cap, coin1_freeze_cap, coin1_mint_cap) =
coin::initialize<BTC>(
&coin_admin,
utf8(btc_name),
utf8(btc_symbol),
6,
true
);
coin::destroy_mint_cap(coin1_mint_cap);
coin::destroy_burn_cap(coin1_burn_cap);
coin::destroy_freeze_cap(coin1_freeze_cap);

let (coin2_burn_cap, coin2_freeze_cap, coin2_mint_cap) =
coin::initialize<USDT>(
&coin_admin,
utf8(usdt_name),
utf8(usdt_symbol),
8,
true
);
coin::destroy_mint_cap(coin2_mint_cap);
coin::destroy_burn_cap(coin2_burn_cap);
coin::destroy_freeze_cap(coin2_freeze_cap);
}

fun generate_lp_name_and_symbol_for_coins<Curve>(): (String, String) {
coin_helper::generate_lp_name_and_symbol<BTC, USDT, Curve>()
}

#[test]
fun test_end_to_end() {
Expand Down Expand Up @@ -58,13 +95,47 @@ module liquidswap::coin_helper_tests {
}

#[test]
fun generate_lp_name() {
fun generate_lp_name_btc_usdt() {
genesis::setup();

test_coins::create_admin_with_coins();
register_coins_for_lp_names(
b"Bitcoin",
b"BTC",
b"Usdt",
b"USDT"
);
let (lp_name, lp_symbol) = generate_lp_name_and_symbol_for_coins<Uncorrelated>();
assert!(lp_name == utf8(b"LiquidLP-BTC-USDT-U"), 0);
assert!(lp_symbol == utf8(b"BTC-USDT"), 1);
}

#[test]
fun generate_lp_name_usdc_usdt() {
genesis::setup();

register_coins_for_lp_names(
b"USDC",
b"USDC",
b"USDT",
b"USDT"
);
let (lp_name, lp_symbol) = generate_lp_name_and_symbol_for_coins<Stable>();
assert!(lp_name == utf8(b"LiquidLP-USDC-USDT-S"), 0);
assert!(lp_symbol == utf8(b"USDC-USDT*"), 1);
}

#[test]
fun generate_lp_name_usdc_usdt_prefix() {
genesis::setup();

let (lp_name, lp_symbol) = coin_helper::generate_lp_name_and_symbol<BTC, USDT, Uncorrelated>();
assert!(lp_name == utf8(b"Liquidswap LP"), 0);
assert!(lp_symbol == utf8(b"LP-BTC-USDT-Uncorrelated"), 1);
register_coins_for_lp_names(
b"USDC",
b"USDCSymbol",
b"USDT",
b"USDTSymbol"
);
let (lp_name, lp_symbol) = generate_lp_name_and_symbol_for_coins<Stable>();
assert!(lp_name == utf8(b"LiquidLP-USDCSymbol-USDTSymbol-S"), 0);
assert!(lp_symbol == utf8(b"USDC-USDT*"), 1);
}
}
11 changes: 5 additions & 6 deletions tests/liquidity_pool_tests.move
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ module liquidswap::liquidity_pool_tests {
fun test_create_empty_pool_uncorrelated() {
let (_, lp_owner) = test_pool::setup_coins_and_lp_owner();

liquidity_pool::register<BTC, USDT, Uncorrelated>(
&lp_owner);
liquidity_pool::register<BTC, USDT, Uncorrelated>(&lp_owner);

assert!(liquidity_pool::is_pool_exists<BTC, USDT, Uncorrelated>(), 10);
assert!(coin::is_coin_initialized<LP<BTC, USDT, Uncorrelated>>(), 11);
Expand All @@ -56,9 +55,9 @@ module liquidswap::liquidity_pool_tests {
// Check created LP.
assert!(coin::is_coin_initialized<LP<BTC, USDT, Uncorrelated>>(), 17);
let lp_name = coin::name<LP<BTC, USDT, Uncorrelated>>();
assert!(lp_name == utf8(b"Liquidswap LP"), 18);
assert!(lp_name == utf8(b"LiquidLP-BTC-USDT-U"), 18);
let lp_symbol = coin::symbol<LP<BTC, USDT, Uncorrelated>>();
assert!(lp_symbol == utf8(b"LP"), 19);
assert!(lp_symbol == utf8(b"BTC-USDT"), 19);
let lp_supply = coin::supply<LP<BTC, USDT, Uncorrelated>>();
assert!(option::is_some(&lp_supply), 20);
assert!(*option::borrow(&lp_supply) == 0, 21);
Expand Down Expand Up @@ -102,9 +101,9 @@ module liquidswap::liquidity_pool_tests {

assert!(coin::is_coin_initialized<LP<USDC, USDT, Stable>>(), 4);
let lp_name = coin::name<LP<USDC, USDT, Stable>>();
assert!(lp_name == utf8(b"Liquidswap LP"), 6);
assert!(lp_name == utf8(b"LiquidLP-USDC-USDT-S"), 6);
let lp_symbol = coin::symbol<LP<USDC, USDT, Stable>>();
assert!(lp_symbol == utf8(b"LP"), 7);
assert!(lp_symbol == utf8(b"USDC-USDT*"), 7);
let lp_supply = coin::supply<LP<USDC, USDT, Stable>>();
assert!(option::is_some(&lp_supply), 8);

Expand Down

0 comments on commit 1d4d3b6

Please sign in to comment.