Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add initial liq hook #819

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions dex/pair/src/pair_actions/add_liq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,16 @@ pub trait AddLiquidityModule:
);
self.set_optimal_amounts(&mut add_liq_context, &storage_cache);

add_liq_context.liq_added = if storage_cache.lp_token_supply == 0u64 {
self.pool_add_initial_liquidity(
&add_liq_context.first_token_optimal_amount,
&add_liq_context.second_token_optimal_amount,
&mut storage_cache,
)
} else {
self.pool_add_liquidity(
&add_liq_context.first_token_optimal_amount,
&add_liq_context.second_token_optimal_amount,
&mut storage_cache,
)
};
require!(
storage_cache.lp_token_supply > 0,
"Add initial liquidity first"
);

add_liq_context.liq_added = self.pool_add_liquidity(
&add_liq_context.first_token_optimal_amount,
&add_liq_context.second_token_optimal_amount,
&mut storage_cache,
);

let new_k = self.calculate_k_constant(
&storage_cache.first_token_reserve,
Expand Down
34 changes: 31 additions & 3 deletions dex/pair/src/pair_actions/initial_liq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use common_errors::ERROR_PERMISSION_DENIED;
use pausable::State;

use crate::{
contexts::add_liquidity::AddLiquidityContext, StorageCache, ERROR_ACTIVE,
ERROR_BAD_PAYMENT_TOKENS, ERROR_INITIAL_LIQUIDITY_ALREADY_ADDED,
contexts::add_liquidity::AddLiquidityContext, pair_hooks::hook_type::HookType, StorageCache,
ERROR_ACTIVE, ERROR_BAD_PAYMENT_TOKENS, ERROR_INITIAL_LIQUIDITY_ALREADY_ADDED,
};

use super::common_result_types::AddLiquidityResultType;
Expand All @@ -22,6 +22,10 @@ pub trait InitialLiquidityModule:
+ permissions_module::PermissionsModule
+ pausable::PausableModule
+ super::common_methods::CommonMethodsModule
+ crate::pair_hooks::banned_address::BannedAddressModule
+ crate::pair_hooks::change_hooks::ChangeHooksModule
+ crate::pair_hooks::call_hook::CallHookModule
+ utils::UtilsModule
{
#[payable("*")]
#[endpoint(addInitialLiquidity)]
Expand Down Expand Up @@ -54,6 +58,19 @@ pub trait InitialLiquidityModule:
ERROR_INITIAL_LIQUIDITY_ALREADY_ADDED
);

let mut payments_vec = ManagedVec::new();
payments_vec.push(first_payment);
payments_vec.push(second_payment);

let payments_after_hook = self.call_hook(
HookType::BeforeAddInitialLiq,
caller.clone(),
payments_vec,
ManagedVec::new(),
);
let first_payment = payments_after_hook.get(0);
let second_payment = payments_after_hook.get(1);

let first_token_optimal_amount = &first_payment.amount;
let second_token_optimal_amount = &second_payment.amount;
let liq_added = self.pool_add_initial_liquidity(
Expand All @@ -64,8 +81,19 @@ pub trait InitialLiquidityModule:

self.send()
.esdt_local_mint(&storage_cache.lp_token_id, 0, &liq_added);

let mut lp_payment =
EsdtTokenPayment::new(storage_cache.lp_token_id.clone(), 0, liq_added.clone());
let lp_payment_after_hook = self.call_hook(
HookType::AfterAddInitialLiq,
caller.clone(),
ManagedVec::from_single_item(lp_payment),
ManagedVec::new(),
);
lp_payment = lp_payment_after_hook.get(0);

self.send()
.direct_esdt(&caller, &storage_cache.lp_token_id, 0, &liq_added);
.direct_non_zero_esdt_payment(&caller, &lp_payment);

self.state().set(State::PartialActive);

Expand Down
5 changes: 5 additions & 0 deletions dex/pair/src/pair_hooks/call_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub trait CallHookModule {
return input_payments;
}

let payments_len = input_payments.len();
let mut call_args = ManagedArgBuffer::new();
call_args.push_arg(caller);

Expand All @@ -37,6 +38,10 @@ pub trait CallHookModule {
.execute_on_dest_context_with_back_transfers::<MultiValueEncoded<ManagedBuffer>>();

output_payments = back_transfers.esdt_payments;
require!(
output_payments.len() == payments_len,
"Wrong payments received from SC"
);
}

output_payments
Expand Down
60 changes: 21 additions & 39 deletions dex/pair/tests/pair_rs_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,15 @@ fn test_pair_setup() {
fn test_add_liquidity() {
let mut pair_setup = PairSetup::new(pair::contract_obj);

pair_setup.add_liquidity(
1_001_000, 1_000_000, 1_001_000, 1_000_000, 1_000_000, 1_001_000, 1_001_000,
);
pair_setup.add_initial_liquidity(1_001_000, 1_001_000, 1_000_000, 1_001_000, 1_001_000);
}

#[test]
fn test_swap_fixed_input() {
let mut pair_setup = PairSetup::new(pair::contract_obj);

pair_setup.add_liquidity(
1_001_000, 1_000_000, 1_001_000, 1_000_000, 1_000_000, 1_001_000, 1_001_000,
);
pair_setup.add_initial_liquidity(1_001_000, 1_001_000, 1_000_000, 1_001_000, 1_001_000);
pair_setup.set_state_active();

pair_setup.swap_fixed_input(WEGLD_TOKEN_ID, 1_000, MEX_TOKEN_ID, 900, 996);
}
Expand All @@ -53,9 +50,8 @@ fn test_swap_fixed_input() {
fn test_swap_fixed_output() {
let mut pair_setup = PairSetup::new(pair::contract_obj);

pair_setup.add_liquidity(
1_001_000, 1_000_000, 1_001_000, 1_000_000, 1_000_000, 1_001_000, 1_001_000,
);
pair_setup.add_initial_liquidity(1_001_000, 1_001_000, 1_000_000, 1_001_000, 1_001_000);
pair_setup.set_state_active();

pair_setup.swap_fixed_output(WEGLD_TOKEN_ID, 1_000, MEX_TOKEN_ID, 900, 96);
}
Expand All @@ -75,15 +71,10 @@ fn test_safe_price() {
let mut second_token_reserve = 1_000_004;
let mut first_token_accumulated = 1_001_000;
let mut second_token_accumulated = 1_001_000;
pair_setup.add_liquidity(
1_001_000,
1_000_000,
1_001_000,
1_000_000,
1_000_000,
first_token_accumulated,
second_token_accumulated,
);

pair_setup.add_initial_liquidity(1_001_000, 1_001_000, 1_000_000, 1_001_000, 1_001_000);
pair_setup.set_state_active();

pair_setup.swap_fixed_input(
WEGLD_TOKEN_ID,
payment_amount,
Expand Down Expand Up @@ -431,15 +422,14 @@ fn test_safe_price_linear_interpolation() {
let mut first_token_accumulated = weight * first_token_reserve;
let mut second_token_accumulated = weight * second_token_reserve;

pair_setup.add_liquidity(
first_token_reserve,
pair_setup.add_initial_liquidity(
first_token_reserve,
second_token_reserve,
first_token_reserve,
first_token_reserve - min_pool_reserve,
first_token_reserve,
second_token_reserve,
);
pair_setup.set_state_active();

// Initial price ~ 30
let mut first_token_payment_amount = 1_000;
Expand Down Expand Up @@ -626,15 +616,10 @@ fn test_both_legacy_and_new_safe_price_from_other_contract() {
let mut second_token_reserve = 1_000_004;
let mut first_token_accumulated = 1_001_000;
let mut second_token_accumulated = 1_001_000;
pair_setup.add_liquidity(
1_001_000,
1_000_000,
1_001_000,
1_000_000,
1_000_000,
first_token_accumulated,
second_token_accumulated,
);

pair_setup.add_initial_liquidity(1_001_000, 1_001_000, 1_000_000, 1_001_000, 1_001_000);
pair_setup.set_state_active();

pair_setup.swap_fixed_input(
WEGLD_TOKEN_ID,
payment_amount,
Expand Down Expand Up @@ -888,9 +873,8 @@ fn test_both_legacy_and_new_safe_price_from_other_contract() {
fn test_locked_asset() {
let mut pair_setup = PairSetup::new(pair::contract_obj);

pair_setup.add_liquidity(
1_001_000, 1_000_000, 1_001_000, 1_000_000, 1_000_000, 1_001_000, 1_001_000,
);
pair_setup.add_initial_liquidity(1_001_000, 1_001_000, 1_000_000, 1_001_000, 1_001_000);
pair_setup.set_state_active();

// init locking SC
let rust_zero = rust_biguint!(0);
Expand Down Expand Up @@ -1018,9 +1002,8 @@ fn test_locked_asset() {
fn add_liquidity_through_simple_lock_proxy() {
let mut pair_setup = PairSetup::new(pair::contract_obj);

pair_setup.add_liquidity(
1_001_000, 1_000_000, 1_001_000, 1_000_000, 1_000_000, 1_001_000, 1_001_000,
);
pair_setup.add_initial_liquidity(1_001_000, 1_001_000, 1_000_000, 1_001_000, 1_001_000);
pair_setup.set_state_active();

// init locking SC
let lp_address = pair_setup.pair_wrapper.address_ref().clone();
Expand Down Expand Up @@ -1373,9 +1356,8 @@ fn fees_collector_pair_test() {
)
.assert_ok();

pair_setup.add_liquidity(
1_001_000, 1_000_000, 1_001_000, 1_000_000, 1_000_000, 1_001_000, 1_001_000,
);
pair_setup.add_initial_liquidity(1_001_000, 1_001_000, 1_000_000, 1_001_000, 1_001_000);
pair_setup.set_state_active();

pair_setup.swap_fixed_input(WEGLD_TOKEN_ID, 100_000, MEX_TOKEN_ID, 900, 90_669);

Expand Down
26 changes: 16 additions & 10 deletions dex/pair/tests/pair_setup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub const USER_TOTAL_MEX_TOKENS: u64 = 5_000_000_000;
pub const USER_TOTAL_WEGLD_TOKENS: u64 = 5_000_000_000;

use pair::config::ConfigModule as PairConfigModule;
use pair::pair_actions::add_liq::AddLiquidityModule;
use pair::pair_actions::initial_liq::InitialLiquidityModule;
use pair::pair_actions::swap::SwapModule;
use pair::safe_price_view::*;
use pair::*;
Expand Down Expand Up @@ -74,8 +74,6 @@ where

let lp_token_id = managed_token_id!(LP_TOKEN_ID);
sc.lp_token_identifier().set(&lp_token_id);

sc.state().set(State::Active);
})
.assert_ok();

Expand Down Expand Up @@ -130,13 +128,24 @@ where
}
}

pub fn set_state_active(&mut self) {
self.b_mock
.execute_tx(
&self.owner_address,
&self.pair_wrapper,
&rust_biguint!(0),
|sc| {
sc.state().set(State::Active);
},
)
.assert_ok();
}

#[allow(clippy::too_many_arguments)]
pub fn add_liquidity(
pub fn add_initial_liquidity(
&mut self,
first_token_amount: u64,
first_token_min: u64,
second_token_amount: u64,
second_token_min: u64,
expected_lp_amount: u64,
expected_first_amount: u64,
expected_second_amount: u64,
Expand All @@ -156,10 +165,7 @@ where

self.b_mock
.execute_esdt_multi_transfer(&self.user_address, &self.pair_wrapper, &payments, |sc| {
let MultiValue3 { 0: payments } = sc.add_liquidity(
managed_biguint!(first_token_min),
managed_biguint!(second_token_min),
);
let MultiValue3 { 0: payments } = sc.add_initial_liquidity();

assert_eq!(payments.0.token_identifier, managed_token_id!(LP_TOKEN_ID));
assert_eq!(payments.0.token_nonce, 0);
Expand Down
26 changes: 21 additions & 5 deletions dex/scenarios/add_liquidity.scen.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,8 @@
"value": "2,000,000,000"
}
],
"function": "addLiquidity",
"arguments": [
"1,000,000,000",
"1,000,000,000"
],
"function": "addInitialLiquidity",
"arguments": [],
"gasLimit": "100,000,000",
"gasPrice": "0"
},
Expand All @@ -40,6 +37,25 @@
"gas": "*",
"refund": "*"
}
},
{
"step": "scCall",
"txId": "resume",
"tx": {
"from": "address:owner",
"to": "sc:pair_contract",
"function": "resume",
"arguments": [],
"gasLimit": "100,000,000",
"gasPrice": "0"
},
"expect": {
"out": [],
"status": "0",
"message": "",
"gas": "*",
"refund": "*"
}
}
]
}
28 changes: 22 additions & 6 deletions dex/scenarios/check_fee_disabled_after_swap.scen.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,8 @@
"value": "2,000,000,000"
}
],
"function": "addLiquidity",
"arguments": [
"1,000,000,000",
"1,000,000,000"
],
"function": "addInitialLiquidity",
"arguments": [],
"gasLimit": "100,000,000",
"gasPrice": "0"
},
Expand All @@ -45,6 +42,25 @@
"refund": "*"
}
},
{
"step": "scCall",
"txId": "resume",
"tx": {
"from": "address:owner",
"to": "sc:pair_contract",
"function": "resume",
"arguments": [],
"gasLimit": "100,000,000",
"gasPrice": "0"
},
"expect": {
"out": [],
"status": "0",
"message": "",
"gas": "*",
"refund": "*"
}
},
{
"step": "checkState",
"accounts": {
Expand Down Expand Up @@ -85,4 +101,4 @@
}
}
]
}
}
2 changes: 1 addition & 1 deletion dex/scenarios/steps/hackish.steps.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"storage": {
"str:first_token_id": "str:WEGLD-abcdef",
"str:second_token_id": "str:ALC-abcdef",
"str:state": "1",
"str:state": "0",
"str:lpTokenIdentifier": "str:LPTOK-abcdef",
"str:router_address": "sc:router_contract",
"str:router_owner_address": "address:owner",
Expand Down
Loading
Loading