Skip to content

Commit

Permalink
Merge pull request #821 from multiversx/hooks-again
Browse files Browse the repository at this point in the history
implement all hooks
  • Loading branch information
dorin-iancu authored Jan 31, 2024
2 parents ec6e161 + 6508d65 commit 8474c5e
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ jobs:
uses: multiversx/mx-sc-actions/.github/workflows/[email protected]
with:
rust-toolchain: nightly-2023-12-11
vmtools-version: v1.4.60
vmtools-version: v1.5.24
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
5 changes: 0 additions & 5 deletions dex/pair/src/contexts/output_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ pub trait OutputBuilderModule:
) -> ManagedVec<EsdtTokenPayment<Self::Api>> {
let mut payments: ManagedVec<EsdtTokenPayment<Self::Api>> = ManagedVec::new();

payments.push(EsdtTokenPayment::new(
storage_cache.lp_token_id.clone(),
0,
add_liq_context.liq_added.clone(),
));
payments.push(EsdtTokenPayment::new(
storage_cache.first_token_id.clone(),
0,
Expand Down
46 changes: 42 additions & 4 deletions dex/pair/src/pair_actions/add_liq.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
contexts::add_liquidity::AddLiquidityContext, StorageCache, ERROR_BAD_PAYMENT_TOKENS,
ERROR_INITIAL_LIQUIDITY_NOT_ADDED, ERROR_INVALID_ARGS, ERROR_K_INVARIANT_FAILED,
ERROR_LP_TOKEN_NOT_ISSUED, ERROR_NOT_ACTIVE,
contexts::add_liquidity::AddLiquidityContext, pair_hooks::hook_type::HookType, StorageCache,
ERROR_BAD_PAYMENT_TOKENS, ERROR_INITIAL_LIQUIDITY_NOT_ADDED, ERROR_INVALID_ARGS,
ERROR_K_INVARIANT_FAILED, ERROR_LP_TOKEN_NOT_ISSUED, ERROR_NOT_ACTIVE,
};

use super::common_result_types::AddLiquidityResultType;
Expand All @@ -21,6 +21,10 @@ pub trait AddLiquidityModule:
+ 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(addLiquidity)]
Expand Down Expand Up @@ -61,6 +65,24 @@ pub trait AddLiquidityModule:
ERROR_INITIAL_LIQUIDITY_NOT_ADDED
);

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

let mut args = ManagedVec::new();
self.encode_arg_to_vec(&first_token_amount_min, &mut args);
self.encode_arg_to_vec(&second_token_amount_min, &mut args);

let (hook_type_before, hook_type_after) = if storage_cache.lp_token_supply == 0 {
(HookType::BeforeAddInitialLiq, HookType::AfterAddInitialLiq)
} else {
(HookType::BeforeAddLiq, HookType::AfterAddLiq)
};
let payments_after_hook =
self.call_hook(hook_type_before, caller.clone(), payments_vec, args.clone());
let first_payment = payments_after_hook.get(0);
let second_payment = payments_after_hook.get(1);

self.update_safe_price(
&storage_cache.first_token_reserve,
&storage_cache.second_token_reserve,
Expand Down Expand Up @@ -102,7 +124,23 @@ pub trait AddLiquidityModule:
self.send()
.esdt_local_mint(&storage_cache.lp_token_id, 0, &add_liq_context.liq_added);

let output_payments = self.build_add_liq_output_payments(&storage_cache, &add_liq_context);
let mut lp_payment = EsdtTokenPayment::new(
storage_cache.lp_token_id.clone(),
0,
add_liq_context.liq_added.clone(),
);
let lp_payment_after_hook = self.call_hook(
hook_type_after,
caller.clone(),
ManagedVec::from_single_item(lp_payment),
args,
);
lp_payment = lp_payment_after_hook.get(0);

let mut output_payments =
self.build_add_liq_output_payments(&storage_cache, &add_liq_context);
output_payments.push(lp_payment);

self.send_multiple_tokens_if_not_zero(&caller, &output_payments);

let output = self.build_add_liq_results(&storage_cache, &add_liq_context);
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
33 changes: 28 additions & 5 deletions dex/pair/src/pair_actions/remove_liq.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
contexts::remove_liquidity::RemoveLiquidityContext, StorageCache, SwapTokensOrder,
ERROR_BAD_PAYMENT_TOKENS, ERROR_INVALID_ARGS, ERROR_K_INVARIANT_FAILED,
ERROR_LP_TOKEN_NOT_ISSUED, ERROR_NOT_ACTIVE, ERROR_NOT_WHITELISTED,
contexts::remove_liquidity::RemoveLiquidityContext, pair_hooks::hook_type::HookType,
StorageCache, SwapTokensOrder, ERROR_BAD_PAYMENT_TOKENS, ERROR_INVALID_ARGS,
ERROR_K_INVARIANT_FAILED, ERROR_LP_TOKEN_NOT_ISSUED, ERROR_NOT_ACTIVE, ERROR_NOT_WHITELISTED,
};

