Skip to content

Commit

Permalink
Fix liquidity incentive (#3218)
Browse files Browse the repository at this point in the history
* fix: add end time for liquidity incentive

* fix: remove unuse import

* fix: withdraw incentive

* fix: modify endtime when update reward coin

* update fee rate

* Add admin_cap parameter to update_fee_rate function

---------

Co-authored-by: jolestar <jolestar@gmail.com>
  • Loading branch information
mx819812523 and jolestar authored Jan 21, 2025
1 parent 48ce3d2 commit d722771
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 50 deletions.
74 changes: 49 additions & 25 deletions apps/rooch_dex/sources/router.move
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module rooch_dex::router {
use rooch_dex::swap;
use std::signer;
use std::signer::address_of;
use rooch_dex::swap::LPToken;
use rooch_dex::swap::{LPToken, borrow_fee_rate};
use rooch_framework::account_coin_store;
use rooch_framework::coin;
use rooch_dex::swap_utils;
Expand Down Expand Up @@ -129,12 +129,14 @@ module rooch_dex::router {
) {
assert_token_pair_created<X, Y>();
let x_in = if (swap_utils::sort_token_type<X, Y>()) {
let fee_rate = borrow_fee_rate<X, Y>();
let (rin, rout, _) = swap::token_reserves<X, Y>();
let amount_in = swap_utils::get_amount_in(y_out, rin, rout);
let amount_in = swap_utils::get_amount_in(y_out, rin, rout, fee_rate);
swap::swap_x_to_exact_y<X, Y>(sender, amount_in, y_out, signer::address_of(sender))
} else {
let fee_rate = borrow_fee_rate<Y, X>();
let (rout, rin, _) = swap::token_reserves<Y, X>();
let amount_in = swap_utils::get_amount_in(y_out, rin, rout);
let amount_in = swap_utils::get_amount_in(y_out, rin, rout, fee_rate);
swap::swap_y_to_exact_x<Y, X>(sender, amount_in, y_out, signer::address_of(sender))
};
assert!(x_in <= x_max_in, ErrorInsufficientInputAmount);
Expand Down Expand Up @@ -179,21 +181,25 @@ module rooch_dex::router {

fun get_amount_in_internal<X:key+store, Y:key+store>(is_x_to_y:bool, y_out_amount: u64): u64 {
if (is_x_to_y) {
let fee_rate = borrow_fee_rate<X, Y>();
let (rin, rout, _) = swap::token_reserves<X, Y>();
swap_utils::get_amount_in(y_out_amount, rin, rout)
swap_utils::get_amount_in(y_out_amount, rin, rout, fee_rate)
} else {
let fee_rate = borrow_fee_rate<Y, X>();
let (rout, rin, _) = swap::token_reserves<Y, X>();
swap_utils::get_amount_in(y_out_amount, rin, rout)
swap_utils::get_amount_in(y_out_amount, rin, rout, fee_rate)
}
}

fun get_amount_out_internal<X:key+store, Y:key+store>(is_x_to_y:bool, x_in_amount: u64): u64 {
if (is_x_to_y) {
let fee_rate = borrow_fee_rate<X, Y>();
let (rin, rout, _) = swap::token_reserves<X, Y>();
swap_utils::get_amount_out(x_in_amount, rin, rout)
swap_utils::get_amount_out(x_in_amount, rin, rout, fee_rate)
} else {
let fee_rate = borrow_fee_rate<Y, X>();
let (rout, rin, _) = swap::token_reserves<Y, X>();
swap_utils::get_amount_out(x_in_amount, rin, rout)
swap_utils::get_amount_out(x_in_amount, rin, rout, fee_rate)
}
}

Expand Down Expand Up @@ -269,18 +275,22 @@ module rooch_dex::router {
let rin;
let rout;
let y_out = if (second_is_y_to_z) {
let fee_rate = borrow_fee_rate<Y, Z>();
(rin, rout, _) = swap::token_reserves<Y, Z>();
swap_utils::get_amount_in(z_out, rin, rout)
swap_utils::get_amount_in(z_out, rin, rout, fee_rate)
}else {
let fee_rate = borrow_fee_rate<Z, Y>();
(rout, rin, _) = swap::token_reserves<Z, Y>();
swap_utils::get_amount_in(z_out, rin, rout)
swap_utils::get_amount_in(z_out, rin, rout, fee_rate)
};
let x_in = if (first_is_x_to_y) {
let fee_rate = borrow_fee_rate<X, Y>();
(rin, rout, _) = swap::token_reserves<X, Y>();
swap_utils::get_amount_in(y_out, rin, rout)
swap_utils::get_amount_in(y_out, rin, rout, fee_rate)
}else {
let fee_rate = borrow_fee_rate<Y, X>();
(rout, rin, _) = swap::token_reserves<Y, X>();
swap_utils::get_amount_in(y_out, rin, rout)
swap_utils::get_amount_in(y_out, rin, rout, fee_rate)
};

assert!(x_in <= x_max_in, ErrorInsufficientInputAmount);
Expand Down Expand Up @@ -371,26 +381,32 @@ module rooch_dex::router {
let rin;
let rout;
let z_out = if (third_is_z_to_a) {
let fee_rate = borrow_fee_rate<Z, A>();
(rin, rout, _) = swap::token_reserves<Z, A>();
swap_utils::get_amount_in(a_out, rin, rout)
swap_utils::get_amount_in(a_out, rin, rout, fee_rate)
}else {
let fee_rate = borrow_fee_rate<A, Z>();
(rout, rin, _) = swap::token_reserves<A, Z>();
swap_utils::get_amount_in(a_out, rin, rout)
swap_utils::get_amount_in(a_out, rin, rout, fee_rate)
};

let y_out = if (second_is_y_to_z) {
let fee_rate = borrow_fee_rate<Y, Z>();
(rin, rout, _) = swap::token_reserves<Y, Z>();
swap_utils::get_amount_in(z_out, rin, rout)
swap_utils::get_amount_in(z_out, rin, rout, fee_rate)
}else {
let fee_rate = borrow_fee_rate<Z, Y>();
(rout, rin, _) = swap::token_reserves<Z, Y>();
swap_utils::get_amount_in(z_out, rin, rout)
swap_utils::get_amount_in(z_out, rin, rout, fee_rate)
};
let x_in = if (first_is_x_to_y) {
let fee_rate = borrow_fee_rate<X, Y>();
(rin, rout, _) = swap::token_reserves<X, Y>();
swap_utils::get_amount_in(y_out, rin, rout)
swap_utils::get_amount_in(y_out, rin, rout, fee_rate)
}else {
let fee_rate = borrow_fee_rate<Y, X>();
(rout, rin, _) = swap::token_reserves<Y, X>();
swap_utils::get_amount_in(y_out, rin, rout)
swap_utils::get_amount_in(y_out, rin, rout, fee_rate)
};

assert!(x_in <= x_max_in, ErrorInsufficientInputAmount);
Expand Down Expand Up @@ -496,34 +512,42 @@ module rooch_dex::router {
let rout;

let a_out = if (fourth_is_a_to_b) {
let fee_rate = borrow_fee_rate<A, B>();
(rin, rout, _) = swap::token_reserves<A, B>();
swap_utils::get_amount_in(b_out, rin, rout)
swap_utils::get_amount_in(b_out, rin, rout, fee_rate)
}else {
let fee_rate = borrow_fee_rate<B, A>();
(rout, rin, _) = swap::token_reserves<B, A>();
swap_utils::get_amount_in(b_out, rin, rout)
swap_utils::get_amount_in(b_out, rin, rout, fee_rate)
};

let z_out = if (third_is_z_to_a) {
let fee_rate = borrow_fee_rate<Z, A>();
(rin, rout, _) = swap::token_reserves<Z, A>();
swap_utils::get_amount_in(a_out, rin, rout)
swap_utils::get_amount_in(a_out, rin, rout, fee_rate)
}else {
let fee_rate = borrow_fee_rate<A, Z>();
(rout, rin, _) = swap::token_reserves<A, Z>();
swap_utils::get_amount_in(a_out, rin, rout)
swap_utils::get_amount_in(a_out, rin, rout, fee_rate)
};

let y_out = if (second_is_y_to_z) {
let fee_rate = borrow_fee_rate<Y, Z>();
(rin, rout, _) = swap::token_reserves<Y, Z>();
swap_utils::get_amount_in(z_out, rin, rout)
swap_utils::get_amount_in(z_out, rin, rout, fee_rate)
}else {
let fee_rate = borrow_fee_rate<Z, Y>();
(rout, rin, _) = swap::token_reserves<Z, Y>();
swap_utils::get_amount_in(z_out, rin, rout)
swap_utils::get_amount_in(z_out, rin, rout, fee_rate)
};
let x_in = if (first_is_x_to_y) {
let fee_rate = borrow_fee_rate<X, Y>();
(rin, rout, _) = swap::token_reserves<X, Y>();
swap_utils::get_amount_in(y_out, rin, rout)
swap_utils::get_amount_in(y_out, rin, rout, fee_rate)
}else {
let fee_rate = borrow_fee_rate<Y, X>();
(rout, rin, _) = swap::token_reserves<Y, X>();
swap_utils::get_amount_in(y_out, rin, rout)
swap_utils::get_amount_in(y_out, rin, rout, fee_rate)
};

assert!(x_in <= x_max_in, ErrorInsufficientInputAmount);
Expand Down
40 changes: 19 additions & 21 deletions apps/rooch_dex/sources/swap.move
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module rooch_dex::swap {
use std::option::none;
use std::string;
use std::u128;
use app_admin::admin;
use app_admin::admin::AdminCap;
use moveos_std::timestamp;
use moveos_std::account::borrow_mut_resource;
use rooch_dex::swap_utils;
Expand All @@ -12,7 +12,6 @@ module rooch_dex::swap {
use moveos_std::type_info;
use rooch_framework::coin;
use moveos_std::signer::module_signer;
use moveos_std::tx_context::sender;
use moveos_std::object;
use moveos_std::account;
use rooch_framework::coin::{CoinInfo, symbol_by_type, supply_by_type};
Expand Down Expand Up @@ -101,22 +100,8 @@ module rooch_dex::swap {
amount_y_out: u64
}

struct RoochDexCap has key {}

fun init() {
object::transfer_extend(object::new_named_object(RoochDexCap{}), sender())
}


public entry fun create_admin(_admin: &mut Object<admin::AdminCap>, receiver: address){
let new_admin = object::new(RoochDexCap{});
object::transfer_extend(new_admin, receiver)
}

public entry fun delete_admin(_admin: &mut Object<admin::AdminCap>, admin_id: ObjectID){
let admin_obj = object::take_object_extend<RoochDexCap>(admin_id);
let RoochDexCap{} = object::remove(admin_obj);
}

/// Create the specified coin pair
public(friend) fun create_pair<X:key+store, Y:key+store>(
Expand All @@ -125,7 +110,7 @@ module rooch_dex::swap {
assert!(!is_pair_created<X, Y>(), ErrorAlreadyExists);

let sender_addr = signer::address_of(sender);
let resource_signer = module_signer<RoochDexCap>();
let resource_signer = module_signer<TokenPair<X, Y>>();

let lp_name: string::String = string::utf8(b"RoochDex-");
let name_x = symbol_by_type<X>();
Expand Down Expand Up @@ -359,10 +344,11 @@ module rooch_dex::swap {
public(friend) fun swap_exact_x_to_y_direct<X:key+store, Y:key+store>(
coins_in: coin::Coin<X>
): (coin::Coin<X>, coin::Coin<Y>){
let fee_rate = borrow_fee_rate<X, Y>();
let amount_in = coin::value<X>(&coins_in);
deposit_x<X, Y>(coins_in);
let (rin, rout, _) = token_reserves<X, Y>();
let amount_out = swap_utils::get_amount_out((amount_in as u64), rin, rout);
let amount_out = swap_utils::get_amount_out((amount_in as u64), rin, rout, fee_rate);
let (coins_x_out, coins_y_out) = swap<X, Y>(0, amount_out);
assert!(coin::value<X>(&coins_x_out) == 0, ErrorOutputTokenAmount);
(coins_x_out, coins_y_out)
Expand Down Expand Up @@ -430,10 +416,11 @@ module rooch_dex::swap {
public(friend) fun swap_exact_y_to_x_direct<X:key+store, Y:key+store>(
coins_in: coin::Coin<Y>
): (coin::Coin<X>, coin::Coin<Y>) {
let fee_rate = borrow_fee_rate<X, Y>();
let amount_in = coin::value<Y>(&coins_in);
deposit_y<X, Y>(coins_in);
let (rout, rin, _) = token_reserves<X, Y>();
let amount_out = swap_utils::get_amount_out((amount_in as u64), rin, rout);
let amount_out = swap_utils::get_amount_out((amount_in as u64), rin, rout, fee_rate);
let (coins_x_out, coins_y_out) = swap<X, Y>(amount_out, 0);
assert!(coin::value<Y>(&coins_y_out) == 0, ErrorOutputTokenAmount);
(coins_x_out, coins_y_out)
Expand Down Expand Up @@ -614,7 +601,7 @@ module rooch_dex::swap {
fee
}

public entry fun withdraw_fee<X:key+store, Y:key+store>(admin_cap: &mut Object<RoochDexCap>){
public entry fun withdraw_fee<X:key+store, Y:key+store>(admin_cap: &mut Object<AdminCap>){
if (swap_utils::sort_token_type<X, Y>()) {
let token_pair_obj = object::borrow_mut_object_shared<TokenPair<X, Y>>(named_object_id<TokenPair<X, Y>>());
let token_pair = object::borrow_mut<TokenPair<X, Y>>(token_pair_obj);
Expand All @@ -632,7 +619,7 @@ module rooch_dex::swap {
};
}

public entry fun update_token_pair_status<X:key+store, Y:key+store>(_admin_cap: &mut Object<RoochDexCap>, status: bool){
public entry fun update_token_pair_status<X:key+store, Y:key+store>(_admin_cap: &mut Object<AdminCap>, status: bool){
if (swap_utils::sort_token_type<X, Y>()) {
let token_pair_obj = object::borrow_mut_object_shared<TokenPair<X, Y>>(named_object_id<TokenPair<X, Y>>());
let token_pair = object::borrow_mut<TokenPair<X, Y>>(token_pair_obj);
Expand All @@ -644,6 +631,17 @@ module rooch_dex::swap {
};
}

public entry fun update_fee_rate<X:key+store, Y:key+store>(_admin_cap: &mut Object<AdminCap>, fee_rate: u64){
let token_pair_obj = object::borrow_mut_object_shared<TokenPair<X, Y>>(named_object_id<TokenPair<X, Y>>());
let token_pair = object::borrow_mut<TokenPair<X, Y>>(token_pair_obj);
token_pair.fee_rate = fee_rate
}

public fun borrow_fee_rate<X:key+store, Y:key+store>() : u64{
let token_pair_obj = object::borrow_object<TokenPair<X, Y>>(named_object_id<TokenPair<X, Y>>());
object::borrow<TokenPair<X, Y>>(token_pair_obj).fee_rate
}

#[test_only]
struct TestCoinX has key, store{}
#[test_only]
Expand Down
10 changes: 6 additions & 4 deletions apps/rooch_dex/sources/swap_utils.move
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ module rooch_dex::swap_utils {
public fun get_amount_out(
amount_in: u64,
reserve_in: u64,
reserve_out: u64
reserve_out: u64,
fee_rate: u64,
): u64 {
assert!(amount_in > 0, ErrorInputTokenAmount);
assert!(reserve_in > 0 && reserve_out > 0, ErrorInsufficientLiquidity);

let amount_in_with_fee = (amount_in as u128) * 9975u128;
let amount_in_with_fee = (amount_in as u128) * (fee_rate as u128);
let numerator = amount_in_with_fee * (reserve_out as u128);
let denominator = (reserve_in as u128) * 10000u128 + amount_in_with_fee;
((numerator / denominator) as u64)
Expand All @@ -32,13 +33,14 @@ module rooch_dex::swap_utils {
public fun get_amount_in(
amount_out: u64,
reserve_in: u64,
reserve_out: u64
reserve_out: u64,
fee_rate: u64
): u64 {
assert!(amount_out > 0, ErrorOutputTokenAmount);
assert!(reserve_in > 0 && reserve_out > 0, ErrorInsufficientLiquidity);

let numerator = (reserve_in as u128) * (amount_out as u128) * 10000u128;
let denominator = ((reserve_out as u128) - (amount_out as u128)) * 9975u128;
let denominator = ((reserve_out as u128) - (amount_out as u128)) * (fee_rate as u128);
(((numerator / denominator) as u64) + 1u64)
}

Expand Down

0 comments on commit d722771

Please sign in to comment.