Skip to content

Commit

Permalink
remove decaying fees
Browse files Browse the repository at this point in the history
  • Loading branch information
rrruko committed May 7, 2024
1 parent d301422 commit f11d50b
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 96 deletions.
4 changes: 3 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
AIKEN=$1

aiken() {
/home/pi/proj/aiken/target/release/aiken $*
${AIKEN} $*
}

set -e
Expand Down
55 changes: 3 additions & 52 deletions lib/calculation/process.ak
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ use aiken/bytearray
use aiken/cbor
use aiken/dict.{Dict}
use aiken/hash.{Blake2b_256, Hash}
use aiken/interval.{Finite, IntervalBound, NegativeInfinity}
use aiken/math
use aiken/time.{PosixTime}
use aiken/interval
use aiken/transaction.{
InlineDatum, Input, NoDatum, Output, OutputReference, TransactionId,
ValidityRange,
Expand All @@ -27,38 +25,11 @@ use sundae/multisig
use types/order.{Destination, Fixed, Order, OrderDatum, SignedStrategyExecution}
use types/pool.{PoolDatum}

pub fn calculate_fees(
fees: (Int, Int),
market_open: PosixTime,
fee_finalized: PosixTime,
valid_from: PosixTime,
) {
// So, if the transaction is guaranteed to run after fee_finalized, charge the final fee rate
if valid_from > fee_finalized {
fees.2nd
} else {
// Otherwise, calculate the duration of this decay period
let duration = fee_finalized - market_open
if duration == 0 {
// If it's zero (market_open == fee_finalized) then just use the final fee rate
fees.2nd
} else {
// Otherwise, calculate how much has elapsed since the market open
// then the full range of the fee rate
// then, starting from the opening fee rate, linearly increase (or decrease) the fees by that range
let elapsed = valid_from - market_open
let range = fees.2nd - fees.1st
fees.1st + elapsed * range / duration
}
}
}

/// Construct the initial pool state for processing a set of orders
pub fn pool_input_to_state(
pool_token_policy: PolicyId,
datum: PoolDatum,
input: Output,
valid_from: IntervalBound<PosixTime>,
continuation: fn(
PolicyId,
AssetName,
Expand All @@ -82,8 +53,6 @@ pub fn pool_input_to_state(
circulating_lp,
bid_fees_per_10_thousand,
ask_fees_per_10_thousand,
market_open,
fee_finalized,
..
} = datum
let (asset_a, asset_b) = assets
Expand All @@ -102,28 +71,10 @@ pub fn pool_input_to_state(
// Scoopers could in theory set a wide validity range to cause users to overpay, but this should be considered malicious activity and
// get the scooper removed from the list of valid scoopers / ignore scooper rewards
// TODO: we could solve this by enforcing a validity range, and checking the length is within 4 hours.
let valid_from =
when valid_from.bound_type is {
NegativeInfinity -> market_open
Finite(t) -> math.max(t, market_open)
_ -> fail
}
// Calculate the fees per 10k rate to use for this whole scoop
// We let the creator of the pool specify a fee rate that decays (or increases) between market_open and fee_finalized
let bid_fees =
calculate_fees(
bid_fees_per_10_thousand,
market_open,
fee_finalized,
valid_from,
)
let ask_fees =
calculate_fees(
ask_fees_per_10_thousand,
market_open,
fee_finalized,
valid_from,
)
let bid_fees = bid_fees_per_10_thousand
let ask_fees = ask_fees_per_10_thousand
// Then construct the pool state. We include the assets here, instead of just the reserves, so we can check the values of each order
// TODO: we could potentially save quite a bit by not passing around this object, and passing around a lot of parameters instead...
continuation(
Expand Down
8 changes: 3 additions & 5 deletions lib/shared.ak
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,9 @@ pub fn oracle_sft_name() {
"oracle"
}

pub fn fees_in_legal_range(fees: (Int, Int)) {
pub fn fees_in_legal_range(fees: Int) {
and {
fees.1st >= 0,
fees.2nd >= 0,
fees.1st <= 10000,
fees.2nd <= 10000,
fees >= 0,
fees <= 10000,
}
}
4 changes: 2 additions & 2 deletions lib/tests/examples/ex_pool.ak
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ fn mk_pool_datum() -> PoolDatum {
),
),
circulating_lp: 20229488080013,
bid_fees_per_10_thousand: (2000, 500),
ask_fees_per_10_thousand: (2000, 500),
bid_fees_per_10_thousand: 2000,
ask_fees_per_10_thousand: 2000,
fee_manager: None,
market_open: 100,
fee_finalized: 1000,
Expand Down
4 changes: 2 additions & 2 deletions lib/types/pool.ak
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ pub type PoolDatum {
/// The two values represent the fees as of `market_open` and as of `fee_finalized`, respectively, with a linear
/// decay from one to the other.
/// The transaction uses the valid_from field to charge the largest fee the transaction *could* be obligated to pay
bid_fees_per_10_thousand: (Int, Int),
ask_fees_per_10_thousand: (Int, Int),
bid_fees_per_10_thousand: Int,
ask_fees_per_10_thousand: Int,
// An optional multisig condition under which the protocol fees can be updated
fee_manager: Option<multisig.MultisigScript>,
/// The UNIX millisecond timestamp at which trading against the pool should be allowed
Expand Down
34 changes: 17 additions & 17 deletions plutus.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions validators/oracle.ak
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ fn mint_oracle(
identifier: pool_id,
assets: ((#"", #""), (rberry_policy_id, rberry_token_name)),
circulating_lp: 1_000_000_000,
bid_fees_per_10_thousand: (5, 5),
ask_fees_per_10_thousand: (5, 5),
bid_fees_per_10_thousand: 5,
ask_fees_per_10_thousand: 5,
fee_manager: None,
market_open: 0,
fee_finalized: 0,
Expand Down
1 change: 0 additions & 1 deletion validators/pool.ak
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ validator(
pool_script_hash,
datum,
pool_input,
validity_range.lower_bound,
)

// Process the orders in order, and decide the final pool state we should see
Expand Down
28 changes: 14 additions & 14 deletions validators/tests/pool.ak
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ type ScoopTestOptions {
edit_order_intended_destination: Option<Destination>,
edit_order_actual_destination: Option<Destination>,
edit_fee: Option<Value>,
edit_swap_fees: Option<((Int, Int), (Int, Int))>,
edit_new_swap_fees: Option<((Int, Int), (Int, Int))>,
edit_swap_fees: Option<(Int, Int)>,
edit_new_swap_fees: Option<(Int, Int)>,
edit_fee_admin: Option<Option<multisig.MultisigScript>>,
edit_withdrawals: Option<Dict<StakeCredential, Int>>,
edit_pool_input_address: Option<Address>,
Expand Down Expand Up @@ -206,7 +206,7 @@ test scoop_high_swap_fees() {
let options =
ScoopTestOptions {
..default_scoop_test_options(),
edit_swap_fees: Some(((swap_fee, swap_fee), (swap_fee, swap_fee))),
edit_swap_fees: Some((swap_fee, swap_fee)),
edit_order_1_out_value: Some(
value.from_lovelace(2_000_000)
|> value.add(
Expand Down Expand Up @@ -328,7 +328,7 @@ test scooper_not_in_settings() fail {
fn scoop(options: ScoopTestOptions) {
let user_addr = wallet_address(constants.payment_key)
let owner = multisig.Signature(constants.payment_key)
let fees = option.or_else(options.edit_swap_fees, ((5, 5), (5, 5)))
let fees = option.or_else(options.edit_swap_fees, (5, 5))
let pool_datum =
PoolDatum {
identifier: constants.pool_ident,
Expand Down Expand Up @@ -548,7 +548,7 @@ fn scoop(options: ScoopTestOptions) {
fn scoop_swap_deposit(options: ScoopTestOptions) {
let user_addr = wallet_address(constants.payment_key)
let owner = multisig.Signature(constants.payment_key)
let pool_fees = option.or_else(options.edit_swap_fees, ((5, 5), (5, 5)))
let pool_fees = option.or_else(options.edit_swap_fees, (5, 5))
let pool_datum =
PoolDatum {
identifier: constants.pool_ident,
Expand Down Expand Up @@ -777,7 +777,7 @@ fn withdraw_fees_transaction(options: ScoopTestOptions, withdraw_amount: Int, po
options.edit_pool_output_address,
default_pool_output_address,
)
let pool_fees = option.or_else(options.edit_swap_fees, ((5, 5), (5, 5)))
let pool_fees = option.or_else(options.edit_swap_fees, (5, 5))
let protocol_fees = 2_000_000
let pool_datum =
PoolDatum {
Expand Down Expand Up @@ -1019,7 +1019,7 @@ fn update_pool_fees_transaction(options: ScoopTestOptions) {
options.edit_pool_output_address,
default_pool_output_address,
)
let pool_fees = option.or_else(options.edit_swap_fees, ((5, 5), (5, 5)))
let pool_fees = option.or_else(options.edit_swap_fees, (5, 5))
let fee_manager =
option.or_else(
options.edit_fee_admin,
Expand Down Expand Up @@ -1063,7 +1063,7 @@ fn update_pool_fees_transaction(options: ScoopTestOptions) {
)

let new_pool_fees =
option.or_else(options.edit_new_swap_fees, ((10, 10), (310, 150)))
option.or_else(options.edit_new_swap_fees, (10, 10))
let pool_out_datum =
PoolDatum {
..pool_datum,
Expand Down Expand Up @@ -1132,7 +1132,7 @@ test illegal_new_pool_fees_test() fail {
let settings =
ScoopTestOptions {
..default_scoop_test_options(),
edit_new_swap_fees: Some(((10001, 10001), (10001, 10001))),
edit_new_swap_fees: Some((10001, 10001)),
}
update_pool_fees_transaction(settings)
}
Expand Down Expand Up @@ -1245,8 +1245,8 @@ fn mint_test_modify(
(constants.rberry_policy, constants.rberry_asset_name),
),
circulating_lp: 1_000_000_000,
bid_fees_per_10_thousand: (5, 5),
ask_fees_per_10_thousand: (5, 5),
bid_fees_per_10_thousand: 5,
ask_fees_per_10_thousand: 5,
fee_manager: None,
market_open: 0,
fee_finalized: 0,
Expand Down Expand Up @@ -1525,7 +1525,7 @@ fn evaporate_pool_tx(options: ScoopTestOptions, withdraw_amount: Int) {
let withdraw_fees_redeemer =
WithdrawFees { amount: withdraw_amount, treasury_output: 0, pool_input: 0 }
let pool_nft_name = shared.pool_nft_name(constants.pool_ident)
let pool_fees = option.or_else(options.edit_swap_fees, ((5, 5), (5, 5)))
let pool_fees = option.or_else(options.edit_swap_fees, (5, 5))
let pool_datum =
PoolDatum {
identifier: constants.pool_ident,
Expand Down Expand Up @@ -1612,7 +1612,7 @@ test attempt_evaporate_pool_test() {
let withdraw_fees_redeemer =
WithdrawFees { amount: 18_000_000, treasury_output: 0, pool_input: 0 }
let pool_nft_name = shared.pool_nft_name(constants.pool_ident)
let pool_fees = ((5, 5), (5, 5))
let pool_fees = (5, 5)
let pool_datum =
PoolDatum {
identifier: constants.pool_ident,
Expand Down Expand Up @@ -1683,7 +1683,7 @@ test attempt_evaporate_pool_test() {

test burn_pool() {
let user_addr = wallet_address(constants.payment_key)
let fees = ((5, 5), (5, 5))
let fees = (5, 5)
let pool_datum =
PoolDatum {
identifier: constants.pool_ident,
Expand Down

0 comments on commit f11d50b

Please sign in to comment.