Skip to content

Commit

Permalink
Merge pull request #30 from SundaeSwap-finance/pi/SSW-305
Browse files Browse the repository at this point in the history
SSW-305: Redundant fee calculation
  • Loading branch information
Quantumplation authored Jan 16, 2024
2 parents c143cd3 + e686590 commit 67250bd
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 72 deletions.
5 changes: 0 additions & 5 deletions lib/calculation/deposit.ak
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ pub fn do_deposit(
pool_state.quantity_lp.2nd,
pool_state.quantity_lp.3rd + issued_lp_tokens,
),
fees_per_10_thousand: pool_state.fees_per_10_thousand,
protocol_fees: pool_state.protocol_fees + actual_protocol_fee,
}
}

Expand All @@ -114,8 +112,6 @@ test deposit_test() {
quantity_a: (#"", #"", 1_000_000_000),
quantity_b: (rberry.1st, rberry.2nd, 1_000_000_000),
quantity_lp: (lp.1st, lp.2nd, 1_000_000_000),
fees_per_10_thousand: 5,
protocol_fees: 2_000_000,
}
let input_value =
value.from_lovelace(14_500_000)
Expand Down Expand Up @@ -146,6 +142,5 @@ test deposit_test() {
let final_pool_state = do_deposit(pool_state, input_value, assets, order.destination, 2_500_000, output)
expect final_pool_state.quantity_a.3rd == 1_010_000_000
expect final_pool_state.quantity_b.3rd == 1_010_000_000
expect final_pool_state.protocol_fees == 4_500_000
True
}
5 changes: 0 additions & 5 deletions lib/calculation/donation.ak
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ pub fn do_donation(
pool_state.quantity_b.3rd + assets.2nd.3rd,
),
quantity_lp: pool_state.quantity_lp,
fees_per_10_thousand: pool_state.fees_per_10_thousand,
protocol_fees: pool_state.protocol_fees + actual_protocol_fee,
},
has_remainder,
)
Expand All @@ -71,8 +69,6 @@ test donation() {
quantity_a: (#"", #"", 1_000_000_000),
quantity_b: (rberry.1st, rberry.2nd, 1_000_000_000),
quantity_lp: (lp.1st, lp.2nd, 1_000_000_000),
fees_per_10_thousand: 5,
protocol_fees: 2_000_000,
}
let input_value =
value.from_lovelace(1_000_000)
Expand Down Expand Up @@ -107,6 +103,5 @@ test donation() {
expect !has_remainder
expect final_pool_state.quantity_a.3rd == 1_001_000_000
expect final_pool_state.quantity_b.3rd == 1_001_000_000
expect final_pool_state.protocol_fees == 4_500_000
True
}
41 changes: 19 additions & 22 deletions lib/calculation/process.ak
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub fn pool_input_to_state(
datum: PoolDatum,
input: Output,
valid_from: IntervalBound<PosixTime>,
) -> PoolState {
) -> (PoolState, Int, Int) {
let PoolDatum {
assets,
protocol_fees,
Expand Down Expand Up @@ -63,7 +63,7 @@ pub fn pool_input_to_state(
fees_per_10_thousand.1st + (elapsed * range / duration)
}
}
PoolState {
(PoolState {
quantity_a: (
asset_a_policy_id,
asset_a_name,
Expand All @@ -75,10 +75,7 @@ pub fn pool_input_to_state(
value.quantity_of(input.value, asset_b_policy_id, asset_b_name),
),
quantity_lp: (pool_token_policy, pool_lp_name(identifier), circulating_lp),
fees_per_10_thousand: fees,
// Pay the transaction fee out of the protocol_fees
protocol_fees,
}
}, fees, protocol_fees)
}

fn validate_pool_id(order_pool_ident: Option<Ident>, pool_ident: Ident) -> Bool {
Expand All @@ -97,11 +94,12 @@ pub fn process_order(
details: Order,
max_protocol_fee: Int,
destination: Destination,
fees_per_10_thousand: Int,
amortized_base_fee: Int,
simple_fee: Int,
strategy_fee: Int,
outputs: List<Output>,
) -> (PoolState, List<Output>, Int) {
) -> (PoolState, List<Output>) {
when details is {
order.Strategy(signer) -> {
expect Some(execution) = signed_execution
Expand All @@ -120,6 +118,7 @@ pub fn process_order(
details,
max_protocol_fee,
destination,
fees_per_10_thousand,
amortized_base_fee,
// We pass strategy_fee here, instead of simple_fee,
// reuse the code to calculate the result, but charge the higher fee
Expand All @@ -138,20 +137,21 @@ pub fn process_order(
initial,
value,
destination,
fees_per_10_thousand,
fee,
offer,
min_received,
output,
)
(next, rest_outputs, fee)
(next, rest_outputs)
}
order.Deposit(assets) -> {
expect [output, ..rest_outputs] = outputs
// Make sure the scooper can only take up to the max fee the user has agreed to
let fee = amortized_base_fee + simple_fee
expect max_protocol_fee >= fee
let next = deposit.do_deposit(initial, value, assets, destination, fee, output)
(next, rest_outputs, fee)
(next, rest_outputs)
}
order.Withdrawal(amount) -> {
expect [output, ..rest_outputs] = outputs
Expand All @@ -160,7 +160,7 @@ pub fn process_order(
expect max_protocol_fee >= fee
let next =
withdrawal.do_withdrawal(initial, value, amount, destination, fee, output)
(next, rest_outputs, fee)
(next, rest_outputs)
}
// order.Zap(..) -> do_zap(initial, input, datum)
order.Donation(assets) -> {
Expand All @@ -171,9 +171,9 @@ pub fn process_order(
let (next, used_output) =
donation.do_donation(initial, value, assets, destination, fee, output)
if used_output {
(next, rest_outputs, fee)
(next, rest_outputs)
} else {
(next, outputs, fee)
(next, outputs)
}
}
}
Expand All @@ -185,6 +185,7 @@ pub fn process_orders(
datums: Dict<Hash<Blake2b_256, Data>, Data>,
initial: PoolState,
input_order: List<(Int, Option<SignedStrategyExecution>)>,
fees_per_10_thousand: Int,
amortized_base_fee: Int,
simple_fee: Int,
strategy_fee: Int,
Expand All @@ -195,10 +196,9 @@ pub fn process_orders(
uniqueness_flag: Int,
simple_count: Int,
strategy_count: Int,
total_fee: Int,
) -> (PoolState, Int, Int, Int) {
) -> (PoolState, Int, Int) {
when input_order is {
[] -> (initial, simple_count, strategy_count, total_fee)
[] -> (initial, simple_count, strategy_count)
[(idx, sse), ..rest] -> {
// Check that this idx is unique
let next_uniqueness_flag = check_and_set_unique(uniqueness_flag, idx)
Expand Down Expand Up @@ -227,7 +227,7 @@ pub fn process_orders(
_ -> (simple_count + 1, strategy_count)
}

let (next_state, next_orders, fee) = process_order(
let (next_state, next_orders) = process_order(
initial,
sse,
output_reference,
Expand All @@ -236,6 +236,7 @@ pub fn process_orders(
details,
max_protocol_fee,
destination,
fees_per_10_thousand,
amortized_base_fee,
simple_fee,
strategy_fee,
Expand All @@ -248,6 +249,7 @@ pub fn process_orders(
datums,
next_state,
rest,
fees_per_10_thousand,
amortized_base_fee,
simple_fee,
strategy_fee,
Expand All @@ -258,7 +260,6 @@ pub fn process_orders(
next_uniqueness_flag,
next_simple_count,
next_strategy_count,
total_fee + fee
)
}
}
Expand All @@ -279,8 +280,6 @@ test process_orders_test() {
quantity_a: (#"", #"", 1_000_000_000),
quantity_b: (rberry.1st, rberry.2nd, 1_000_000_000),
quantity_lp: (lp.1st, lp.2nd, 1_000_000_000),
fees_per_10_thousand: 5,
protocol_fees: 2_000_000,
}
let order_datum = OrderDatum {
pool_ident: None,
Expand Down Expand Up @@ -338,13 +337,11 @@ test process_orders_test() {
let inputs = [input]
let outputs = [output]

let (final_pool_state, simple, strategies, fee) = process_orders(#"", valid_range, datums, pool_state, input_order, 2_500_000, 0, 0, 0, inputs, inputs, outputs, 0, 0, 0, 0)
let (final_pool_state, simple, strategies) = process_orders(#"", valid_range, datums, pool_state, input_order, 5, 2_500_000, 0, 0, 0, inputs, inputs, outputs, 0, 0, 0)

expect final_pool_state.quantity_a.3rd == 1_001_000_000
expect final_pool_state.quantity_b.3rd == 1_001_000_000
expect final_pool_state.protocol_fees == 4_500_000
expect simple == 1
expect strategies == 0
expect fee == 2_500_000
True
}
4 changes: 0 additions & 4 deletions lib/calculation/shared.ak
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ pub type PoolState {
quantity_b: SingletonValue,
/// The quantity of LP tokens in the pool
quantity_lp: SingletonValue,
/// The fee the pool charges
fees_per_10_thousand: Int,
/// The protocol_fees accumulated in the pool
protocol_fees: Int,
}

pub fn unsafe_fast_index_skip_with_tail(inputs: List<a>, idx: Int) -> List<a> {
Expand Down
12 changes: 2 additions & 10 deletions lib/calculation/swap.ak
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub fn do_swap(
pool_state: PoolState,
input_value: Value,
destination: Destination,
fees_per_10_thousand: Int,
actual_protocol_fee: Int,
offer: SingletonValue,
min_received: SingletonValue,
Expand All @@ -63,8 +64,6 @@ pub fn do_swap(
quantity_a,
quantity_b,
quantity_lp,
fees_per_10_thousand,
protocol_fees,
} = pool_state
let (a_policy_id, a_asset_name, a_amt) = quantity_a
let (b_policy_id, b_asset_name, b_amt) = quantity_b
Expand Down Expand Up @@ -96,8 +95,6 @@ pub fn do_swap(
quantity_a: (a_policy_id, a_asset_name, a_amt + offer_amt),
quantity_b: (b_policy_id, b_asset_name, b_amt - takes),
quantity_lp,
fees_per_10_thousand,
protocol_fees: protocol_fees + actual_protocol_fee,
}
} else if offer_policy_id == b_policy_id && offer_asset_name == b_asset_name {
expect min_received.1st == a_policy_id
Expand Down Expand Up @@ -125,8 +122,6 @@ pub fn do_swap(
quantity_a: (a_policy_id, a_asset_name, a_amt - takes),
quantity_b: (b_policy_id, b_asset_name, b_amt + offer_amt),
quantity_lp,
fees_per_10_thousand,
protocol_fees: protocol_fees + actual_protocol_fee,
}
} else {
fail
Expand All @@ -151,8 +146,6 @@ test swap_mintakes_too_high() fail {
quantity_a: (#"", #"", 1_000_000_000),
quantity_b: (rberry.1st, rberry.2nd, 1_000_000_000),
quantity_lp: (lp.1st, lp.2nd, 1_000_000_000),
fees_per_10_thousand: 5,
protocol_fees: 2_000_000,
}
let input_value =
value.from_lovelace(14_500_000)
Expand All @@ -178,9 +171,8 @@ test swap_mintakes_too_high() fail {
datum: NoDatum,
reference_script: None,
}
let final_pool_state = do_swap(pool_state, input_value, order.destination, 2_500_000, swap_offer, swap_min_received, output)
let final_pool_state = do_swap(pool_state, input_value, order.destination, 5, 2_500_000, swap_offer, swap_min_received, output)
expect final_pool_state.quantity_a.3rd == 1_000_000_000 + 10_000_000
expect final_pool_state.quantity_b.3rd == 1_000_000_000 - 9_896_088
expect final_pool_state.protocol_fees == 4_500_000
True
}
5 changes: 0 additions & 5 deletions lib/calculation/withdrawal.ak
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ pub fn do_withdrawal(
pool_state.quantity_lp.2nd,
pool_state.quantity_lp.3rd - withdrawn,
),
fees_per_10_thousand: pool_state.fees_per_10_thousand,
protocol_fees: pool_state.protocol_fees + actual_protocol_fee,
}
}

Expand Down Expand Up @@ -120,8 +118,6 @@ fn withdrawal_test(options: WithdrawalTestOptions) {
quantity_a: (#"", #"", 1_010_000_000),
quantity_b: (rberry.1st, rberry.2nd, 1_010_000_000),
quantity_lp: (lp.1st, lp.2nd, 1_010_000_000),
fees_per_10_thousand: 5,
protocol_fees: 2_000_000,
}
let input_value =
value.from_lovelace(4_500_000)
Expand Down Expand Up @@ -155,6 +151,5 @@ fn withdrawal_test(options: WithdrawalTestOptions) {
let final_pool_state = do_withdrawal(pool_state, input_value, amount, order.destination, 2_500_000, output)
expect final_pool_state.quantity_a.3rd == 1_000_000_000
expect final_pool_state.quantity_b.3rd == 1_000_000_000
expect final_pool_state.protocol_fees == 4_500_000
True
}
1 change: 1 addition & 0 deletions lib/types/pool.ak
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub type PoolRedeemer {
PoolScoop {
signatory_index: Int,
scooper_index: Int,
// TODO: remove this, and update all our off-chain tx building code
amortized_base_fee: Int,
input_order: List<(Int, Option<SignedStrategyExecution>)>,
}
Expand Down
Loading

0 comments on commit 67250bd

Please sign in to comment.