use super::common_result_types::RemoveLiquidityResultType;
Expand All @@ -22,6 +22,10 @@ pub trait RemoveLiquidityModule:
+ 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(removeLiquidity)]
Expand Down Expand Up @@ -62,6 +66,18 @@ pub trait RemoveLiquidityModule:
&storage_cache.second_token_reserve,
);

let mut args = ManagedVec::new();
self.encode_arg_to_vec(&first_token_amount_min, &mut args);
self.encode_arg_to_vec(&second_token_amount_min, &mut args);

let payments_after_hook = self.call_hook(
HookType::BeforeRemoveLiq,
caller.clone(),
ManagedVec::from_single_item(payment),
args.clone(),
);
let payment = payments_after_hook.get(0);

let mut remove_liq_context = RemoveLiquidityContext::new(
payment.amount,
first_token_amount_min,
Expand All @@ -82,11 +98,18 @@ pub trait RemoveLiquidityModule:

let output_payments =
self.build_remove_liq_output_payments(&storage_cache, &remove_liq_context);
self.send_multiple_tokens_if_not_zero(&caller, &output_payments);
let output_payments_after_hook = self.call_hook(
HookType::AfterRemoveLiq,
caller.clone(),
output_payments,
args,
);

self.send_multiple_tokens_if_not_zero(&caller, &output_payments_after_hook);

self.emit_remove_liquidity_event(&storage_cache, remove_liq_context);

self.build_remove_liq_results(output_payments)
self.build_remove_liq_results(output_payments_after_hook)
}

#[payable("*")]
Expand Down
88 changes: 68 additions & 20 deletions dex/pair/src/pair_actions/swap.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
use crate::{
contexts::swap::SwapContext, StorageCache, ERROR_INVALID_ARGS, ERROR_K_INVARIANT_FAILED,
ERROR_NOT_ENOUGH_RESERVE, ERROR_NOT_WHITELISTED, ERROR_SLIPPAGE_EXCEEDED,
ERROR_SWAP_NOT_ENABLED, ERROR_ZERO_AMOUNT,
contexts::swap::SwapContext, pair_hooks::hook_type::HookType, StorageCache, ERROR_INVALID_ARGS,
ERROR_K_INVARIANT_FAILED, ERROR_NOT_ENOUGH_RESERVE, ERROR_NOT_WHITELISTED,
ERROR_SLIPPAGE_EXCEEDED, ERROR_SWAP_NOT_ENABLED, ERROR_ZERO_AMOUNT,
};

use super::common_result_types::{SwapTokensFixedInputResultType, SwapTokensFixedOutputResultType};

multiversx_sc::imports!();
multiversx_sc::derive_imports!();

#[derive(TypeAbi, TopEncode, TopDecode, NestedEncode, NestedDecode, Clone, Copy)]
pub enum SwapType {
FixedInput,
FixedOutput,
}

#[multiversx_sc::module]
pub trait SwapModule:
Expand All @@ -22,6 +29,10 @@ pub trait SwapModule:
+ 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(swapNoFeeAndForward)]
Expand All @@ -30,8 +41,9 @@ pub trait SwapModule:
require!(self.whitelist().contains(&caller), ERROR_NOT_WHITELISTED);

let mut storage_cache = StorageCache::new(self);
let (token_in, _, amount_in) = self.call_value().single_esdt().into_tuple();
let swap_tokens_order = storage_cache.get_swap_tokens_order(&token_in, &token_out);
let payment = self.call_value().single_esdt();
let swap_tokens_order =
storage_cache.get_swap_tokens_order(&payment.token_identifier, &token_out);

require!(
self.can_swap(storage_cache.contract_state),
Expand All @@ -49,13 +61,13 @@ pub trait SwapModule:
);

