From 57fff31e6cbe478f4a2a092d2d71bfebb00a19b6 Mon Sep 17 00:00:00 2001 From: Richard Nguyen Date: Tue, 24 Oct 2023 11:30:17 +0700 Subject: [PATCH] enhance: allow validator find script datum via both DatumDict or InlineDatum & add partial swap (#7) * allow validator find script datum via both DatumDict or InlineDatum * add partial swap * add some safety check * add some safety check --- lib/amm_dex_v2/math.ak | 33 ++- lib/amm_dex_v2/order_validation.ak | 404 ++++++++++++++++++++++------ lib/amm_dex_v2/types.ak | 28 +- lib/amm_dex_v2/utils.ak | 56 ++-- plutus.json | 16 +- validators/authen_minting_policy.ak | 4 +- validators/factory_validator.ak | 8 +- validators/pool_validator.ak | 135 ++++------ 8 files changed, 454 insertions(+), 230 deletions(-) diff --git a/lib/amm_dex_v2/math.ak b/lib/amm_dex_v2/math.ak index 9ef7287..dadac93 100644 --- a/lib/amm_dex_v2/math.ak +++ b/lib/amm_dex_v2/math.ak @@ -62,6 +62,23 @@ pub fn calculate_amount_out( numerator / denominator } +pub fn calculate_max_in_swap( + reserve_in: Int, + reserve_out: Int, + trading_fee_numerator: Int, + trading_fee_denominator: Int, + io_ratio_numerator: Int, + io_ratio_denominator: Int, +) -> Int { + let diff = trading_fee_denominator - trading_fee_numerator + let numerator = + io_ratio_numerator * diff * reserve_out - io_ratio_denominator * trading_fee_denominator * reserve_in + let denominator = io_ratio_denominator * diff + let max_in_swap = numerator / denominator + expect max_in_swap > 0 + max_in_swap +} + pub fn calculate_amount_out_fraction( reserve_in: Int, reserve_out: Int, @@ -83,16 +100,12 @@ pub fn calculate_amount_in( amount_out: Int, trading_fee_numerator: Int, trading_fee_denominator: Int, -) -> Option { - if amount_out >= reserve_out { - None - } else { - let diff = trading_fee_denominator - trading_fee_numerator - let numerator = reserve_in * amount_out * trading_fee_denominator - let denominator = ( reserve_out - amount_out ) * diff - let amount_in = numerator / denominator + 1 - Some(amount_in) - } +) -> Int { + expect amount_out < reserve_out + let diff = trading_fee_denominator - trading_fee_numerator + let numerator = reserve_in * amount_out * trading_fee_denominator + let denominator = ( reserve_out - amount_out ) * diff + numerator / denominator + 1 } // Calculate liquidity amount which will be minted for profit sharing diff --git a/lib/amm_dex_v2/order_validation.ak b/lib/amm_dex_v2/order_validation.ak index 4a0cabc..c0a9657 100644 --- a/lib/amm_dex_v2/order_validation.ak +++ b/lib/amm_dex_v2/order_validation.ak @@ -1,14 +1,15 @@ -use aiken/dict.{Dict} -use aiken/hash.{Blake2b_256, Hash} +use aiken/builtin +use aiken/hash use aiken/list -use aiken/transaction.{DatumHash, Input, NoDatum, Output} -use aiken/transaction/credential +use aiken/transaction.{DatumHash, InlineDatum, Input, NoDatum, Output} +use aiken/transaction/credential.{Address, ScriptCredential} use aiken/transaction/value.{Value, ada_asset_name, ada_policy_id} use amm_dex_v2/math use amm_dex_v2/types.{ - AToB, Asset, BToA, BatchingPool, Deposit, OrderDatum, PoolState, ProfitSharing, - SwapExactIn, SwapExactInOCO, SwapExactInStopLoss, SwapExactOut, - SwapMultiRouting, SwapRouting, Withdraw, ZapOut, + AToB, Asset, BToA, BatchingPool, CustomDatumHash, DatumMap, Deposit, + OrderDatum, PartialSwap, PoolState, ProfitSharing, SwapExactIn, SwapExactInOCO, + SwapExactInStopLoss, SwapExactOut, SwapMultiRouting, SwapRouting, Withdraw, + ZapOut, } use amm_dex_v2/utils @@ -22,9 +23,9 @@ fn validate_swap_exact_in( output_ada: Int, trading_fee_numerator: Int, trading_fee_denominator: Int, - pool_state: (Int, Int, Int, Int, Int), + pool_state: PoolState, checking_slippage_fn: fn(Int) -> Bool, -) -> (Int, Int, Int, Int, Int) { +) -> PoolState { let (reserve_a, reserve_b, total_liquidity, liquidity_share, root_k_last) = pool_state let (asset_in, asset_out, reserve_in, reserve_out) = @@ -100,8 +101,8 @@ fn validate_swap_exact_out( output_ada: Int, trading_fee_numerator: Int, trading_fee_denominator: Int, - pool_state: (Int, Int, Int, Int, Int), -) -> (Int, Int, Int, Int, Int) { + pool_state: PoolState, +) -> PoolState { let (reserve_a, reserve_b, total_liquidity, liquidity_share, root_k_last) = pool_state let (asset_in, asset_out, reserve_in, reserve_out) = @@ -123,7 +124,7 @@ fn validate_swap_exact_out( temp_amount_in } let has_enough_amount_in = maximum_amount_in > 0 - let necessary_amount_in_opt = + let necessary_amount_in = math.calculate_amount_in( reserve_in, reserve_out, @@ -131,7 +132,6 @@ fn validate_swap_exact_out( trading_fee_numerator, trading_fee_denominator, ) - let necessary_amount_in = utils.must_parse_option(necessary_amount_in_opt) let not_over_slippage = necessary_amount_in <= maximum_amount_in let actual_amount_out = value.quantity_of( @@ -185,8 +185,8 @@ fn validate_deposit( profit_sharing_opt: Option, trading_fee_numerator: Int, trading_fee_denominator: Int, - pool_state: (Int, Int, Int, Int, Int), -) -> (Int, Int, Int, Int, Int) { + pool_state: PoolState, +) -> PoolState { let (reserve_a, reserve_b, total_liquidity, liquidity_share, root_k_last) = pool_state let Asset { policy_id: asset_a_policy_id, asset_name: asset_a_asset_name } = @@ -266,8 +266,8 @@ fn validate_withdraw( lp_asset: Asset, output_ada: Int, profit_sharing_opt: Option, - pool_state: (Int, Int, Int, Int, Int), -) -> (Int, Int, Int, Int, Int) { + pool_state: PoolState, +) -> PoolState { let (reserve_a, reserve_b, total_liquidity, liquidity_share, root_k_last) = pool_state let Asset { policy_id: asset_a_policy_id, asset_name: asset_a_asset_name } = @@ -341,8 +341,8 @@ fn validate_zap_out( profit_sharing_opt: Option, trading_fee_numerator: Int, trading_fee_denominator: Int, - pool_state: (Int, Int, Int, Int, Int), -) -> (Int, Int, Int, Int, Int) { + pool_state: PoolState, +) -> PoolState { let (reserve_a, reserve_b, total_liquidity, liquidity_share, root_k_last) = pool_state let asset_out = @@ -426,6 +426,115 @@ fn validate_zap_out( } } +fn validate_partial_swap( + order_in_value: Value, + order_out_value: Value, + a_to_b_direction: Bool, + io_ratio_numerator: Int, + io_ratio_denominator: Int, + hops: Int, + minimum_swap_amount_required: Int, + asset_a: Asset, + asset_b: Asset, + batcher_fee: Int, + output_ada: Int, + trading_fee_numerator: Int, + trading_fee_denominator: Int, + pool_state: PoolState, +) -> (Int, Int, Int, Int, Int, Bool) { + let (reserve_a, reserve_b, total_liquidity, liquidity_share, root_k_last) = + pool_state + let (asset_in, asset_out, reserve_in, reserve_out) = + if a_to_b_direction { + (asset_a, asset_b, reserve_a, reserve_b) + } else { + (asset_b, asset_a, reserve_b, reserve_a) + } + let Asset { policy_id: asset_in_policy_id, asset_name: asset_in_asset_name } = + asset_in + let Asset { policy_id: asset_out_policy_id, asset_name: asset_out_asset_name } = + asset_out + let ada_in_require = batcher_fee * hops + output_ada + let temp_amount_in = + value.quantity_of(order_in_value, asset_in_policy_id, asset_in_asset_name) + let amount_in = + if utils.is_ada_asset(asset_in_policy_id, asset_in_asset_name) { + temp_amount_in - ada_in_require + } else { + temp_amount_in + } + let has_enough_amount_in = amount_in > 0 + let max_in_swap = + math.calculate_max_in_swap( + reserve_in: reserve_in, + reserve_out: reserve_out, + trading_fee_numerator: trading_fee_numerator, + trading_fee_denominator: trading_fee_denominator, + io_ratio_numerator: io_ratio_numerator, + io_ratio_denominator: io_ratio_denominator, + ) + let (swap_amount_in, remaining_amount_in) = + if amount_in <= max_in_swap { + (amount_in, 0) + } else { + (max_in_swap, amount_in - max_in_swap) + } + expect swap_amount_in > 0 && swap_amount_in >= minimum_swap_amount_required + let amount_out = + math.calculate_amount_out( + reserve_in: reserve_in, + reserve_out: reserve_out, + amount_in: swap_amount_in, + trading_fee_numerator: trading_fee_numerator, + trading_fee_denominator: trading_fee_denominator, + ) + let ada_out_require = batcher_fee * ( hops - 1 ) + output_ada + let old_amount_out = + value.quantity_of(order_in_value, asset_out_policy_id, asset_out_asset_name) + let new_amount_out = + value.quantity_of( + order_out_value, + asset_out_policy_id, + asset_out_asset_name, + ) + let new_amount_in = + value.quantity_of(order_out_value, asset_in_policy_id, asset_in_asset_name) + let is_valid_out_value = + if utils.is_ada_asset(asset_in_policy_id, asset_in_asset_name) { + new_amount_in == remaining_amount_in + ada_out_require && new_amount_out == old_amount_out + amount_out + } else if + utils.is_ada_asset(asset_out_policy_id, asset_out_asset_name){ + + new_amount_in == remaining_amount_in && new_amount_out == old_amount_out + amount_out * ada_out_require + } else { + let ada_amount = + value.quantity_of(order_out_value, ada_policy_id, ada_asset_name) + new_amount_in == remaining_amount_in && new_amount_out == old_amount_out + amount_out && ada_out_require == ada_amount + } + expect has_enough_amount_in && is_valid_out_value + let has_next_swap = + hops - 1 > 0 && remaining_amount_in >= minimum_swap_amount_required + if a_to_b_direction { + ( + reserve_a + swap_amount_in, + reserve_b - amount_out, + total_liquidity, + liquidity_share, + root_k_last, + has_next_swap, + ) + } else { + ( + reserve_a - amount_out, + reserve_b + swap_amount_in, + total_liquidity, + liquidity_share, + root_k_last, + has_next_swap, + ) + } +} + fn get_multi_routing_swap_amount_out( amount_in: Int, pool: BatchingPool, @@ -439,10 +548,8 @@ fn get_multi_routing_swap_amount_out( trading_fee_denominator, .. } = pool - let PoolState { reserve_a: old_reserve_a, reserve_b: old_reserve_b, .. } = - pool_state_in - let PoolState { reserve_a: new_reserve_a, reserve_b: new_reserve_b, .. } = - pool_state_out + let (old_reserve_a, old_reserve_b, _, _, _) = pool_state_in + let (new_reserve_a, new_reserve_b, _, _, _) = pool_state_out let SwapRouting { lp_asset: routing_lp_asset, direction } = routing expect pool_lp_asset == routing_lp_asset let (reserve_in, reserve_out) = @@ -510,23 +617,11 @@ test test_validate_swap_multi_routing_order() { asset_name: #"6c3ea488e6ff940bb6fb1b18fd605b5931d9fefde6440117015ba484cf321200", } let pool_1_pool_state_in = - PoolState { - reserve_a: 27877961987941, - reserve_b: 414804973691450, - root_k_last: 0, - total_liquidity: 106241703280080, - liquidity_share: 0, - remaining_liquidity_supply: 9223372036854775807 - 106241703280080, - } + (27877961987941, 414804973691450, 106241703280080, 0, 0) + let pool_1_pool_state_out = - PoolState { - reserve_a: 27871263020717, - reserve_b: 414904973691450, - root_k_last: 0, - total_liquidity: 106241703280080, - liquidity_share: 0, - remaining_liquidity_supply: 9223372036854775807 - 106241703280080, - } + (27871263020717, 414904973691450, 106241703280080, 0, 0) + let pool1 = BatchingPool { asset_a: pool_1_asset_a, @@ -539,6 +634,7 @@ test test_validate_swap_multi_routing_order() { address: credential.from_script( #"11f3fb05033cb08e95f5c6d4b11891003dc762a46828a4b6f164efe2", ), + delta_remaining_liquidity_supply: 0, pool_state_in: pool_1_pool_state_in, pool_state_out: pool_1_pool_state_out, } @@ -554,24 +650,9 @@ test test_validate_swap_multi_routing_order() { policy_id: #"1a919d30617fcbc8a92c337c59c3aecb6c4ded8f154e4c24528ccea2", asset_name: #"452089abb5bf8cc59b678a2cd7b9ee952346c6c0aa1cf27df324310a70d02fc3", } - let pool_2_pool_state_in = - PoolState { - reserve_a: 5281584632864, - reserve_b: 1432277778019, - root_k_last: 0, - total_liquidity: 2450077671602, - liquidity_share: 0, - remaining_liquidity_supply: 9223372036854775807 - 2450077671602, - } + let pool_2_pool_state_in = (5281584632864, 1432277778019, 2450077671602, 0, 0) let pool_2_pool_state_out = - PoolState { - reserve_a: 5288283600088, - reserve_b: 1430468867110, - root_k_last: 0, - total_liquidity: 2450077671602, - liquidity_share: 0, - remaining_liquidity_supply: 9223372036854775807 - 2450077671602, - } + (5288283600088, 1430468867110, 2450077671602, 0, 0) let pool2 = BatchingPool { asset_a: pool_2_asset_a, @@ -584,6 +665,7 @@ test test_validate_swap_multi_routing_order() { address: credential.from_script( #"11f3fb05033cb08e95f5c6d4b11891003dc762a46828a4b6f164efe2", ), + delta_remaining_liquidity_supply: 0, pool_state_in: pool_2_pool_state_in, pool_state_out: pool_2_pool_state_out, } @@ -677,62 +759,79 @@ pub fn validate_swap_multi_routing_order( True } +pub fn validate_order_receiver( + receiver: Address, + receiver_datum_hash_opt: Option, + output: Output, +) -> Bool { + let Output { address: output_address, datum: raw_order_output_datum, .. } = + output + let is_valid_receiver_datum = + when receiver_datum_hash_opt is { + Some(receiver_datum_hash) -> + when raw_order_output_datum is { + NoDatum -> fail + DatumHash(dh) -> dh == receiver_datum_hash + InlineDatum(dat) -> + hash.blake2b_256(builtin.serialise_data(dat)) == receiver_datum_hash + } + None -> raw_order_output_datum == NoDatum + } + expect receiver == output_address && is_valid_receiver_datum + True +} + // TODO: validate order input value size pub fn apply_orders( - all_outputs: List, - datum_dict: Dict, Data>, + datum_map: DatumMap, asset_a: Asset, asset_b: Asset, lp_asset: Asset, trading_fee_numerator: Int, trading_fee_denominator: Int, + order_hash: ByteArray, profit_sharing_opt: Option, order_inputs: List, order_outputs: List, - pool_state: (Int, Int, Int, Int, Int), -) -> (Int, Int, Int, Int, Int) { + pool_state: PoolState, +) -> PoolState { when order_inputs is { [] -> pool_state [input, ..inputs] -> when order_outputs is { [] -> pool_state [output, ..outputs] -> { - let Input { output: order_in_output, .. } = input - let Output { value: order_in_value, .. } = order_in_output - let Output { - value: order_out_value, - address: output_address, - datum: order_output_datum, + let Input { + output: Output { + value: order_in_value, + datum: raw_order_in_datum, + .. + }, .. - } = output + } = input + let Output { value: order_out_value, .. } = output + let order_in_datum = + utils.must_find_order_datum(datum_map, raw_order_in_datum) let OrderDatum { + sender, receiver, receiver_datum_hash_opt, step: order_step, batcher_fee, output_ada, lp_asset: order_lp_asset, - .. - } = - utils.must_find_order_datum( - all_outputs, - datum_dict, - order_in_output, - ) - let is_valid_receiver_datum_hash = - when receiver_datum_hash_opt is { - Some(datum_hash) -> { - expect DatumHash(output_datum_hash) = order_output_datum - output_datum_hash == datum_hash - } - None -> order_output_datum == NoDatum - } - expect - receiver == output_address && batcher_fee > 0 && output_ada > 0 && is_valid_receiver_datum_hash && lp_asset == order_lp_asset + } = order_in_datum + expect batcher_fee > 0 && output_ada > 0 && lp_asset == order_lp_asset let new_state = when order_step is { SwapExactIn(direction, minimum_receive) -> { expect minimum_receive > 0 + expect + validate_order_receiver( + receiver: receiver, + receiver_datum_hash_opt: receiver_datum_hash_opt, + output: output, + ) let a_to_b_direction = when direction is { AToB -> True @@ -756,6 +855,12 @@ pub fn apply_orders( } SwapExactInStopLoss(direction, stop_loss_receive) -> { expect stop_loss_receive > 0 + expect + validate_order_receiver( + receiver: receiver, + receiver_datum_hash_opt: receiver_datum_hash_opt, + output: output, + ) let a_to_b_direction = when direction is { AToB -> True @@ -779,6 +884,12 @@ pub fn apply_orders( } SwapExactInOCO(direction, minimum_receive, stop_loss_receive) -> { expect minimum_receive > 0 && stop_loss_receive > 0 + expect + validate_order_receiver( + receiver: receiver, + receiver_datum_hash_opt: receiver_datum_hash_opt, + output: output, + ) let a_to_b_direction = when direction is { AToB -> True @@ -802,6 +913,12 @@ pub fn apply_orders( } SwapExactOut(direction, expected_receive) -> { expect expected_receive > 0 + expect + validate_order_receiver( + receiver: receiver, + receiver_datum_hash_opt: receiver_datum_hash_opt, + output: output, + ) let a_to_b_direction = when direction is { AToB -> True @@ -823,6 +940,12 @@ pub fn apply_orders( } Deposit(minimum_lp) -> { expect minimum_lp > 0 + expect + validate_order_receiver( + receiver: receiver, + receiver_datum_hash_opt: receiver_datum_hash_opt, + output: output, + ) validate_deposit( order_in_value: order_in_value, order_out_value: order_out_value, @@ -840,6 +963,12 @@ pub fn apply_orders( } Withdraw(minimum_asset_a, minimum_asset_b) -> { expect minimum_asset_a > 0 && minimum_asset_b > 0 + expect + validate_order_receiver( + receiver: receiver, + receiver_datum_hash_opt: receiver_datum_hash_opt, + output: output, + ) validate_withdraw( order_in_value: order_in_value, order_out_value: order_out_value, @@ -855,6 +984,12 @@ pub fn apply_orders( } ZapOut(direction, minimum_receive) -> { expect minimum_receive > 0 + expect + validate_order_receiver( + receiver: receiver, + receiver_datum_hash_opt: receiver_datum_hash_opt, + output: output, + ) let a_to_b_direction = when direction is { AToB -> True @@ -875,16 +1010,113 @@ pub fn apply_orders( pool_state: pool_state, ) } + PartialSwap( + direction, + io_ratio_numerator, + io_ratio_denominator, + hops, + minimum_swap_amount_required, + ) -> { + expect + io_ratio_numerator > 0 && io_ratio_numerator > 0 && hops > 0 + let a_to_b_direction = + when direction is { + AToB -> True + BToA -> False + } + let ( + new_reserve_a, + new_reserve_b, + new_total_liquidity, + new_liquidity_share, + new_root_k_last, + has_next_swap, + ) = + validate_partial_swap( + order_in_value: order_in_value, + order_out_value: order_out_value, + a_to_b_direction: a_to_b_direction, + io_ratio_numerator: io_ratio_numerator, + io_ratio_denominator: io_ratio_denominator, + hops: hops, + minimum_swap_amount_required: minimum_swap_amount_required, + asset_a: asset_a, + asset_b: asset_b, + batcher_fee: batcher_fee, + output_ada: output_ada, + trading_fee_numerator: trading_fee_numerator, + trading_fee_denominator: trading_fee_denominator, + pool_state: pool_state, + ) + expect + if has_next_swap { + let Output { + address: Address { + payment_credential: order_out_payment_cred, + .. + }, + datum: raw_order_out_datum, + .. + } = output + expect ScriptCredential(order_out_script_hash) = + order_out_payment_cred + let OrderDatum { + sender: order_out_sender, + receiver: order_out_receiver, + receiver_datum_hash_opt: order_out_receiver_datum_hash_opt, + step: order_out_step, + batcher_fee: order_out_batcher_fee, + output_ada: order_out_output_ada, + lp_asset: order_out_lp_asset, + } = + utils.must_find_order_datum( + datum_map, + raw_order_out_datum, + ) + expect PartialSwap( + order_out_step_direction, + order_out_io_ratio_numerator, + order_out_io_ratio_denominator, + order_out_hops, + order_out_minimum_swap_amount_required, + ) = order_out_step + order_out_script_hash == order_hash && // hihi + sender == order_out_sender && // hihi + receiver == order_out_receiver && // hihi + receiver_datum_hash_opt == order_out_receiver_datum_hash_opt && // hihi + batcher_fee == order_out_batcher_fee && // hihi + output_ada == order_out_output_ada && // hihi + order_lp_asset == order_out_lp_asset && // hihi + direction == order_out_step_direction && // hihi + io_ratio_numerator == order_out_io_ratio_numerator && // hihi + io_ratio_denominator == order_out_io_ratio_denominator && // hihi + hops - 1 == order_out_hops && // hihi + minimum_swap_amount_required == order_out_minimum_swap_amount_required + } else { + validate_order_receiver( + receiver: receiver, + receiver_datum_hash_opt: receiver_datum_hash_opt, + output: output, + ) + } + ( + new_reserve_a, + new_reserve_b, + new_total_liquidity, + new_liquidity_share, + new_root_k_last, + ) + } SwapMultiRouting(_, _) -> fail } apply_orders( - all_outputs: all_outputs, - datum_dict: datum_dict, + datum_map: datum_map, asset_a: asset_a, asset_b: asset_b, lp_asset: lp_asset, trading_fee_numerator: trading_fee_numerator, trading_fee_denominator: trading_fee_denominator, + order_hash: order_hash, profit_sharing_opt: profit_sharing_opt, order_inputs: inputs, order_outputs: outputs, diff --git a/lib/amm_dex_v2/types.ak b/lib/amm_dex_v2/types.ak index 9e76a42..f5ffbbc 100644 --- a/lib/amm_dex_v2/types.ak +++ b/lib/amm_dex_v2/types.ak @@ -1,3 +1,4 @@ +use aiken/dict.{Dict} use aiken/hash.{Blake2b_224, Blake2b_256, Hash} use aiken/transaction/credential.{Address, Script, VerificationKey} use aiken/transaction/value.{AssetName, PolicyId} @@ -16,6 +17,9 @@ pub type Asset { asset_name: AssetName, } +pub type DatumMap = + Dict, Data> + pub type ProfitSharing { fee_sharing_numerator: Int, fee_sharing_denominator: Int, @@ -63,6 +67,7 @@ pub type SwapRouting { // TODO: handle MultiRouting Order pub type OrderStep { + // TODO: Combine SwapExactIn, SwapExactInStopLoss & SwapExactInOCO to single one SwapExactIn { direction: OrderDirection, minimum_receive: Int } // TODO: SwapExactInStopLoss & SwapExactInOCO: Find another way that's easier to understand for users SwapExactInStopLoss { direction: OrderDirection, stop_loss_receive: Int } @@ -75,6 +80,13 @@ pub type OrderStep { Deposit { minimum_lp: Int } Withdraw { minimum_asset_a: Int, minimum_asset_b: Int } ZapOut { direction: OrderDirection, minimum_receive: Int } + PartialSwap { + direction: OrderDirection, + io_ratio_numerator: Int, + io_ratio_denominator: Int, + hops: Int, + minimum_swap_amount_required: Int, + } SwapMultiRouting { routings: List, minimum_receive: Int } } @@ -118,15 +130,15 @@ pub type BatchingPool { profit_sharing: Option, order_hash: ValidatorHash, address: Address, + delta_remaining_liquidity_supply: Int, pool_state_in: PoolState, pool_state_out: PoolState, } -pub type PoolState { - reserve_a: Int, - reserve_b: Int, - root_k_last: Int, - total_liquidity: Int, - liquidity_share: Int, - remaining_liquidity_supply: Int, -} +// Reserve A +// Reserve B +// Total Liquidity +// Liquidity Share +// Root K Last +pub type PoolState = + (Int, Int, Int, Int, Int) diff --git a/lib/amm_dex_v2/utils.ak b/lib/amm_dex_v2/utils.ak index e8e561b..f14217c 100644 --- a/lib/amm_dex_v2/utils.ak +++ b/lib/amm_dex_v2/utils.ak @@ -1,18 +1,16 @@ use aiken/builtin use aiken/bytearray use aiken/cbor -use aiken/dict.{Dict} -use aiken/hash.{Blake2b_256, Hash} +use aiken/dict +use aiken/hash use aiken/interval.{Finite} use aiken/list use aiken/string -use aiken/transaction.{ - Datum, DatumHash, InlineDatum, NoDatum, Output, ValidityRange, -} +use aiken/transaction.{Datum, DatumHash, InlineDatum, NoDatum, ValidityRange} use aiken/transaction/value.{ AssetName, PolicyId, Value, ada_asset_name, ada_policy_id, } -use amm_dex_v2/types.{Asset, FactoryDatum, OrderDatum, PoolDatum} +use amm_dex_v2/types.{Asset, DatumMap, FactoryDatum, OrderDatum, PoolDatum} const minus_ascii_code = 45 @@ -225,41 +223,33 @@ pub fn find_posix_time_range(time_rage: ValidityRange) -> (Int, Int) { (t1, t2) } -pub fn must_find_script_datum( - outputs: List, - datums: Dict, Data>, - output: Output, -) -> Data { - let data_option = - when output.datum is { - NoDatum -> None - DatumHash(dh) -> transaction.find_datum(outputs, datums, dh) - InlineDatum(dat) -> Some(dat) - } - must_parse_option(data_option) +pub fn find_script_datum(datums: DatumMap, datum: Datum) -> Option { + when datum is { + NoDatum -> None + DatumHash(dh) -> + datums + |> dict.get(dh) + InlineDatum(dat) -> Some(dat) + } +} + +fn must_find_script_datum(datums: DatumMap, datum: Datum) -> Data { + let datum_opt = find_script_datum(datums, datum) + must_parse_option(datum_opt) } -pub fn must_find_order_datum( - outputs: List, - datums: Dict, Data>, - output: Output, -) -> OrderDatum { - expect order_datum: OrderDatum = - must_find_script_datum(outputs, datums, output) +pub fn must_find_order_datum(datums: DatumMap, datum: Datum) -> OrderDatum { + expect order_datum: OrderDatum = must_find_script_datum(datums, datum) order_datum } -// TODO: Support both normal & inline datum -pub fn parse_pool_datum(datum: Datum) -> PoolDatum { - expect InlineDatum(data) = datum - expect pool_datum: PoolDatum = data +pub fn must_find_pool_datum(datums: DatumMap, datum: Datum) -> PoolDatum { + expect pool_datum: PoolDatum = must_find_script_datum(datums, datum) pool_datum } -// TODO: Support both normal & inline datum -pub fn parse_factory_datum(datum: Datum) -> FactoryDatum { - expect InlineDatum(data) = datum - expect factory_datum: FactoryDatum = data +pub fn must_find_factory_datum(datums: DatumMap, datum: Datum) -> FactoryDatum { + expect factory_datum: FactoryDatum = must_find_script_datum(datums, datum) factory_datum } diff --git a/plutus.json b/plutus.json index 84b1383..a8c780c 100644 --- a/plutus.json +++ b/plutus.json @@ -35,8 +35,8 @@ } } ], - "compiledCode": "59063201000032323232323232323222322322232533300b32323232533300f3370e90001807000899191919191919299980b19b87480000144c8c8c8c8c8c8c8c8c94ccc088c0940044c8c8c94ccc094c0a00084c8c8c8c8c94ccc09d4ccc09d4ccc09ccdc780280b899b8f00302214a0266e1c005200214a026464a666058605e00426464646464646464a666062a66606266e3c00d22101000013371e00291121ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000014a0294458dd7181a800981a8011bae3033001302b533302d3370e90021816000899191900119299981819b87480000044c8c8c8c94ccc0dcc0e800852616375c607000260700046eb8c0d8004c0b800858c0b8004c0cc004c0ac00458c0c4004c0c4004c0c0004c09c00458c0b4004cc0480348cdc399980b1bab302d302e30260010180234800858dd6981580098158011bae30290013029002375c604e0022c6eb0c098004c034004c02c00858cc02401c8cdd79812180e80080e1bab3022001302200130210023758603e002603e002603c0046eb0c070004c05002854ccc058cdc3a400400a2646464646464646464646464646464a66605060560042646464a66605066e1cccc05800406008d2002153330283370e66602c0020300429001099192999816981800109919191919191919191919191919299981c1919191919191919299982019b8f00700313372000a002266e4001c00cdd7182200098220011bae3042001303a00d375c608000260800046eb8c0f8004c0d802c4c94ccc0e4cdc3999813809014800a41fdfffffffffffffffe022a66607266e1ccc8c004004894ccc0f800452000133700900119801001182080098130092400c29445858ccccc8c88888c018cc014c018cc01401000cc018cc01400800488cdc500100091b9300100700500300116375c607800260780046eb8c0e8004c0c8014dd7181c000981c0011bae3036001302e003303400130340023032001302a002332232533302e3370e9000000899191919299981a981c0010991924c6010004600e0062c606c002606c004606800260580042c6058002464a66605a66e1d200000113232323253330343037002149858dd7181a800981a8011bae3033001302b00216302b001001302c00116302e001323300100100722533302d00114bd6f7b6300991929998161919299981719b87480080044cdd7804181998160010a50302c001302d002133030002330040040011330040040013031002302f0011616301300b302b00130230011630290013300e00c23370e6660246eacc0a4c0a8c088c0a4c0a8c08800405007d20023756604e002604e002604c002604a002604800260460046eacc084004c084004c080004c07c004c078008dd6180e000980a0050b11191980080080191299980e0008a5eb804c8c94ccc06cc0140084cc07c008cc0100100044cc010010004c080008c0780048c8cc004004008894ccc06800452f5bded8c0264646464a66603666e3d220100002100313301f337606ea4008dd3000998030030019bab301c003375c6034004603c00460380024646600200200444a666032002297ae0132333222323300100100322533301f001100313233322233024374e660486ea4024cc090dd4801998121ba80024bd700009bae301e001375a603e00266006006604600460420026eb8c060004dd5980c80099801801980e801180d80091119199119299980c99b874800800440084dd6980f180b801980b80119299980b99b87480080045300103d87a8000132323300100100222533301d00114c103d87a8000132323232533301e3371e014004266e95200033022375000297ae0133006006003375a603e0066eb8c074008c084008c07c004dd5980e180a801180a800a4000646600200200844a6660340022980103d87a8000132323232533301b3371e010004266e9520003301f374c00297ae0133006006003375660380066eb8c068008c078008c070004c040024dd7180a80098068008b18098009809801180880098048010a4c2c64a66601666e1d20000011533300e300900314985854ccc02ccdc3a40040022a66601c60120062930b0a99980599b874801000454ccc038c02400c52616163009002375c0026eb80048c014dd5000918019baa0015734aae7555cf2ab9f5740ae855d101", - "hash": "82f64e167d37cef78308d42b4639262fa88d147df743ffef77557dcb" + "compiledCode": "5906cc01000032323232323232323222322322232533300b32323232533300f3370e90001807000899191919191919299980b19b87480000144c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc0a4c0b00044c8c8c94ccc0b0c0bc0084c8c8c8c8c94ccc0b94ccc0b94ccc0b8cdc780280f099b8f00302914a0266e1c005200214a026464a666066606c00426464646464646464a666070a66607066e3c00d22101000013371e00291121ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000014a0294458dd7181e000981e0011bae303a001303232320023253330363370e9000000899191919299981e98200010a4c2c6eb8c0f8004c0f8008dd7181e000981a0010b181a00099299981a99b8748000c0d00044c0e8c0cc00458c94ccc0d4cdc3a4000002298103d87a8000153330353370e9001000899191980080080991299981d8008a6103d87a8000132323232533303c3371e00e004266e952000330400014bd70099803003001981e8019bae303b002303f002303d001375c60746066004266e95200033039303a30330024bd701819800981c000981c000981b80098170008b181a0009980c80a119b8733301d37566068606a605a00203e05490010b1bad30320013032002375c606000260600046eb8c0b800458dd61816800980a00098090048b19808007119baf302b30240010233756605200260520026050002604e002604c002604a00260480046eacc088004c088004c084008dd6180f800980f800980f0011bac301c001301400a153330163370e90010028991919191919191919191919191919299981418158010991919299981419b873330160010180234800854ccc0a0cdc399980b00080c010a400426464a66605a606000426464646464646464646464646464a6660706464646464646464a66608066e3c01c00c4cdc8002800899b90007003375c608800260880046eb8c108004c0e8034dd7182000098200011bae303e001303600b13253330393370e66604e024052002907f7fffffffffffffff808a99981c99b87332300100122533303e0011480004cdc024004660040046082002604c02490030a511616333332322222300633005300633005004003300633005002001223371400400246e4c00401c01400c00458dd7181e000981e0011bae303a0013032005375c607000260700046eb8c0d8004c0b800cc0d0004c0d0008c0c8004c0a8008cc88c94ccc0b8cdc3a4000002264646464a66606a60700042646493180400118038018b181b000981b001181a00098160010b1816000919299981699b87480000044c8c8c8c94ccc0d0c0dc00852616375c606a002606a0046eb8c0cc004c0ac00858c0ac004004c0b000458c0b8004c8cc00400401c894ccc0b400452f5bded8c026464a6660586464a66605c66e1d200200113375e010606660580042940c0b0004c0b40084cc0c0008cc0100100044cc010010004c0c4008c0bc0045858c04c02cc0ac004c08c00458c0a4004cc0380308cdc39998091bab3029302a30223029302a302200101401f48008dd59813800981380098130009812800981200098118011bab302100130210013020001301f001301e0023758603800260280142c44646600200200644a666038002297ae013232533301b300500213301f002330040040011330040040013020002301e0012323300100100222533301a00114bd6f7b630099191919299980d99b8f488100002100313301f337606ea4008dd3000998030030019bab301c003375c6034004603c00460380024646600200200444a666032002297ae0132333222323300100100322533301f001100313233322233024374e660486ea4024cc090dd4801998121ba80024bd700009bae301e001375a603e00266006006604600460420026eb8c060004dd5980c80099801801980e801180d80091119199119299980c99b874800800440084dd6980f180b801980b80119299980b99b87480080045300103d87a8000132323300100100222533301d00114c103d87a8000132323232533301e3371e014004266e95200033022375000297ae0133006006003375a603e0066eb8c074008c084008c07c004dd5980e180a801180a800a4000646600200200844a6660340022980103d87a8000132323232533301b3371e010004266e9520003301f374c00297ae0133006006003375660380066eb8c068008c078008c070004c040024dd7180a80098068008b18098009809801180880098048010a4c2c64a66601666e1d20000011533300e300900314985854ccc02ccdc3a40040022a66601c60120062930b0a99980599b874801000454ccc038c02400c52616163009002375c0026eb80048c014dd5000918019baa0015734aae7555cf2ab9f5740ae855d101", + "hash": "ee240c057b722beb4b3b62deca88b2f8db01ab028fc020a7ceb33d7b" }, { "title": "factory_validator.validate_factory", @@ -84,8 +84,8 @@ } } ], - "compiledCode": "590a880100003232323232323232322322322322322322223232323253330143232323253330183370e9001180b8008991919191919191919191919191919191919191919191919191929998191919191919191919299981d19b8f00700313372000a002266e4001c00cdd7181f000981f0011bae303c0013034011375c607400260740046eb8c0e0004c0c003c4c8c94ccc0d0cdc3a40006066002264646464646464646464a66607c66e1cccc0040080e80d120021323232323253330463049002132323232323232323232323232323232325333054533305453330545333054533305453330543372000e00a266e4000c004528099b8f00702d14a0266e3c0040ac528099b8f02200514a0266e3c08800c52809919299982c982e00109919191919191919191919191919191919191919191919299983699b8748008c1b00044c8c8c8c94ccc1c54ccc1c54ccc1c54ccc1c54ccc1c54ccc1c54ccc1c54ccc1c54ccc1c4cdd780a827099baf01304c14a0266e1c044004528099b8700f48000528099b8700d48000528099b884800002c528099b8848000024528099b8800b00914a0266e3c01c1a4528099299983919b8733303501a06e0400011533307232323370e646600200200444a6660f200229000099911919191919299983e99b8f0050791533307d533307d3371e0060e6266e1c005200214a0266e0001920021533307d533307d3371e0060e2266e1c005200214a0266e0001920021533307d533307d3371e006096266e1c00520feffffffffffffffff0114a0266e0001920021616375a6102020026102020046eb8c1fc004c1fc00cdd7183e8011bac307b00133002002307c00148018c8cc004004008894ccc1e000452f5c0264666444646600200200644a6660fc002200626466644466106026e9ccc20c04dd480499841809ba90033308301375000497ae0001375c60fa0026eb4c1f8004cc00c00cc20804008c20004004dd7183b8009bab307800133003003307c002307a001323300100105222533307700114bd6f7b630099191919299983c19b8f48900002100313307c337606ea4008dd3000998030030019bab3079003375c60ee00460f600460f200229445858cdc0a41fdfffffffffffffffe020022c6464a6660e466e20cdc1000800801099b800014800840054ccc1c4cdc4000a40002c2a6660e266e1c005200014800054ccc1c4cdc3800a4004290010a99983899b87001480105200213232333001001003002222533307533710002004266600600600266e0ccdc019b83005001001480104008cdc019b830014801120023370400400266606402e08007ca6660dca6660dc66e3c10d22010013371e0829110014a0266e0400520809bee0210013330300150420401630710013071002375c60de00260de0046eb4c1b4004c1b4008dd6983580098358011bad30690013069002375a60ce00260ce0046eb4c194004c194008c18c004c18c008c184004c164cc894ccc174cdc3a400860b8002264646400464a6660c066e1d20000011323232323232323232323232323232323232533307530780021323232498c94ccc1d4cdc3a400000226464a6660f460fa0042649319299983c19b87480000044c8c8c8c8c8c8c8c94ccc20c04c218040084c8c926325333082013370e9000000899192999843809845008010a4c2c6eb8c22004004c2000400c54ccc20804cdc3a40040022a66610a026100020062930b0b1840008011929998408099b87480000044c8c8c8c94ccc22004c22c040084c8c926325333087013370e90000008991929998460098478080109924c64a6661140266e1d200000113232533308f01309201002132498c0c400458c24004004c2200400854ccc22804cdc3a40040022646464646464a66612602612c020042930b1bad309401001309401002375a6124020026124020046eb4c24004004c2200400858c2200400458c23404004c2140400c54ccc21c04cdc3a40040022a66611402610a020062930b0b18428080118150018b184480800984480801184380800983f8020b183f8018b1842008009842008011841008009841008011bad308001001308001002375a60fc00260ec0042c60ec0022c60f600260e60082a6660ea66e1d200200115333078307300414985858c1cc00cc184040c18004458c1d8004c1d8008dd7183a000983a0011bad30720013072002375a60e000260e00046eb4c1b8004c1b8008dd6983600098360011bad306a001306a002306800130680023066001305e00216305e0013063001305b00116232533305d3370e900000089919299983118328010a4c2c6eb8c18c004c16c00854ccc174cdc3a400400226464a6660c460ca0042930b1bae3063001305b00216305b001001305f001305f002375660ba00260ba00260a80022c60b40026602c06c464646464646464a6660b866e1d200200113232533305e3371e0b0002266e1cccc084018168149200214a06eb8c188004c168008528182d000982f800982b8019bab305d001305d002305b001305300116375c60b000260b00046eb8c158004c138c014018dd7182a000982a0011bae3052001304a30010062533304c3370e900218258008991919001181f000982900098250008b182780098278009827000982280298258009825800982500098208018b18238009823801182280099800810919191919299982219baf00300a13370e66600e00208007490010a50375660900026090004608c002607c00244646600200200644a66608a002297ae013232533304430050021330480023300400400113300400400130490023047001162223233223253330443370e9001000880109bad3049304200330420023253330423370e90010008a6103d87a8000132323300100100222533304800114c103d87a800013232323253330493371e014004266e9520003304d375000297ae0133006006003375a60940066eb8c120008c130008c128004dd5982398200011820000a4000646600200200844a66608a0022980103d87a800013232323253330463371e010004266e9520003304a374c00297ae01330060060033756608e0066eb8c114008c124008c11c004dd598208009820801181f800981b800981e800981e800981a000981d00098190008b191980080080c91299981c0008a60103d87a80001323253330373375e6078606a00403c266e9520003303b0024bd70099802002000981e001181d0009999991911111803198029803198028020019803198028010009119b8a0020012372600200e00a0060022c6eb8c0d8004c0d8008dd7181a00098160049bae30320013032002375c6060002605000e6eb8c0b8004c0b8008dd71816000981200c981500098150011814000981000a1bab30260013026001302500237586046002604600260440046eb0c080004c060014c078004c05800458c070004c070008c068004c048014526163253330143370e9000000899191919299980d980f0010991924c600e004600c0062c603800260380046034002602400c2c602400a464a66602866e1d2000001132323232533301b301e002149858dd7180e000980e0011bae301a0013012002163012001300100423253330123370e9000000899191919299980c980e0010a4c2c6eb8c068004c068008dd7180c00098080010b18080009bae001375c0026eb8004dd70009bae001230053754002460066ea80055cd2ab9d5573caae7d5d02ba15745", - "hash": "98fdb425f4f11c6fecbbf782330c60242ad4efd3d194b02ad5a3b4f5" + "compiledCode": "590b450100003232323232323232322322322322322322223232323253330143232323253330183370e9001180b8008991919191919191919191919191919191919191919191919191919191919191919299981c9919191919191919299982099b8f00700313372000a002266e4001c00cdd7182280098228011bae3043001303b011375c608200260820046eb8c0fc004c0dc03c4c8c94ccc0eccdc3a40006074002264646464646464646464a66608a66e1cccc0040081040ed200213232323232533304d30500021323232323232323232323232323232323232533305c533305c533305c533305c533305c533305c3372000e00a266e4000c004528099b8f00702e14a0266e3c0040b0528099b8f02300514a0266e3c08c00c528099192999830983200109919191919191919191919191919191919191919191919299983a99b8748008c1d00044c8c8c8c94ccc1e54ccc1e54ccc1e54ccc1e54ccc1e54ccc1e54ccc1e54ccc1e54ccc1e4cdd780a827899baf01304d14a0266e1c044004528099b8700f48000528099b8700d48000528099b884800002c528099b8848000024528099b8800b00914a0266e3c01c1c4528099299983d19b8733303601a0760410011533307a32323370e646600200200444a666102020022900009991191919191929998428099b8f0050810115333085015333085013371e0060f6266e1c005200214a0266e00019200215333085015333085013371e0060f2266e1c005200214a0266e00019200215333085015333085013371e006098266e1c00520feffffffffffffffff0114a0266e0001920021616375a6112020026112020046eb8c21c04004c21c0400cdd71842808011bac3083010013300200230840100148018c8cc004004008894ccc2000400452f5c0264666444646600200200644a66610c02002200626466644466116026e9ccc22c04dd480499845809ba90033308b01375000497ae0001375c610a020026eb4c21804004cc00c00cc22804008c22004004dd7183f8009bab30800100133003003308401002308201001323300100105a22533307f00114bd6f7b63009919191929998400099b8f48900002100313308401337606ea4008dd3000998030030019bab308101003375c60fe00461060200461020200229445858cdc0a41fdfffffffffffffffe020022c6464a6660f466e20cdc1000800801099b800014800840054ccc1e4cdc4000a40002c2a6660f266e1c005200014800054ccc1e4cdc3800a4004290010a99983c99b87001480105200213232333001001003002222533307d33710002004266600600600266e0ccdc019b83005001001480104008cdc019b830014801120023370400400266606602e08207ea6660eca6660ec66e3c11122010013371e0849110014a0266e0400520809bee0210013330310150430411630790013079002375c60ee00260ee0046eb4c1d4004c1d4008dd6983980098398011bad30710013071002375a60de00260de0046eb4c1b4004c1b4008c1ac004c1ac008c1a4004c184ccc888c8c8008c94ccc1a0cdc3a40000022646464646464646464646464646464646464a6660fa61000200426464649319299983e99b87480000044c8c94ccc20804c214040084c926325333080013370e9000000899191919191919192999845809847008010991924c64a6661140266e1d200000113232533308f01309201002149858dd71848008009844008018a9998450099b874800800454ccc23404c2200400c5261616308801002325333089013370e90000008991919192999848009849808010991924c64a66611e0266e1d200000113232533309401309701002132498c94ccc24804cdc3a400000226464a66612e026134020042649318188008b184c008009848008010a9998490099b87480080044c8c8c8c8c8c94ccc26c04c2780400852616375a6138020026138020046eb4c26804004c26804008dd6984c008009848008010b1848008008b184a808009846808018a9998478099b874800800454ccc24804c2340400c5261616308d01002302a00316309101001309101002308f010013087010041630870100316308c01001308c01002308a01001308a01002375a6110020026110020046eb4c21804004c1f800858c1f800458c20c04004c1ec01054ccc1f4cdc3a40040022a6661000260f60082930b0b183d801983480818340088b183f000983f0011bae307c001307c002375a60f400260f40046eb4c1e0004c1e0008dd6983b000983b0011bad30740013074002375a60e400260e400460e000260e000460dc00260cc0042c60cc00266028004002464a6660ca66e1d200000113232533306a306d002149858dd7183580098318010a99983299b87480080044c8c94ccc1a8c1b400852616375c60d600260c60042c60c600207600260ce00260ce0046eacc194004c194004c17000458c188004cc05c0f88c8c8c8c8c8c8c94ccc190cdc3a400400226464a6660cc66e3c1800044cdc399981100303102d240042940dd7183500098310010a5030620013067001305f003375660ca00260ca00460c600260b60022c6eb8c180004c180008dd7182f000982b198028180039bae305c001305c002375c60b400260a46600205800e446464004608c002660060040024464a6660aa66e1d200030540011305a3053001163253330553370e90000008a60103d87a8000153330553370e9001000899191980080080291299982d8008a6103d87a8000132323232533305c3371e00e004266e952000330600014bd70099803003001982e8019bae305b002305f002305d001375c60b460a6004266e95200033059305a30530024bd701829800982b000982b000982a800982600298290009829000982880098240018b18270009827001182600099800814119191919299982599baf00300a13370e66600e00208e08290010a503756609e002609e004609a002608a00244646600200200644a666098002297ae013232533304b300500213304f002330040040011330040040013050002304e0011622232332232533304b3370e9001000880109bad3050304900330490023253330493370e90010008a6103d87a8000132323300100100222533304f00114c103d87a800013232323253330503371e014004266e95200033054375000297ae0133006006003375a60a20066eb8c13c008c14c008c144004dd5982718238011823800a4000646600200200844a6660980022980103d87a8000132323232533304d3371e010004266e95200033051374c00297ae01330060060033756609c0066eb8c130008c140008c138004dd5982400098240011823000981f00098220009822000981d8009820800981c8008b191980080081011299981f8008a60103d87a800013232533303e3375e6086607800404a266e952000330420024bd70099802002000982180118208009999991911111803198029803198028020019803198028010009119b8a0020012372600200e00a0060022c6eb8c0f4004c0f4008dd7181d80098198049bae30390013039002375c606e002605e00e6eb8c0d4004c0d4008dd718198009815810181880098188011817800981380d9bab302d001302d001302c001302b001302a001302900130280023756604c002604c002604a0046eb0c08c004c08c004c088008dd61810000980c002980f000980b0008b180e000980e001180d00098090028a4c2c64a66602866e1d2000001132323232533301b301e00213232498c01c008c01800c58c070004c070008c068004c04801858c0480148c94ccc050cdc3a4000002264646464a666036603c0042930b1bae301c001301c002375c603400260240042c60240026002008464a66602466e1d20000011323232325333019301c002149858dd7180d000980d0011bae30180013010002163010001375c0026eb8004dd70009bae001375c0024600a6ea80048c00cdd5000ab9a5573aaae7955cfaba05742ae881", + "hash": "8135810cb1f84d1ac4dd5b797370b1e111fbfb001b606f051c0b6922" }, { "title": "order_validator.validate_order", @@ -109,8 +109,8 @@ } } ], - "compiledCode": "59057101000032323232323232323223222232533300932323232533300d3370e9001180600089919299980799b87480000044c8c8cdc424000664600200244a66602c00229000099b8048008cc008008c064004c8cc004004008894ccc05800452f5c026464a66602a6464646464646464a66603a66e1d200200113371e0326eb8c088c06c008528180d8009810000980c000980f000980b000980e000980e000980980109980c80119802002000899802002000980d001180c0009bac3015001300d0051323232323232323232323232323232533301e3370e9000180e8008991919198008008049129998128008a501323253330243371e00400a29444cc010010004c0a4008dd718138009bae3024001301c001163022001301a00130200013018015332323232232533301f3370e900000089919191919191919191919191919299981818198010991919191924c64a66606466e1d20000011323232325333039303c002132498c07000c58dd6981d000981d001181c00098180050a99981919b87480080044c8c8c8c94ccc0e4c0f00084c926301c00316375a60740026074004607000260600142a66606466e1d20040011323232323232533303b303e002132498c07801458dd6981e000981e0011bad303a001303a0023038001303000a153330323370e9003000899191919299981c981e00109924c60380062c6eb4c0e8004c0e8008c0e0004c0c002854ccc0c8cdc3a401000226464a66606e60740042930b1bad3038001303000a153330323370e9005000899191919299981c981e0010a4c2c6eb4c0e8004c0e8008dd6981c00098180050a99981919b87480300044c8c8c8c94ccc0e4c0f00084c926301c00316375a60740026074004607000260600142a66606466e1d200e0011323232325333039303c002132498c8cc004004010894ccc0ec00452613233003003303f0023232533303a3370e9000000899191919299982098220010991924c604a00460460062c60840026084004608000260700042c6070002607a0022c6eb4c0e8004c0e8008dd6181c00098180050b1818004980a80519299981819b87480000044c8c94ccc0d4c0e000852616375c606c002605c0182a66606066e1d200200115333033302e00c14985858c0b802cc048030c04403458dd6981880098188011bad302f001302f002302d001302d002302b001302b00230290013029002302700130270023025001301d00216301d001232533301e3370e9000000899191919299981298140010991924c64a66604866e1d2000001132325333029302c002132498c94ccc09ccdc3a400000226464a666058605e0042649318080008b181680098128010a99981399b87480080044c8c8c8c8c8c94ccc0c0c0cc00852616375a606200260620046eb4c0bc004c0bc008dd6981680098128010b18128008b181500098110018a99981219b874800800454ccc09cc08800c52616163022002300900316302600130260023024001301c00216301c001232533301d3370e9000000899191919299981218138010a4c2c6eb8c094004c094008dd71811800980d8010b180d800919299980e19b874800000454ccc07cc068008526161533301c3370e90010008a99980f980d0010a4c2c2c6034002464a66603666e1d20000011323253330203023002149858dd71810800980c8010a99980d99b87480080044c8c94ccc080c08c00852616375c604200260320042c60320020286eb0c074004c074004c070004c06c004c068004c064004c060004c05c004c058004c034014c034020c02c00458c044004c044008c03c004c01c008526163253330093370e90000008a99980618038018a4c2c2a66601266e1d20020011533300c300700314985858c01c008dd7000918029baa001230033754002ae6955ceaab9e5573eae815d0aba21", - "hash": "b0f6c0d5498b2dc9753a4e667ecfcd1a0e1165a5d049957d8a7b6c02" + "compiledCode": "5905be01000032323232323232323223222232533300932323232533300d3370e9001180600089919299980799b87480000044c8c8cdc424000664600200244a66602c00229000099b8048008cc008008c064004c8cc004004008894ccc05800452f5c026464a66602a6464646464646464a66603a66e1d200200113371e0326eb8c088c06c008528180d8009810000980c000980f000980b000980e000980e000980980109980c80119802002000899802002000980d001180c0009bac3015001300d0051323232323232323232323232323232533301e3370e9000180e8008991919198008008049129998128008a501323253330243371e00400a29444cc010010004c0a4008dd718138009bae3024001301c001163022001301a00130200013018015332323232232533301f3370e900000089919191919191919191919191919299981818198010991919191924c64a66606466e1d20000011323232325333039303c002132498c07000c58dd6981d000981d001181c00098180050a99981919b87480080044c8c8c8c94ccc0e4c0f00084c926301c00316375a60740026074004607000260600142a66606466e1d20040011323232323232533303b303e002132498c07801458dd6981e000981e0011bad303a001303a0023038001303000a153330323370e9003000899191919299981c981e00109924c60380062c6eb4c0e8004c0e8008c0e0004c0c002854ccc0c8cdc3a401000226464a66606e60740042930b1bad3038001303000a153330323370e9005000899191919299981c981e0010a4c2c6eb4c0e8004c0e8008dd6981c00098180050a99981919b87480300044c8c8c8c94ccc0e4c0f00084c926301c00316375a60740026074004607000260600142a66606466e1d200e001132323232323232323232533303f3042002132498c08802458dd6982000098200011bad303e001303e002375a607800260780046eb4c0e8004c0e8008c0e0004c0c002854ccc0c8cdc3a4020002264646464a666072607800426493191980080080211299981d8008a4c26466006006607e0046464a66607466e1d20000011323232325333041304400213232498c094008c08c00c58c108004c108008c100004c0e000858c0e0004c0f400458dd6981d000981d0011bac3038001303000a163030009301500a3253330303370e900000089919299981a981c0010a4c2c6eb8c0d8004c0b803054ccc0c0cdc3a40040022a666066605c0182930b0b1817005980900618088068b1bad30310013031002375a605e002605e004605a002605a0046056002605600460520026052004604e002604e004604a002603a0042c603a002464a66603c66e1d20000011323232325333025302800213232498c94ccc090cdc3a400000226464a66605260580042649319299981399b87480000044c8c94ccc0b0c0bc0084c926301000116302d0013025002153330273370e90010008991919191919299981818198010a4c2c6eb4c0c4004c0c4008dd6981780098178011bad302d001302500216302500116302a0013022003153330243370e90010008a99981398110018a4c2c2c604400460120062c604c002604c004604800260380042c6038002464a66603a66e1d200000113232323253330243027002149858dd7181280098128011bae3023001301b00216301b001232533301c3370e90000008a99980f980d0010a4c2c2a66603866e1d20020011533301f301a00214985858c0680048c94ccc06ccdc3a400000226464a66604060460042930b1bae302100130190021533301b3370e900100089919299981018118010a4c2c6eb8c084004c06400858c064004050dd6180e800980e800980e000980d800980d000980c800980c000980b800980b0009806802980680418058008b18088009808801180780098038010a4c2c64a66601266e1d20000011533300c300700314985854ccc024cdc3a40040022a666018600e0062930b0b18038011bae001230053754002460066ea80055cd2ab9d5573caae7d5d02ba15745", + "hash": "c03b1ddfe2dd5ae80a8cfc5e64ad8dddc5f9b05e9dc5297dbb65f93b" }, { "title": "pool_validator.validate_pool", @@ -158,8 +158,8 @@ } } ], - "compiledCode": "592c0a0100003232323232323232322322322322322322223232323232323232533301832323232533301c3370e9001180d8008991919191919191919191919191919191919191919191919299981a19b87480000584c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc12ccccccccc09c0400180100581140480fc0284cccccccccc8c8c8c8c8c8c8c8c8888888888c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc1e14ccc1e14ccc1e0cdd79ba7003374e038266e1cc12c010c12400c528099b87304b002304b00114a02a6660f066e1cc12c008c12c0044c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc278054ccc278054ccc278054ccc278054ccc278054ccc27804cdc380680c899b8700b01714a0266e1c02404c528099b8700701114a0266e1c01405452808008a5014a22c66e1c00ccdc080100099b8100d0193370201c03466e0403c06cdd6984f00800984f008011bad309c01001309c01002375a6134020026134020046eb4c26004004c26004008dd6984b008009919199980080080e00d8011111299984c00801880089919299984d008020801899191919191919191919191919191919191919191919191919191919299985980a99985980a99985980a99985980a9998598099baf00c01313371090000020a5013371090000010a50100114a0266ebc1380205280999981101100e80d99299985a0099b87480000044c8c8c8c94ccc2e004cdc424000002264666666666660d003602e0020b00ac0140100a40a004a466e2400c004c94ccc2e404cdc3a40000022944528185b808018b1bad30bc0100130bc0100230ba0100130b201007153330b4013370e9001000899191919299985c0099b88480000044c8ccccccccccc1a006c05c0041601580280201481400948cdc480080199299985c8099b87480000045288a5030b70100316375a61780200261780200461740200261640200e2a6661680266e1d2004001132323232323253330ba0153330ba01337109000001899b88480000045280991999999999983500e80c80082d02c00600502a0290139299985e0099b8900500114a2266e2400400cc94ccc2ec04cdc3a40000022944528185c808028b1bad30be0100130be01002375a61780200261780200461740200261640200e2a6661680266e1d200600113232323253330b80133710900000089999999999111111111919191919191919191919191919191919191919191919191919191919191919191919299987200a99987200a9998720080408028a50100114a02a6661c8020582661d0026ea0cdc001180319874009ba833702042056661d0026ea007ccc3a004dd400e99874009ba801b4bd70099874009ba833702046056661d0026ea0cdc001080319874009ba801f330e801375003a661d0026ea006d2f5c02ca6661c602661740202001c2a6661c60266e1c00c0a84cdc380119b813370004c01000a294054ccc38c04cc2e80403002854ccc38c04cdc380199b8002a02613370e00266e040200145280a99987180a9998718099b8700302a13370e00266e04020014528099b8700202614a06661740208001e01a6661720207e9101004881003330b80103e00900733712002008a6661bc0266e1d200030dd010011375a61c60261b8020022ca6661ba0266e240300905300103d87a800013374a900019870809ba83370066e0ccdc119b8200e02401e3370466e04030090cdc080f00fa400497ae0337109000000a99986d809985900804003099b810013370003e03c20026661640207800e00a6eb8c37804004c37804008dd7186e00800986a008049bae30da0100130da01002375c61b00200261a00200e6eb4c35804004c35804008dd6986a00800986a00801186900800986900801186800800a9998650080909986700808198670080799867009ba8009330ce01375000e97ae01330ce0100f330ce01010330ce01375000e6619c026ea00252f5c06eb4c33804004c33804008dd69866008009866008011bad30ca0100130ca01002375a6190020026190020046eb4c31804004c94ccc2e404cdc3a40000022944528185b8080180082b82a8048038288278120b1bad30bc0100130bc0100230ba0100130b201007153330b4013370e900400089919299985b0099b88480000044c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc36c054ccc36c054ccc36c04034402452808030a501330df01375000a661be026ea0010cc37c04dd419b8033700042014004661be026ea0cdc000f8011986f809ba80014bd700b1bad30dc01002375a61b40200264a6661b20266e1d20000011323232337606ea0ccccc23004078030088dd69870808009bad30e10130e2010013750611e0266e08018014c36404004c37c04004c35c041b84cdd8261010000375003661ae020da66e0007c02ccdc0010004a99986a8099b8700102413370e0040082940ccc2b0040c92201004881003330ab0103100b0093371203a0026eb4c34c04008dd6986880800991929998688099b880010021323232323232337606ea0cdc019b833370466e00cdc101080200299b813370403e00200466e080100052002375066e0ccdc119b803370401600200403a66e04cdc100f8008011bad30d801002375a61ac0200266666610c0203c0380040020da0d66eb4c35404008dd69869808009999998410080200280d80c8350340a9998688099b880020011323232323232337606ea0cdc019b833370466e00cdc100f80200299b813370404200200466e080100052002375066e0ccdc119b803370401400200403a66e04cdc10108008011bad30d801002375a61ac0200266666610c0203803c0040020da0d66eb4c35404008dd69869808009999998410080280200c80d835034099bb0375066e0806c064dd400119b833370400802c03066e0ccdc100100a80ca99986700a9998670099b89480000044cdc4a400000429404cdc42400066e000040085282999866809985200806805899b810023370003c03820046661480205c01000c6661460205a0160126eb8c33c04004c33c04008dd71866808009862808311bae30cb0100130cb01002375c6192020026182020c06eb8c31c04004c31c04008dd7186280800985e8082f1bad30c30100130c301002375a6182020026182020046eb4c2fc04004c2fc04008dd6985e80800985e808119bad30bb0102216375a61740200261640200e2a6661680266e1d200a00113232323253330b80153330b801337109000001899b88480000045280991919191919191919191919191919191919191919191919191919191919191919191919299986e00a99986e00a99986e0080708050a50100614a02661c0026ea0014cc38004dd400219870009ba83370066e0408003c008cc38004dd419b8001e002330e001375000297ae016375a61ba020046eb4c36c04004c94ccc36804cdc3a4000002264646466ec0dd4199998468080e99b82025023021375a61c4020026eb4c38804c38c04004dd418480099b8200600530da0100130e00100130d80106f133760981010000375003461b0020dc66e0407801ccdc080f803a99986b00998568080a0090a99986b0099b870033370000c04a266e1c0080145280a99986b00a99986b0099b8700102513370e00600c29404cdc38010028a503330ad01033489004881003330ac0103200e00c3330ab0103101100f53330d2013371203a004266e2406c0045281bad30d301002375a61a20200266661060202e02a00402666e2120000013330a50102f003001375c61a20200261a2020046eb8c33c04004c31c04190dd71866808009866808011bae30cb0100130c301062375c6192020026192020046eb8c31c04004c2fc04180dd69862808009862808011bad30c30100130c301002375a6182020026182020046eb4c2fc04004c2fc04094dd6985e808120b1bad30bc0100130bc01002375a61740200261640200e2a6661680266e1d200c00113232323253330b8013371090000008999999999911111111191919191919191919191919191919191919191919191919191919191919299986f80a99986f80a99986f8080588020a50100114a02a6661be0204e2661c6026ea0078cc38c04dd419b8101c008330e301375066e00cdc080d00600319871809ba83370003000c661c6026ea00152f5c02661c6026ea0cdc080f00419871809ba801c330e301375066e00cdc080d00600319871809ba83370003000c661c6026ea00152f5c02ca6661bc026616a02024020266e1c004cdc00110038a99986f0099b8700100713370e0440042940ccc2d4040ec04403cccc2d0040e922100488100337120480086eb4c37004008dd6986d0080099299986c8099b87480000044c8c8c8cdd81ba83333308c010133370403603202e6eb4c38404004dd69870809871008009ba8308f0100630d90100130df0100130d70101c133760981010000375002061ae020366eb4c36404008dd6986b80800991919191919bb0375066e08008004dd4299986d00811099b80003333330a70100200100401c01b1337000086666614e0200200400603803666e04058008cdc080b8011bad30d901002375a61ae0200266661120202802400402066e2120000013330ab01035003001375c61ae0200261ae020046eb8c35404004c33404050dd71869808009869808011bae30d10100130c90100153330ca0101210101011375a619c02002619c020046eb4c33004004c33004008dd69865008009865008011bad30c80100130c801002375a618c0200264a6661720266e1d200000114a22940c2dc0400c15c15414c01c13414413c09058dd6985e00800985e00801185d0080098590080389931859008039859008030b1929998598099b87480000044c8c94ccc2d404cdc3a4004616802022266e3cdd7185d009859808088008b1bae30b90100130b10100a13375e01e98103d879800030b101009375a616c02002616c020046eb4c2d004004c2d004008c2c804004c2c804008c2c004004c2c004008c2b804004c2b804008c2b004004c2b004004c28c04ccc1cc138134028c2a404004c2a404008dd5985380800985380801185280800984e808041bab30a30100130a301001309a0100130a00100130a001001309701004309e01005309c01004309c01004309a010033309401375002e66128026ea0054cc25004dd40089984a009ba800f3309401375002697ae0375a6128020026128020046eb4c24804004c24804008dd69848008009848008011bad308e01001308e01002375a6118020026118020046eb4c22804004c20804044dd69844008009844008011bad308601001308601002375a6108020026108020046eb4c20804004c20804008dd69840008009840008011bad307e001307600716163304c02023232533307a33307a3375e00201694128899983d19baf00101f4a0944528183f000983b0009919980080080125eb808894ccc1f000840044ccc00c00cc1fc008cc88cc1fcc160cc16401c008004dd6983f001000981100c9982480f11919191919191919299983e99b87480080044cdc79bae308201307b00201014a060f600261000200260f000260fc00260ec00260f800260f800260e600260f000260f000460ec00260ec00460e800260e80046eb8c1c8004c1c8008c1c0004c1c0008dd6983700098370011bad306c001306c002306a001306a002306800130680023066001305e3333303600200100c00b0063061002305f0013232533306230650021323232323232323232533306b306e002132533306c306f001132533306d30700011337600180062c6607c024466ebcc1bcc1a0c1bcc1a000401458cc0f40488cdd798371833983718339837183798338008020b18360009981d807919baf004306c3065001306a00130620013068001306000130660013066001305d0011630630013303200723375e00a60c660b8002600200244a6660ae002297ae0132323305a375000466008008646600200200444a6660b6002297ae013232533305a33305a3370e00400c9412889982f1ba800233004004001133004004001305f002375a60ba00260b60046eb4c16400488888888888c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc1f14ccc1f14ccc1f0014400c52808008a501533307c02913308001375066e00080018cc20004dd419b8101e0043308001375003866100026ea0068cc20004dd400c25eb804cc20004dd419b810200043308001375066e00078018cc20004dd400e19840009ba801a3308001375003097ae016533307b3305200900713370e66e0000c0900044c94ccc1f0cdc3802001099b8700102514a06660a6052910100488100333052028008006301e0013333304500e00c00202001f337109000000a99983b19826804003099b810013370004003e200266609a04800e00a6eb8c1e4004c1e4008dd7183b80098378049bae30750013075002375c60e600260d600e6eb4c1c4004c1c4008dd698378009837801183680098368011835800a99983280909983480899834808198349ba800933069375000e97ae01330690103306901133069375000e660d26ea00252f5c06eb4c1a4004c1a4008dd6983380098338011bad30650013065002375a60c600260c60066eb4c184008888894ccc154cdc4802a400029000099299982b19b880060011323232533305933710900000088008a400066e0c008004cdc019b823370200600800466e0801001ccdc119b820030043370200200c2900018040021111111919191919bb0375066e04c030cdc0980700099b823370400600a66e04014018004dd419b820023370200a00c66e08cdc099b824801001001400ccdc12400866e0001c014cdc119b8248020cdc000300219b813370400c601600a66e08cdc100380280219b823370000a0060084444446466ec0dd419b823370400a00200c6ea0cdc019b823370400400800e66e08014004cdc08008011299982719b88001480005854ccc138cdc3800a4000290000a99982719b8700148008520021533304e3370e00290020a400426464666002002006004444a6660a466e200040084ccc00c00c004cdc199b803370600a0020029002080119b8033706002900224004444466ec0dd419b83337040040080026ea0cdc199b8200200300123370400200208e08602001a00205c07c02c0282c6eacc13c004c13c004c138008dd61826000982600118250009825000982480098240011bab30460013046001304500237586086002608600260840046eb0c100004c0e0084dd6981f000981f0011bac303c001303c002303a0013032026153330343370e900100b099191919191919191919299981f299981f19b8700200113371290020008a5013232323232323232323232323232323232533304f3333333302b01000600401a04901804300a1333333333323232323232322222222223232323232323232323232323232323253330723075002132325333074307700213232323232323232323232323232323232323232323232323232533308b01533308b01533308b01533308b01533308b013375e018026266e21200000414a0266e21200000214a0200229404cdd78140040a50132533308c013370e900700089919191929998480099b88480000044c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc2bc04cdc4810000899192999858808008a511653330b001330870100700513370e66e0000809c0044c94ccc2c404cdc3801801099b8700102814a06661100206c9101004881003330870103500600416333305b0014800013c0854ccc2b404cc210040200184cdc080099b80026024100133308401036007005375c6160020026160020046eb8c2b804004c29804014dd71856008009856008011bae30aa0100130a2010023253330a4013370e9000000880188029851008051929998518099b874800000440204018c28404030c29804004c29804008c29004004c2700402cc28804004c28804008c28004004c26004020c27804004c27804004c25404018c26c04004c26c04004c24804010cc0f80d0cdc0983301a240046607a06690001981e00219b81306400448008cc0ec00d200016375a6128020026128020046eb0c24804004c2280401c5281845008030b1929998458099b87480000044c8c94ccc23404cdc3a4004611802022266e3cdd71849009845808088008b1bae30910100130890100a13375e01e98103d8798000308901009375a611c02002611c020046eb4c23004004c23004008c22804004c22804008c22004004c22004008c21804004c21804008c21004004c21004004c1ecccc12c09008c028c20404004c20404008dd5983f800983f801183e800983a8039bab307b001307b001307200130780013078001306f0031630750013304401623232323253330743330743375e00603094128899983a19baf0010084a0944528183c0009838000983b00098370008b18398009982100a91919191919191919299983b19b87480080044cdc79bae307b307400200e14a060e800260f200260e200260ee00260de00260ea00260ea00260d800260e200260d200260de00260de0046eb8c1b4004c1b4004c1b0004c1ac004c1a8008c1a0004c1a0004c19c004c178cc02c005200032323232325333067306a002132323232323232533306b3370e607c66080026466ebcc1c4c1a8c1c4c1a8c1c4c1c8c1a800400802854ccc1accdc3981f19820009119baf3071306a3071306a00100200a13233300100100d00c22253330710021533307100114bd700b0991929998398018a5eb804cc1d0c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc200054ccc20004cdd78058030991919191919191919191919191919191919191919191919191919191919191919191919299985200a99985200a99985200a99985200a99985200a99985200a99985200a9998520099baf02301113375e04201e29404cdc380f8068a5013370e03a01629404cdc380d8048a5013370e03200e29404cdc380b8028a5013371e02a00629404cdd78098008a5030a80100130a801002375c614c02002614c020046eb4c29004004c29004008dd69851008009851008011bad30a00100130a001002375a613c02002613c020046eb4c27004004c27004008c26804004c26804008c26004004c2400404cc25804004c25804008dd7184a00800984a008011bad309201001309201002375a6120020026120020046eb4c23804004c23804008dd69846008009846008011bad308a01001308a01002308801001308801002308601001307e00214a02666660ac0240200540520042c60b000460ae00c61040200261040200261020200460fe00260ee01260fa00260fa00260f800460f400260e400260f000260f000260de00660ea00666600a00a00260ec00660ea00660e60042c2c60de00260ce00260da00260ca00260d600260d600260c40022c60d00026606e014466ebc020c1a0c184004c0d0008cc03c0088cc030020004cc0380088cc02c020004c0040048894ccc15ccdc4a4028002266600600660ba60ba60ba60ba60ba60ba60ba60ba60ba60ba00466e040052014133007002001300100122222533305a002100313232533305c003100513232323333300a00a00100100400232323232323232323232323232323232323232323232323232323253330763375e0300062646464a6660f266e212000026132533307a3371090000008a99983d19299983d99b874800000454ccc1eccdc399b8001002800c13370e66e040380080285280a99983d99b8733702020004018266e1ccdc00070140050a503079005100116163333304600200102601901716375a60f40046eb4c1e0004c94ccc1dccdc3a4000002266ec0dd40061ba800a1337606ea0028dd4006183a8008b183d000983d001183c000983800c9bad30760013076002375a60e800260d800a6eb4c1c8004c1c8008dd69838000983400198370009837001183600098360009835800983500098348011bad30670013067002375a60ca00260ca00460c600260c600260c400260b200860c000860bc00660bc00660b800444646600200200644a6660b0002297ae01330593003375a60b40026600400460b60026002002444a6660a466e240052000130570021333003003305800233702002900102582380800680081900d00b00a0b1bab305300130530013052002375860a000260a0004609c002609c002609a00260980046eacc128004c128004c124008dd61823800982380098230011bac3044001303c02516300e002300d0033758608000260800046eb0c0f8004c0f8008dd6981e000981e001181d00098190130a99981a19b87480100584c928981901309925130320262222232323370666e08004018cdc019b820030070013370400200866e04004008888c8c8008c94ccc0dccdc3a400000226464646464646464646464646464a6660906096004264646464649319299982519b87480000044c8c8c8c94ccc144c1500084c926301e00316375a60a400260a400460a000260900142a66609466e1d200200113232323253330513054002132498c07800c58dd698290009829001182800098240050a99982519b87480100044c8c8c8c8c8c94ccc14cc1580084c926302000516375a60a800260a80046eb4c148004c148008c140004c12002854ccc128cdc3a400c002264646464a6660a260a800426493180f0018b1bad305200130520023050001304800a1533304a3370e900400089919299982798290010a4c2c6eb4c140004c12002854ccc128cdc3a4014002264646464a6660a260a80042930b1bad30520013052002375a60a000260900142a66609466e1d200c00113232323253330513054002132498c07800c58dd698290009829001182800098240050a99982519b87480380044c8c8c8c94ccc144c1500084c9263303800323253330503370e9000000899191919299982b982d0010991924c604a00460820062c60b000260b000460ac002609c0042c609c0022c6eb4c148004c148008dd6182800098240050b1824004981a805181b005981a00618198068b1bad30490013049002375a608e002608e004608a002608a0046086002608600460820026082004607e002607e004607a002606a0042c606a00260246464a66606e66e1d200000114c0103d87a8000153330373370e90010008991919299981d19b87480080044c94ccc0f8004530103d87a800013374a90001981f9820000a5eb80c8cc004004024894ccc0fc00452f5c0264646464a66608066e1d20020011330060060031330443045303e00233006006003303e001323253330403370e900200089919299982119b8f37286ecc00402c4cdd2a40006608c00297ae014c0103d87a80003046001303e00214c103d87a8000303e001300d303c0023043002304100110023038001323300100100622533303d00114c103d87a8000132323232533303e3371e00e004266e952000330420014bd70099803003001981f8019bae303d0023041002303f001375c6078606a004266e9520003303b303c30350024bd70181a800980218198009181b981c181c000919299981919b874800000454ccc0d4c0c000852616153330323370e90010008a99981a98180010a4c2c2c6060002600200244a66606600229000099b8048008cc008008c0d8004c004004894ccc0c400452000133700900119801001181a0009119198008008019129998190008a5eb804c8c94ccc0c4c0140084cc0d4008cc0100100044cc010010004c0d8008c0d000488888c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc158c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc1d14ccc1d14ccc1d14ccc1d14ccc1d0cdd780e807099baf01b00c14a0266e1c05801c528099b8701400514a0266e3c04800c528099baf01000114a060f000260f00046eb8c1d8004c1d8008dd6983a000983a0011bad3072001307200130710013070001306f002306d001306d002306b001306301830690013069002375c60ce00260ce0046eb4c194004c194008dd698318009831800983100098308009830001182f000982f001182e000982a014099191919191919191919299983019b8733303802b0340334800854ccc180cdc399981c01401a019a4004264646466e95200033067027330670253306700433067375003a660ce6ea006ccc19c05ccc19cdd480c998338181983399ba548000cc19cc190004cc19cdd419981d817004003198339ba8021330673750046660ce6ea007ccc19cdd419981d81701b802a5eb80cc19ccdd2a4000660ce60ca002660ce6ea0ccc0ec0ac020018cc19cdd4008198339ba801233067375001c660ce6ea0ccc0ec0ac0dc0152f5c097ae053330623303900b0091337606ea0cdc08012410137dc046ea0cdc0800a410137dc04266ec0dd40011ba800133303902900a00833303802b00900716163374a9000198319ba903333063375200297ae0303833039303833039007005303833039003001375c60c400260c40046eb8c180004c160070dd7182f000982f0011bae305c001305401a16375a60b400260b40046eb4c160004c160008dd6982b000982b000982a80098260009813009982880098288011bae304f001304f002375a609a002609a0046eb4c12c004c12c008dd6982480098248011bad30470013047002375a608a002608a004608600260860046082002607201a607e002607e0046eacc0f4004c0f4004c0d002cdd5981d000981d001181c0009818000981b000981b000981680291299981599b8f00248810013371e0029110014a044464664464a66605e66e1d200200110021375a6068605a006605a00464a66605a66e1d200200114c103d87a8000132323300100100222533303300114c103d87a800013232323253330343371e014004266e95200033038375000297ae0133006006003375a606a0066eb8c0cc008c0dc008c0d4004dd5981918158011815800a4000660180060044a66605066e1d2004302700113232320023016001302e001302600116237260024466e28008004888888894ccc0b0c94ccc0c0c8cc004004008894ccc0c800452f5c0264666444646600200200644a66607000220062646664446607a6e9ccc0f4dd48049981e9ba90033303d375000497ae0001375c606e0026eb4c0e0004cc00c00cc0f0008c0e8004dd718188009bab3032001330030033036002303400114a22c646600200200444a666062002297adef6c6013232323253330323371e911000021003133036337606ea4008dd3000998030030019bab3033003375c6062004606a00460660022a666058646464646464646464646464a66607066e1d2000303700113232533303a533303a533303a323300100101522533303f00114a026464a66607c66e3c00801452889980200200098218011bae304100113371200a01029404cdc480419b8000601014a0294458dd7181f000981b0008b181e000981a0079bad3037002375a606a00264a66606866e1d20023033001132323253330373370e9001181b000899bb037500046078606a0022c602c60686076607860680226eb4c0e8004c0c800458c04cc0c4c04cc0c4038c8c94ccc0dcc0e80084c8c94ccc0d8cdc3800a400426464666002002900024000444a66607466e1c00801040044c94ccc0ed4ccc0eccdc3801a4000266e1c005205a14a0266e08ccc010010cdc0001a400400490008a99981da99981da99981d99b8800148180528899b8800148180528899b88337009030240240022c266600800866e0000d20023370066e08009201433702002903019b8e006002371a0042c6eb4c0dc008dd7181a8008b181c000999119299981a99b874800800440084dd5981d181980198198011980980080525eb7bdb180dd5981b000981b00098168009819800981980098151804998050040018a511616253330243370e900018118008981498110008b180080091129998138010a60103d87a80001323253330263370e0069000099ba548000cc0a80092f5c0266600a00a00266e0400d2002302b00330290022302600122323300100100322533302600114c103d87a800013232323253330273371e00e004266e9520003302b374c00297ae0133006006003375660500066eb8c098008c0a8008c0a0004c074040c088004c06800458c080004c080008c078004c058024526163253330183370e90000008991919191919299981098120010991924c6601200846eb4004c03001458dd6981100098110011bac30200013020002301e001301600a153330183370e90010008991919191919191929998119813001099191924c6601800646eb4004cc02c0108dd680098070038b1bac302400130240023758604400260440046eb4c080004c080008c078004c05802854ccc060cdc3a400800226464a66603a60400042930b1bad301e001301600a153330183370e9003000899191919299980f98110010a4c2c6eb4c080004c080008dd6980f000980b0050b180b00491191980080080191299980e8008a4c2646600600660420046006603e0026002010464a66602c66e1d20000011323232323232323232323232323232323232533302b302e0021323232498c94ccc0accdc3a400000226464a66606060660042649319299981719b87480000044c8c8c8c8c8c8c8c94ccc0e4c0f00084c8c9263026002302400316303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0b000858c0b000458c0c4004c0a401054ccc0accdc3a40040022a66605c60520082930b0b1814801980b008180a8088b181600098160011bae302a001302a002375a605000260500046eb4c098004c098008dd6981200098120011bad30220013022002375a60400026040004603c002603c004603800260280042c6028002464a66602a66e1d2000001132323232533301c301f002149858dd7180e800980e8011bae301b001301300216301300123253330143370e9000000899191919299980d980f0010991924c64a66603466e1d200000113232533301f3022002132498c94ccc074cdc3a400000226464a666044604a0042649318078008b1811800980d8010a99980e99b87480080044c8c8c8c8c8c94ccc098c0a400852616375a604e002604e0046eb4c094004c094008dd69811800980d8010b180d8008b1810000980c0018a99980d19b874800800454ccc074c06000c52616163018002300800316301c001301c002301a001301200216301200123253330133370e900000089919299980c180d8010a4c2c6eb8c064004c04400854ccc04ccdc3a40040022a66602c60220042930b0b1808800919299980919b87480000044c8c94ccc05cc06800852616375c603000260200042a66602466e1d2002001132325333017301a002149858dd7180c00098080010b18080009bad001375c0026eb8004dd70009bae001230053754002460066ea80055cd2ab9d5573caae7d5d02ba157441", - "hash": "9966ddb6b98dc774d30b0360656ee0a42402adc89faef105cb3fafd8" + "compiledCode": "5930e10100003232323232323232322322322322322322223232323232323232533301832323232533301c3370e9001180d800899191919191919191919191919191919191919191919191919299981a99b874800005c4c8c8c8c8c8c94ccc0ed4ccc0eccdc4a4000002266e212000301500314a026464646464646464646464646464646464a6660986666666605002000c00802c08c02408001426666666666464646464646464644444444446464646464646464646464646464646464646464646464646464646464a6660f6a6660f6a6660f666ebcdd38019ba701e13370e609600860aa00629404cdc3982580118258008a501533307b3370e609600460960022646464646464646464646464646464646464646464646464646464a66612c02a66612c02a66612c02a66612c02a66612c02a66612c0266e1c0300584cdc380500a0a5013370e01002429404cdc38030080a5013370e00801c294040045280a51163370e00466e0400408ccdc080700a99b8100f016375a612e02002612e020046eb4c25404004c25404008dd69849808009849808011bad309101001309101002375a611e0200264666600200202202002c4444a66612002006200226464a666124020082006264646464646464646464646464646464646464646464646464646464a66615602a66615602a6661560266e21200000313371090000008a5013375e08a00e29404cccc08808807406cc94ccc2b004cdc3a4000002264646464a6661600266e212000001153330b00133307d01000e0211323333333333305f01b01600104f04d00900704904702523371200600264a6661620266e1d200000114a22940c2bc0400c5858dd6985a00800985a008011859008009855008030a9998560099b87480080044c8c8c8c94ccc2c004cdc4240000022a666160026660fa02001c042264666666666660be03602c00209e09a01200e09208e04a466e2400400cc94ccc2c404cdc3a400000229445281857808018b0b1bad30b40100130b40100230b20100130aa01006153330ac013370e90020008991919191919299985900a9998590099b884800000c4cdc424000002294054ccc2c804ccc1fc04804008c4c8ccccccccccc18407406000414413c02c02412c12409c94ccc2d004cdc48028008a5113371200200664a6661660266e1d200000114a22940c2c4040145858dd6985b00800985b008011bad30b40100130b40100230b20100130aa01006153330ac013370e900300089919191929998580099b884800000454ccc2c004ccc1f40400380844ccccccccc888888888c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc36c054ccc36c054ccc36c0401c401452808008a50153330db0102b1330df01375066e00088018cc37c04dd419b8102002a330df01375003c661be026ea0070cc37c04dd400d25eb804cc37c04dd419b8102202a330df01375066e00080018cc37c04dd400f1986f809ba801c330df01375003497ae01653330da01330ae0100f00d153330da013370e006052266e1c008cdc099b8002500700514a02a6661b4026615c020160122a6661b40266e1c00ccdc0014812899b870013370200e00a294054ccc368054ccc36804cdc3801814899b870013370200e00a29404cdc38010128a503330ae0103e00e00c3330ad0103d4881004881003330ac0103c00800633712002006a6661aa0266e200900304cdc019b833370466e08038090078cdc119b8100c0243370203c03e90010b19b88480000054ccc34c04cc29c040200184cdc080099b8001f01e10013330a70103c007005375c61ac0200261ac020046eb8c35004004c33004024dd71869008009869008011bae30d00100130c801007375a619c02002619c020046eb4c33004004c33004008c32804004c32804008c320040054ccc308040484cc31804040cc3180403ccc31804dd400499863009ba80074bd7009986300807998630080819863009ba8007330c601375001297ae0375a618c02002618c020046eb4c31004004c31004008dd69861008009861008011bad30c00100130c001002375a617c0200264a6661620266e1d200000114a22940c2bc0400c0041381300200181201180905858dd6985a00800985a008011859008009855008030a9998560099b87480200044c8c94ccc2b804cdc4240000022a66615c026660f601c01803e264646464646464646464646464646464646464646464646464646464646464646464646464a6661a602a6661a602a6661a60201a20122940401852809986b809ba8005330d7013750008661ae026ea0cdc019b8002100a002330d701375066e0007c008cc35c04dd4000a5eb8058dd6986a008011bad30d2010013253330d1013370e9000000899191919bb03750666661060203c0180446eb4c36404004dd6986c80986d008009ba83086013370400c00a61a20200261ae02002619e020ca266ec13010100003750036619e020c866e0007c02ccdc0010004a9998668099b8700102313370e0040082940ccc284040c52201004881003330a00103000b0093371203a0026eb4c32c04008dd6986480800991929998648099b880010021323232323232337606ea0cdc019b833370466e00cdc101080200299b813370403e00200466e080100052002375066e0ccdc119b803370401600200403a66e04cdc100f8008011bad30d001002375a619c020026666660fa03c0380040020c80c46eb4c33404008dd698658080099999983c80200280d80c83082f8a9998648099b880020011323232323232337606ea0cdc019b833370466e00cdc100f80200299b813370404200200466e080100052002375066e0ccdc119b803370401400200403a66e04cdc10108008011bad30d001002375a619c020026666660fa03803c0040020c80c46eb4c33404008dd698658080099999983c80280200c80d83082f899bb0375066e0806c064dd400119b833370400802c03066e0ccdc100100a80ca99986300a9998630099b89480000044cdc4a400000429404cdc42400066e000040085282999862809984c80806805899b810023370003a03620046661320205c01000c6661300205a0160126eb8c31c04004c31c04008dd7186280800985e8082c9bae30c30100130c301002375c6182020026172020ae6eb8c2fc04004c2fc04008dd7185e80800985a8082a9bad30bb0100130bb01002375a6172020026172020046eb4c2dc04004c2dc04008dd6985a80800985a808119bad30b3010221616375a61640200261540200c2a6661580266e1d200a00113232323253330b00153330b001337109000001899b88480000045280a9998580099983e8080070108991919191919191919191919191919191919191919191919191919191919191919191919299986a00a99986a00a99986a0080708050a50100614a02661b0026ea0014cc36004dd40021986c009ba83370066e0408003c008cc36004dd419b8001e002330d801375000297ae016375a61aa020046eb4c34c04004c94ccc34804cdc3a4000002264646466ec0dd4199998420080e99b82025023021375a61b4020026eb4c36804c36c04004dd418438099b8200600530d20100130d80100130d0010661337609801010000375003461a0020ca66e0407801ccdc080f803a99986700998510080a0090a9998670099b870033370000c048266e1c0080145280a99986700a9998670099b8700102413370e00600c29404cdc38010028a503330a201032489004881003330a10103100e00c3330a00103001100f53330ca013371203a004266e2406c0045281bad30cb01002375a61920200266660f402e02a00402666e21200000133309a0102f003001375c6192020026192020046eb8c31c04004c2fc0416cdd71862808009862808011bae30c30100130bb01059375c6182020026182020046eb8c2fc04004c2dc0415cdd6985e80800985e808011bad30bb0100130bb01002375a6172020026172020046eb4c2dc04004c2dc04094dd6985a808120b0b1bad30b40100130b401002375a61640200261540200c2a6661580266e1d200c00113232323253330b0013371090000008a9998580099983e8080070108999999999911111111191919191919191919191919191919191919191919191919191919191919299986b80a99986b80a99986b8080588020a50100114a02a6661ae0204e2661b6026ea0078cc36c04dd419b8101c008330db01375066e00cdc080d0060031986d809ba83370003000c661b6026ea00152f5c02661b6026ea0cdc080f0041986d809ba801c330db01375066e00cdc080d0060031986d809ba83370003000c661b6026ea00152f5c02ca6661ac026615402024020266e1c004cdc00110038a99986b0099b8700100713370e0440042940ccc2a8040e804403cccc2a4040e5220100488100337120480086eb4c35004008dd69869008009929998688099b87480000044c8c8c8cdd81ba833333083010133370403603202e6eb4c36404004dd6986c80986d008009ba830860100630d10100130d70100130cf0101c1337609810100003750020619e020366eb4c34404008dd6986780800991919191919bb0375066e08008004dd4299986900811099b800033333309e0100200100401c01b1337000086666613c0200200400603803666e04058008cdc080b8011bad30d101002375a619e0200266661000202802400402066e2120000013330a001035003001375c619e02002619e020046eb8c33404004c31404050dd71865808009865808011bae30c90100130c10100153330c20101210101011375a618c02002618c020046eb4c31004004c31004008dd69861008009861008011bad30c00100130c001002375a617c0200264a6661620266e1d200000114a22940c2bc0400c1381301280181101201180905858dd6985a00800985a008011859008009855008030a9998560099b87480380044c8c8c8c8c8c8c8c8c8c94ccc2d8054ccc2d8054ccc2d804cdc42400000e266e21200000714a0266e21200000314a0264646464646464646464646464a66618602a66618602002264646464646464a6661940266e1d200230c90100113232323232323232323232323232323253330da013370e9007186c80802899191919191919191919299987200a99987200a99987200a99987200a99987200a99987200a99987200a99987200a99987200a99987200a9998720099b8f01907613375e08c02e29404cdd782200a8a5013375e08402629404cdc381e0068a5013370e07401629404cdd78200088a5013375e06e01229404cdc381a8038a5013370e06600a29404cdc399b810314800800c528099b8702f00114a06eb4c3a004004c3a004008dd69873008009873008011bad30e40100130e401002375a61c40200261c40200461c00200261b00200a2c6eb4c37804004c37804008dd6986e00800986e00801186d00800986d00801186c00800986c00801186b00800986b00801186a00800986a008011869008009865009984d008398029bae30d00100130c8010011630ce0100130c60100430cc0100130cc0100130cb0100230c90100130c1010341333090010230210341330c70137500166618e026ea0024cc31c04dd400399863809ba8005330c701375000697ae0163370e90011861809baa30c70100130c701002375a618a02002618a020046eb4c30c04004c30c04008dd69860808009860808011bad30bf0100130bf01002375a617a02002646464646464646464646464646464646464646464646464646464646464646464a6661b002a6661b00266e21200000213371204600429404c8c8c8c8c8c94ccc378054ccc3780402c4004528099299986f80814899871809ba833700050012661c6026ea0cdc081300399871809ba8024330e3013750044661c6026ea0080cc38c04ccc37c04005300103d87a80004c0103d87980004bd70099871809ba83370205000e661c6026ea0cdc001300499871809ba8024330e3013750044661c6026ea0080cc38c04ccc37c0400530103d87a80004c0103d87980004bd70299986f0099b8848000cdc0815a4004266e240a401c5280b299986e80998588080a0090a99986e8099b870013370000c008266e1c008cdc00018028a50153330dd01330b10101000e153330dd013370e00200c266e1c008cdc000199b8200500414a0264a6661bc02a6661bc0266e1c00801c4cdc380199b8000400614a0266e1c01400452819985900821245004881003330b1010410130113330b00104000e00c3330af0104400d00b3370066e080c4cdc08132400405e66666148020260220040e00dc2c6eb4c36404008dd6986b80800a99986a8099b890030011337606ea000d30010100001337606ea0004dd419b810030013232323253330d80133710900000088008b19b830020013370404a00466e04cdc119b8202600100e3370466e080901ac040cdc083503619b88480000054ccc34804cc2980402401c4cdc080080108009998530081d80400319b803370405003a04c6eb8c35004004c35004008dd71869008009865008049bae30d00100130d001002375c619c02002618c0200e6eb4c33004004c33004008dd6986500800986500801186400800986400801186300800a999860008050998620082f198620082e19862009ba8009330c401375000e97ae01330c40105c330c40105e330c401375000e66188026ea00252f5c06eb4c31004004c31004008dd69861008009861008011bad30c00100130c001002375a617c02002617c020586eb4c2f0040acc94ccc2dc04cdc3a40000022944528185a808048b1bad30ba0100130ba01002375a6170020026170020046eb4c2d804004c2d804008dd6985a00800985a0080118590080098550080309931855008031855008028b1bad30af0100130af01002375a615a02002615a02004615602002615602004615202002615202004614e02002614e02004614a02002614a02004614602002613602002660d40860086eacc28004004c28004004c25c04028c27404004c27404008dd5984d80800984d80800984900800984c00800984c00800984780802184b00802984a00802184a008021849008019bad308d01001308d01002375a6116020026116020046eb4c22404004c22404008dd69843808009843808059bad30850100a375a6108020026108020046eb4c20804004c20804004c2040401c5858cc1300888c8c94ccc1f4ccc1f4cdd7800806a504a226660fa66ebc0040852825114a061020200260f20026466600200200497ae0222533307f0021001133300300330820100233223308201305b3305c007002001375a61020200400260480366609204046464646464646464a6661000266e1d200200113371e6eb8c21404c1f8008048528183f000984180800983d800984080800983c800983f800983f800983b0009bac307b001307b002375860f200260f20046eb4c1dc004c1dc008c1d4004c1d4008dd718398009839801183880098388011bad306f001306f002375a60da00260da00460d600260d600460d200260d200460ce00260be66666606800400201801600c01060c400460c00026464a6660c660cc0042646464646464646464a6660d860de004264a6660da60e0002264a6660dc60e2002266ec003000c58cc0f00488cdd798381834983818348008028b1981d809119baf306f3068306f3068306f3070306800100416306d0013303900f23375e00860da60cc00260d600260c600260d200260c200260ce00260ce00260bc0022c60c80026606000e466ebc014c190c174004c004004894ccc16000452f5c026464660b66ea0008cc010010c8cc004004008894ccc17000452f5c026464a6660b66660b666e1c0080192825113305f37500046600800800226600800800260c00046eb4c178004c170008dd6982d000911111111111919191919191919191919191919191919191919191919191919191919191919299983ea99983ea99983e80288018a50100114a02a6660fa052266102026ea0cdc001000319840809ba83370203c00866102026ea0070cc20404dd400d19840809ba80184bd70099840809ba83370204000866102026ea0cdc000f00319840809ba801c3308101375003466102026ea00612f5c02ca6660f8660a001200e266e1ccdc0001812000899299983e99b8700400213370e00204a2940ccc1440a5220100488100333050028008006301e0013333304500e00c00202001f337109000000a99983b99825804003099b810013370004003e200266609604800e00a6eb8c1e8004c1e8008dd7183c00098380049bae30760013076002375c60e800260d800e6eb4c1c8004c1c8008dd698380009838001183700098370011836000a99983300909983500899835008198351ba80093306a375000e97ae013306a0103306a0113306a375000e660d46ea00252f5c06eb4c1a8004c1a8008dd6983400098340011bad30660013066002375a60c800260c80066eb4c188008888894ccc158cdc4802a400029000099299982b99b880060011323232533305a33710900000088008a400066e0c008004cdc019b823370200600800466e0801001ccdc119b820030043370200200c2900018040021111111919191919bb0375066e04c030cdc0980700099b823370400600a66e04014018004dd419b820023370200a00c66e08cdc099b824801001001400ccdc12400866e0001c014cdc119b8248020cdc000300219b813370400c601600a66e08cdc100380280219b823370000a0060084444446466ec0dd419b823370400a00200c6ea0cdc019b823370400400800e66e08014004cdc08008011299982799b88001480005854ccc13ccdc3800a4000290000a99982799b8700148008520021533304f3370e00290020a400426464666002002006004444a6660a666e200040084ccc00c00c004cdc199b803370600a0020029002080119b8033706002900224004444466ec0dd419b83337040040080026ea0cdc199b8200200300123370400200209008802001a00205e07e02c0282c6eacc140004c140004c13c008dd61826800982680118258009825800982500098248011bab30470013047001304600237586088002608800260860046eb0c104004c0e408858dd6981f800981f8011bac303d001303d002303b0013033027153330353370e900100b899191919191919191919299981fa99981fa99981f99b894800001c4cdc38010008a5013371290020008a501323232323232323232323232323232323253330503333333302c01000600401a04a01804400a13333333333232323232323222222222232323232323232323232323232323232533307330760021323253330753078002132323232323232323232323232323232323232323232323232533308b01533308b01533308b01533308b01337109000002099b884800000852808008a5013375e04e01029404c94ccc23004cdc3a4020002264646464a6661200266e21200000113232323232323232323232323232323232323232323232323232323232323253330af013371204000226464a666162020022944594ccc2c004cc2100401c0144cdc399b8000202700113253330b1013370e006004266e1c0040a05281998428081a245004881003330840103300600416333305a001480001380854ccc2b404cc204040200184cdc080099b80026024100133308101035007005375c6160020026160020046eb8c2b804004c29804014dd71856008009856008011bae30aa0100130a2010023253330a4013370e9000000880188029851008051929998518099b874800000440204018c28404030c29804004c29804008c29004004c2700402cc28804004c28804008c28004004c26004020c27804004c27804004c25404018c26c04004c26c04004c24804010cc0f40cccdc09831819a40046607806490001981d80219b81306100448008cc0e800d200016375a6128020026128020046eb0c24804004c2280401c5281845008030b19982b80580480c9bad308e01001308e01002375a611802002611802004611402002611402004611002002611002004610c02002610c0200461080200261080200260f6660960440086eacc20404004c20404004c1e0024c1f8004c1f8008dd5983e000983e0009839800983c800983c80098380018b183b0009982100b119191919299983a99983a99baf0030184a09444ccc1d4cdd78008042504a22940c1e4004c1c4004c1dc004c1bc00458c1d0004cc1000548c8c8c8c8c8c8c8c94ccc1dccdc3a4004002266e3cdd7183e183a8010070a503075001307a00130720013078001307000130760013076001306d0013072001306a00130700013070002375c60dc00260dc00260da00260d800260d600460d200260d200260d000260be660160029000191919191929998341835801099191919191919299983619b87303c3303e01323375e60e460d660e460d660e460e660d60020040142a6660d866e1cc0f0cc0f80488cdd7983918359839183580080100509919980080080680611129998390010a9998390008a5eb80584c8c94ccc1d000c52f5c02660ea64646464646464646464646464646464a66610202a6661020266ebc02c0184c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc294054ccc294054ccc294054ccc294054ccc294054ccc294054ccc294054ccc29404cdd7811808899baf02100f14a0266e1c07c034528099b8701d00b14a0266e1c06c024528099b8701900714a0266e1c05c014528099b8f01500314a0266ebc04c0045281854808009854808011bae30a70100130a701002375a614a02002614a020046eb4c28c04004c28c04008dd69850808009850808011bad309f01001309f01002375a613a02002613a02004613602002613602004613202002612202026612e02002612e020046eb8c25404004c25404008dd69849808009849808011bad309101001309101002375a611e02002611e020046eb4c23404004c23404008dd6984580800984580801184480800984480801184380800983f8010a50133333305401201002a0290020261633056025002330550240063083010013083010013082010023080010013078009307e001307e001307d002307b00130730013079001307900130700033076003333005005001307700330760033074002161630700013068001306e0013066001306c001306c00130630011630690013303500a23375e01060d260c400260640046601e0044660180100026601c0044660160100026002002444a6660b066e2520140011333003003305e305e305e305e305e305e305e305e305e305e00233702002900a099803801000980080091111299982d801080189919299982e80188028991919199998050050008008020011919191919191919191919191919191919191919191919191919299983b19baf01700313232325333079337109000012899299983d19b884800000454ccc1e8c94ccc1eccdc3a40000022a6660f666e1ccdc0007813806099b873370201a004014294054ccc1eccdc399b8100f00200c13370e66e0003409c028528183c80288008b0b1999982280100081280c00b0b1bad307a002375a60f000264a6660ee66e1d20000011337606ea002cdd4004899bb037500126ea002cc1d400458c1e8004c1e8008c1e0004c1c0060dd6983b000983b0029bad3074004375a60e600260e60086eb4c1c400cdd6183800098380011bac306e001306e001306d001306c001306b001306a002375a60d000260d00046eb4c198004c198008c190004c190004c18c004c168010c184010c17c00cc17c00cc17400888c8cc00400400c894ccc16400452f5c02660b460066eb4c16c004cc008008c170004c0040048894ccc14ccdc4800a4000260b0004266600600660b200466e04005200204c04801000d00103301a01601416375660a800260a800260a60046eb0c144004c144008c13c004c13c004c138004c134008dd59825800982580098250011bac3048001304800130470023758608a002607a04c2c6030004602e0066eb0c104004c104008dd6181f800981f8011bad303d001303d002303b0013033027153330353370e900200b89925130330271324a2606604e44444646466e0ccdc100080319b803370400600e00266e08004010cdc0800801111191919191919299981e299981e19baf009005100114a0294458c94ccc0f0cdc3a40000022646464a66607e66e1d2000001161533303f3370e9001000899b8f375c6088607a00a004266e3cdca1bb33044303d005002303d004375c60840026074010266ebc009300103d8798000303a007303f001303f001303e002303c00130340012232320023253330363370e900000089919191919191919191919191919299982398250010991919191924c64a66609266e1d200000113232323253330503053002132498c07000c58dd698288009828801182780098238050a99982499b87480080044c8c8c8c94ccc140c14c0084c926301c00316375a60a200260a2004609e002608e0142a66609266e1d2004001132323232323253330523055002132498c07801458dd6982980098298011bad30510013051002304f001304700a153330493370e90030008991919192999828182980109924c60380062c6eb4c144004c144008c13c004c11c02854ccc124cdc3a401000226464a66609c60a20042930b1bad304f001304700a153330493370e9005000899191919299982818298010a4c2c6eb4c144004c144008dd6982780098238050a99982499b87480300044c8c8c8c94ccc140c14c0084c926301c00316375a60a200260a2004609e002608e0142a66609266e1d200e00113232323232323232323253330563059002132498c08802458dd6982b800982b8011bad30550013055002375a60a600260a60046eb4c144004c144008c13c004c11c02854ccc124cdc3a4020002264646464a6660a060a6004264931981b801919299982799b87480000044c8c8c8c94ccc158c1640084c8c9263023002304000316305700130570023055001304d00216304d00116375a60a200260a20046eb0c13c004c11c02858c11c024c0d0028c0d402cc0cc030c0c803458dd6982400098240011bad30460013046002304400130440023042001304200230400013040002303e001303e002303c00130340021630340013300d00200123253330333370e90000008a99981b18188010a4c2c2a66606666e1d200200115333036303100214985858c0c4004c004004894ccc0d000452000133700900119801001181b80091191980080080191299981a8008a5eb804c8c94ccc0d0c0140084cc0e0008cc0100100044cc010010004c0e4008c0dc004888888c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc168c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c94ccc1e14ccc1e14ccc1e14ccc1e14ccc1e0cdd780e807099baf01b00c14a0266e1c05801c528099b8701400514a0266e3c04800c528099baf01000114a060f800260f80046eb8c1e8004c1e8008dd6983c000983c0011bad3076001307600130750013074001307300230710013071002306f0013067018306d001306d002375c60d600260d60046eb4c1a4004c1a4008dd698338009833800983300098328009832001183100098310011830000982c014899191919191919191919299983219b8733303902b0350344800854ccc190cdc399981c81401a81a24004264646466e9520003306b0273306b0253306b0043306b375003a660d66ea006ccc1ac05ccc1acdd480c99835818198359ba83370266607805607000a66607805c07000a660d66e9ccc1acc1a0004cc1acdd419981e017004003198359ba80233306b375003e660d66ea00852f5c0660d66e9ccc1acc1a4004cc1acdd419981e015804003198359ba80123306b375001c660d66ea00412f5c097ae053330663303a00b0091337606ea0cdc08012410137dc046ea0cdc0800a410137dc04266ec0dd40011ba800133303a02900a00833303902b00900716163374a9000198339ba903433067375200297ae030393303a30393303a00700530393303a003001375c60cc00260cc0046eb8c190004c170070dd7183100098310011bae3060001305801a16375a60bc00260bc0046eb4c170004c170008dd6982d000982d000982c80098280009981380f809982a800982a8011bae30530013053002375a60a200260a20046eb4c13c004c13c008dd6982680098268011bad304b001304b002375a60920026092004608e002608e004608a002607a01c608600260860046eacc104004c104004c0e0030dd5981f000981f001181e000981a000981d000981d000981880311299981719b8f0024890013371e0029110014a044464664464a66606466e1d200200110021375a606e6060006606000464a66606066e1d200200114c103d87a8000132323300100100222533303600114c103d87a800013232323253330373371e014004266e9520003303b375000297ae0133006006003375a60700066eb8c0d8008c0e8008c0e0004dd5981a98170011817000a40006601e00600444646400460320026600a00400246e4c00488cdc500100091180319299981519b8748000004530103d87a80001533302a3370e900100089919198008008029129998180008a6103d87a800013232323253330313371e00e004266e952000330350014bd7009980300300198190019bae303000230340023032001375c605e6050004266e9520003302e302f30280024bd70181400098008009129998150008a4000266e01200233002002302d00122222222533302c325333030323300100100222533303200114bd70099199911191980080080191299981c00088018991999111981e9ba73303d37520126607a6ea400ccc0f4dd400125eb80004dd7181b8009bad303800133003003303c002303a001375c60620026eacc0c8004cc00c00cc0d8008c0d00045288b19198008008011129998188008a5eb7bdb1804c8c8c8c94ccc0c8cdc7a45000021003133036337606ea4008dd3000998030030019bab3033003375c6062004606a00460660022a666058646464646464646464646464a66607066e1d2000303700113232533303a533303a533303a323300100101522533303f00114a026464a66607c66e3c00801452889980200200098218011bae304100113371200a01029404cdc480419b8000601014a0294458dd7181f000981b0008b181e000981a0079bad3037002375a606a00264a66606866e1d20023033001132323253330373370e9001181b000899bb037500046078606a0022c602c60686076607860680226eb4c0e8004c0c800458c04cc0c4c04cc0c4038c8c94ccc0dcc0e80084c8c94ccc0d8cdc3800a400426464666002002900024000444a66607466e1c00801040044c94ccc0ed4ccc0eccdc3801a4000266e1c005205a14a0266e08ccc010010cdc0001a400400490008a99981da99981da99981d99b8800148180528899b8800148180528899b88337009030240240022c266600800866e0000d20023370066e08009201433702002903019b8e006002371a0042c6eb4c0dc008dd7181a8008b181c000999119299981a99b874800800440084dd5981d181980198198011980980080525eb7bdb180dd5981b000981b00098168009819800981980098151804998050040018a511616253330243370e900018118008981498110008b180080091129998138010a60103d87a80001323253330263370e0069000099ba548000cc0a80092f5c0266600a00a00266e0400d2002302b00330290022302600122323300100100322533302600114c103d87a800013232323253330273371e00e004266e9520003302b374c00297ae0133006006003375660500066eb8c098008c0a8008c0a0004c074040c088004c06800458c080004c080008c078004c058024526163253330183370e90000008991919191919299981098120010991924c6601200846eb4004c03001458dd6981100098110011bac30200013020002301e001301600a153330183370e90010008991919191919191929998119813001099191924c6601800646eb4004cc02c0108dd680098070038b1bac302400130240023758604400260440046eb4c080004c080008c078004c05802854ccc060cdc3a400800226464a66603a60400042930b1bad301e001301600a153330183370e9003000899191919299980f98110010a4c2c6eb4c080004c080008dd6980f000980b0050b180b00491191980080080191299980e8008a4c2646600600660420046006603e0026002010464a66602c66e1d20000011323232323232323232323232323232323232533302b302e0021323232498c94ccc0accdc3a400000226464a66606060660042649319299981719b87480000044c8c8c8c8c8c8c8c94ccc0e4c0f00084c8c9263026002302400316303a001303a00230380013038002375a606c002606c0046eb4c0d0004c0b000858c0b000458c0c4004c0a401054ccc0accdc3a40040022a66605c60520082930b0b1814801980b008180a8088b181600098160011bae302a001302a002375a605000260500046eb4c098004c098008dd6981200098120011bad30220013022002375a60400026040004603c002603c004603800260280042c6028002464a66602a66e1d2000001132323232533301c301f002149858dd7180e800980e8011bae301b001301300216301300123253330143370e9000000899191919299980d980f0010991924c64a66603466e1d200000113232533301f3022002132498c94ccc074cdc3a400000226464a666044604a0042649318078008b1811800980d8010a99980e99b87480080044c8c8c8c8c8c94ccc098c0a400852616375a604e002604e0046eb4c094004c094008dd69811800980d8010b180d8008b1810000980c0018a99980d19b874800800454ccc074c06000c52616163018002300800316301c001301c002301a001301200216301200123253330133370e900000089919299980c180d8010a4c2c6eb8c064004c04400854ccc04ccdc3a40040022a66602c60220042930b0b1808800919299980919b87480000044c8c94ccc05cc06800852616375c603000260200042a66602466e1d2002001132325333017301a002149858dd7180c00098080010b18080009bad001375c0026eb8004dd70009bae001230053754002460066ea80055cd2ab9d5573caae7d5d02ba157441", + "hash": "20ffa2c64a4acc8bf66c1c68502580bceded55529e3d7ad1bba8fad6" } ], "definitions": { diff --git a/validators/authen_minting_policy.ak b/validators/authen_minting_policy.ak index 2c2561d..df5a969 100644 --- a/validators/authen_minting_policy.ak +++ b/validators/authen_minting_policy.ak @@ -20,7 +20,7 @@ validator( expect Mint(authen_policy_id) = purpose when redeemer is { MintFactoryAuthen -> { - let Transaction { inputs, mint, outputs, .. } = transaction + let Transaction { inputs, mint, outputs, datums, .. } = transaction // Transaction must has @out_ref in the input to make sure that this redeemer can only be executed once expect [_] = @@ -52,7 +52,7 @@ validator( expect [factory_output] = factory_outputs let Output { datum: factory_raw_datum, .. } = factory_output let FactoryDatum { head, tail } = - utils.parse_factory_datum(factory_raw_datum) + utils.must_find_factory_datum(datums, factory_raw_datum) expect head == #"00" && tail == #"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00" True diff --git a/validators/factory_validator.ak b/validators/factory_validator.ak index 88a6138..9b0f15a 100644 --- a/validators/factory_validator.ak +++ b/validators/factory_validator.ak @@ -23,7 +23,7 @@ validator( ) { let ScriptContext { transaction, purpose } = context expect Spend(factory_ref) = purpose - let Transaction { inputs, mint, outputs, .. } = transaction + let Transaction { inputs, mint, outputs, datums, .. } = transaction let FactoryRedeemer { asset_a, asset_b } = redeemer let FactoryDatum { head: current_head, tail: current_tail } = datum let Asset { policy_id: asset_a_policy_id, asset_name: asset_a_asset_name } = @@ -73,9 +73,9 @@ validator( let Output { datum: factory_output_1_raw_datum, .. } = factory_output_1 let Output { datum: factory_output_2_raw_datum, .. } = factory_output_2 let FactoryDatum { head: new_head_1, tail: new_tail_1 } = - utils.parse_factory_datum(factory_output_1_raw_datum) + utils.must_find_factory_datum(datums, factory_output_1_raw_datum) let FactoryDatum { head: new_head_2, tail: new_tail_2 } = - utils.parse_factory_datum(factory_output_2_raw_datum) + utils.must_find_factory_datum(datums, factory_output_2_raw_datum) // Transaction must put new hash between old hashes, (current_head, current_tail) -> (current_head, new_hash) && (new_hash, current_tail) expect builtin.less_than_bytearray(new_head_1, new_tail_1) && builtin.less_than_bytearray( @@ -112,7 +112,7 @@ validator( trading_fee_denominator: pool_datum_trading_fee_denominator, order_hash: pool_datum_order_hash, profit_sharing_opt: pool_datum_profit_sharing_opt, - } = utils.parse_pool_datum(pool_output_raw_datum) + } = utils.must_find_pool_datum(datums, pool_output_raw_datum) expect None = pool_datum_profit_sharing_opt let estimated_amount_a = value.quantity_of( diff --git a/validators/pool_validator.ak b/validators/pool_validator.ak index 3fde786..d6c3987 100644 --- a/validators/pool_validator.ak +++ b/validators/pool_validator.ak @@ -1,17 +1,14 @@ -use aiken/dict.{Dict} use aiken/list use aiken/transaction.{ - DatumHash, Input, NoDatum, Output, OutputReference, ScriptContext, Spend, - Transaction, + Input, Output, OutputReference, ScriptContext, Spend, Transaction, } use aiken/transaction/credential.{Address, ScriptCredential} use aiken/transaction/value.{AssetName, PolicyId} use amm_dex_v2/order_validation use amm_dex_v2/pool_validation use amm_dex_v2/types.{ - Asset, Batching, BatchingPool, CustomDatumHash, MultiRouting, OrderDatum, - PoolDatum, PoolRedeemer, PoolState, SwapMultiRouting, UpdateFeeTo, - WithdrawLiquidityShare, + Asset, Batching, BatchingPool, DatumMap, MultiRouting, OrderDatum, PoolDatum, + PoolRedeemer, SwapMultiRouting, UpdateFeeTo, WithdrawLiquidityShare, } use amm_dex_v2/utils @@ -31,6 +28,7 @@ validator( expect Spend(pool_input_ref) = purpose when redeemer is { Batching(batcher_address, input_indexes, license_index) -> { + expect license_index >= 0 && list.length(input_indexes) > 0 let Transaction { inputs, outputs, @@ -73,7 +71,7 @@ validator( let routing_out_indexes_len = list.length(routing_out_indexes) // TODO: Validate distinct indexes expect - routing_in_indexes_len == routing_out_indexes_len && routing_out_indexes_len >= 2 + license_index >= 0 && routing_in_indexes_len == routing_out_indexes_len && routing_out_indexes_len >= 2 let Transaction { inputs, outputs, @@ -173,6 +171,7 @@ fn get_batching_pool( authen_policy_id: PolicyId, pool_auth_asset_name: AssetName, pool_in_datum: PoolDatum, + datum_map: DatumMap, ) -> BatchingPool { let Input { output: Output { address: pool_in_address, value: pool_in_value, .. }, @@ -192,7 +191,7 @@ fn get_batching_pool( order_hash: pool_in_order_hash, profit_sharing_opt: pool_in_profit_sharing_opt, } = pool_in_datum - let pool_out_datum = utils.parse_pool_datum(pool_out_datum_raw) + let pool_out_datum = utils.must_find_pool_datum(datum_map, pool_out_datum_raw) let PoolDatum { total_liquidity: pool_out_total_liquidity, root_k_last: pool_out_root_k_last, @@ -242,24 +241,6 @@ fn get_batching_pool( let remaining_liquidity_supply_out = value.quantity_of(pool_out_value, authen_policy_id, lp_asset_name) - let pool_state_in = - PoolState { - reserve_a: reserve_a_in, - reserve_b: reserve_b_in, - root_k_last: pool_in_root_k_last, - total_liquidity: pool_in_total_liquidity, - liquidity_share: pool_in_liquidity_share, - remaining_liquidity_supply: remaining_liquidity_supply_in, - } - let pool_state_out = - PoolState { - reserve_a: reserve_a_out, - reserve_b: reserve_b_out, - root_k_last: pool_out_root_k_last, - total_liquidity: pool_out_total_liquidity, - liquidity_share: pool_out_liquidity_share, - remaining_liquidity_supply: remaining_liquidity_supply_out, - } BatchingPool { asset_a: pool_in_asset_a, asset_b: pool_in_asset_b, @@ -269,8 +250,21 @@ fn get_batching_pool( profit_sharing: pool_in_profit_sharing_opt, order_hash: pool_in_order_hash, address: pool_in_address, - pool_state_in, - pool_state_out, + delta_remaining_liquidity_supply: remaining_liquidity_supply_out - remaining_liquidity_supply_in, + pool_state_in: ( + reserve_a_in, + reserve_b_in, + pool_in_total_liquidity, + pool_in_liquidity_share, + pool_in_root_k_last, + ), + pool_state_out: ( + reserve_a_out, + reserve_b_out, + pool_out_total_liquidity, + pool_out_liquidity_share, + pool_out_root_k_last, + ), } } @@ -279,7 +273,7 @@ fn validate_batching( pool_auth_asset_name: AssetName, all_inputs: List, all_outputs: List, - all_datums: Dict, + all_datums: DatumMap, pool_input_ref: OutputReference, pool_in_datum: PoolDatum, batcher_address: Address, @@ -300,6 +294,7 @@ fn validate_batching( profit_sharing, order_hash, address: pool_address, + delta_remaining_liquidity_supply, pool_state_in, pool_state_out, } = @@ -309,6 +304,7 @@ fn validate_batching( authen_policy_id: authen_policy_id, pool_auth_asset_name: pool_auth_asset_name, pool_in_datum: pool_in_datum, + datum_map: all_datums, ) let user_inputs = list.filter( @@ -354,22 +350,14 @@ fn validate_batching( // User Inputs and Outputs must have the same length list.length(sorted_user_inputs) == list.length(user_outputs) expect list.length(sorted_user_inputs) == list.length(user_outputs) - let PoolState { - reserve_a: reserve_a_in, - reserve_b: reserve_b_in, - root_k_last: root_k_last_in, - total_liquidity: total_liquidity_in, - liquidity_share: liquidity_share_in, - remaining_liquidity_supply: remaining_liquidity_supply_in, - } = pool_state_in - let PoolState { - reserve_a: reserve_a_out, - reserve_b: reserve_b_out, - root_k_last: root_k_last_out, - total_liquidity: total_liquidity_out, - liquidity_share: liquidity_share_out, - remaining_liquidity_supply: remaining_liquidity_supply_out, - } = pool_state_out + let (_, _, total_liquidity_in, liquidity_share_in, _) = pool_state_in + let ( + reserve_a_out, + reserve_b_out, + total_liquidity_out, + liquidity_share_out, + root_k_last_out, + ) = pool_state_out let ( new_reserve_a, new_reserve_b, @@ -378,36 +366,25 @@ fn validate_batching( new_root_k_last, ) = order_validation.apply_orders( - all_outputs: all_outputs, - datum_dict: all_datums, + datum_map: all_datums, asset_a: asset_a, asset_b: asset_b, lp_asset: lp_asset, trading_fee_numerator: trading_fee_numerator, trading_fee_denominator: trading_fee_denominator, + order_hash: order_hash, profit_sharing_opt: profit_sharing, order_inputs: sorted_user_inputs, order_outputs: user_outputs, - pool_state: ( - reserve_a_in, - reserve_b_in, - total_liquidity_in, - liquidity_share_in, - root_k_last_in, - ), + pool_state: pool_state_in, ) - let delta_total_liquidity = total_liquidity_out - total_liquidity_in let delta_liquidity_share = liquidity_share_out - liquidity_share_in - let delta_remaining_liquidity_supply = - remaining_liquidity_supply_out - remaining_liquidity_supply_in - // Total Liquidity contains both share of Liquidity Provider and Minswap Labs // Batching transaction transfers Liquidity Provider share to their addresses and keep Minswap Labs share // Minswap Labs share is stored in @liquidity_share variable in Pool Datum let is_liquidity_correct = delta_total_liquidity == delta_liquidity_share - delta_remaining_liquidity_supply - // Validate the Pool State (reserve_a, reserve_b, total_liquidity, liquidity_share, root_k_last) must be the same with the calculated amount after applying through all orders expect new_reserve_a == reserve_a_out && // New Reserve A must be equals amount of Asset A in Pool Value @@ -424,7 +401,7 @@ fn validate_swap_multi_routing( pool_auth_asset_name: AssetName, all_inputs: List, all_outputs: List, - all_datums: Dict, + all_datums: DatumMap, pool_input_ref: OutputReference, batcher_address: Address, routing_in_indexes: List, @@ -445,6 +422,7 @@ fn validate_swap_multi_routing( outputs: all_outputs, routing_in_indexes: routing_in_indexes, routing_out_indexes: routing_out_indexes, + datum_map: all_datums, ) let BatchingPool { @@ -482,14 +460,11 @@ fn validate_swap_multi_routing( }, ) expect [order_output] = order_outputs - let Input { output: order_in_output, .. } = order_input - let Output { value: order_in_value, .. } = order_in_output - let Output { - value: order_out_value, - address: output_address, - datum: order_output_datum, + let Input { + output: Output { value: order_in_value, datum: raw_order_in_datum, .. }, .. - } = order_output + } = order_input + let Output { value: order_out_value, .. } = order_output let OrderDatum { receiver, receiver_datum_hash_opt, @@ -498,17 +473,15 @@ fn validate_swap_multi_routing( output_ada, lp_asset: order_lp_asset, .. - } = utils.must_find_order_datum(all_outputs, all_datums, order_in_output) - let is_valid_receiver_datum_hash = - when receiver_datum_hash_opt is { - Some(datum_hash) -> { - expect DatumHash(output_datum_hash) = order_output_datum - output_datum_hash == datum_hash - } - None -> order_output_datum == NoDatum - } + } = utils.must_find_order_datum(all_datums, raw_order_in_datum) + let is_valid_receiver = + order_validation.validate_order_receiver( + receiver: receiver, + receiver_datum_hash_opt: receiver_datum_hash_opt, + output: order_output, + ) expect - receiver == output_address && batcher_fee > 0 && output_ada > 0 && is_valid_receiver_datum_hash && pool_lp_asset == order_lp_asset + batcher_fee > 0 && output_ada > 0 && is_valid_receiver && pool_lp_asset == order_lp_asset when order_step is { SwapMultiRouting(routings, minimum_receive) -> { expect minimum_receive > 0 @@ -535,6 +508,7 @@ fn find_multi_routing_pools( outputs: List, routing_in_indexes: List, routing_out_indexes: List, + datum_map: DatumMap, ) -> List { let pool_ins = list.map(routing_in_indexes, fn(idx) { utils.list_at_index(inputs, idx) }) @@ -600,8 +574,10 @@ fn find_multi_routing_pools( } = pool_in let Output { address: pool_out_address, datum: pool_out_datum_raw, .. } = pool_out - let pool_in_datum = utils.parse_pool_datum(pool_in_datum_raw) - let pool_out_datum = utils.parse_pool_datum(pool_out_datum_raw) + let pool_in_datum = + utils.must_find_pool_datum(datum_map, pool_in_datum_raw) + let pool_out_datum = + utils.must_find_pool_datum(datum_map, pool_out_datum_raw) expect pool_in_address == pool_out_address && // hehe @@ -612,6 +588,7 @@ fn find_multi_routing_pools( authen_policy_id: authen_policy_id, pool_auth_asset_name: pool_auth_asset_name, pool_in_datum: pool_in_datum, + datum_map: datum_map, ) }, )