let mut swap_context = SwapContext::new(
token_in,
amount_in.clone(),
payment.token_identifier,
payment.amount.clone(),
token_out,
BigUint::from(1u32),
swap_tokens_order,
);
swap_context.final_input_amount = amount_in;
swap_context.final_input_amount = payment.amount;

let amount_out = self.swap_safe_no_fee(
&mut storage_cache,
Expand Down Expand Up @@ -90,8 +102,10 @@ pub trait SwapModule:
require!(amount_out_min > 0, ERROR_INVALID_ARGS);

let mut storage_cache = StorageCache::new(self);
let (token_in, _, amount_in) = self.call_value().single_esdt().into_tuple();
let swap_tokens_order = storage_cache.get_swap_tokens_order(&token_in, &token_out);
let caller = self.blockchain().get_caller();
let payment = self.call_value().single_esdt();
let swap_tokens_order =
storage_cache.get_swap_tokens_order(&payment.token_identifier, &token_out);

require!(
self.can_swap(storage_cache.contract_state),
Expand All @@ -111,9 +125,22 @@ pub trait SwapModule:
&storage_cache.second_token_reserve,
);

let mut args = ManagedVec::new();
self.encode_arg_to_vec(&SwapType::FixedInput, &mut args);
self.encode_arg_to_vec(&token_out, &mut args);
self.encode_arg_to_vec(&amount_out_min, &mut args);

let payments_after_hook = self.call_hook(
HookType::BeforeSwap,
caller.clone(),
ManagedVec::from_single_item(payment),
args.clone(),
);
let payment = payments_after_hook.get(0);

let mut swap_context = SwapContext::new(
token_in,
amount_in,
payment.token_identifier,
payment.amount,
token_out,
amount_out_min,
swap_tokens_order,
Expand All @@ -137,11 +164,14 @@ pub trait SwapModule:

let caller = self.blockchain().get_caller();
let output_payments = self.build_swap_output_payments(&swap_context);
self.send_multiple_tokens_if_not_zero(&caller, &output_payments);
let output_payments_after_hook =
self.call_hook(HookType::AfterSwap, caller.clone(), output_payments, args);

self.send_multiple_tokens_if_not_zero(&caller, &output_payments_after_hook);

self.emit_swap_event(&storage_cache, swap_context);

self.build_swap_fixed_input_results(output_payments)
self.build_swap_fixed_input_results(output_payments_after_hook)
}

#[payable("*")]
Expand All @@ -154,8 +184,10 @@ pub trait SwapModule:
require!(amount_out > 0, ERROR_INVALID_ARGS);

let mut storage_cache = StorageCache::new(self);
let (token_in, _, amount_in_max) = self.call_value().single_esdt().into_tuple();
let swap_tokens_order = storage_cache.get_swap_tokens_order(&token_in, &token_out);
let caller = self.blockchain().get_caller();
let payment = self.call_value().single_esdt();
let swap_tokens_order =
storage_cache.get_swap_tokens_order(&payment.token_identifier, &token_out);

require!(
self.can_swap(storage_cache.contract_state),
Expand All @@ -175,9 +207,22 @@ pub trait SwapModule:
&storage_cache.second_token_reserve,
);

let mut args = ManagedVec::new();
self.encode_arg_to_vec(&SwapType::FixedOutput, &mut args);
self.encode_arg_to_vec(&token_out, &mut args);
self.encode_arg_to_vec(&amount_out, &mut args);

let payments_after_hook = self.call_hook(
HookType::BeforeSwap,
caller.clone(),
ManagedVec::from_single_item(payment),
args.clone(),
);
let payment = payments_after_hook.get(0);

let mut swap_context = SwapContext::new(
token_in,
amount_in_max,
payment.token_identifier,
payment.amount,
token_out,
amount_out,
swap_tokens_order,
Expand All @@ -201,11 +246,14 @@ pub trait SwapModule:

let caller = self.blockchain().get_caller();
let output_payments = self.build_swap_output_payments(&swap_context);
self.send_multiple_tokens_if_not_zero(&caller, &output_payments);
let output_payments_after_hook =
self.call_hook(HookType::AfterSwap, caller.clone(), output_payments, args);

self.send_multiple_tokens_if_not_zero(&caller, &output_payments_after_hook);

self.emit_swap_event(&storage_cache, swap_context);

self.build_swap_fixed_output_results(output_payments)
self.build_swap_fixed_output_results(output_payments_after_hook)
}

fn perform_swap_fixed_input(
Expand Down
Loading

0 comments on commit 8474c5e

Please sign in to comment.