@@ -10,13 +10,10 @@ use aiken/transaction.{
10
10
use aiken/transaction/credential.{
11
11
Address, Inline, ScriptCredential,
12
12
}
13
- use aiken/transaction/value.{MintedValue, PolicyId, Value, ada_policy_id}
13
+ use aiken/transaction/value.{MintedValue, PolicyId, Value, ada_policy_id, ada_asset_name }
14
14
use calculation/process.{pool_input_to_state, process_orders}
15
15
use calculation/shared.{PoolState} as calc_shared
16
- use shared.{
17
- AssetClass, Ident, count_orders, has_exact_token_count, pool_lp_name,
18
- pool_nft_name, spent_output,
19
- }
16
+ use shared.{AssetClass, Ident, spent_output, pool_nft_name, pool_lp_name, count_orders}
20
17
use sundae/multisig
21
18
use types/pool.{
22
19
CreatePool, MintLP, PoolDatum, PoolMintRedeemer, PoolRedeemer, PoolScoop,
@@ -519,7 +516,7 @@ fn minted_correct_pool_tokens(
519
516
520
517
/// Check that the UTXO contents are correct given a specific pool outcome
521
518
/// In particular, it must have the final A reserves, the final B reserves, the pool NFT, and the protocol fees
522
- fn has_expected_pool_value(
519
+ pub fn has_expected_pool_value(
523
520
pool_script_hash: PolicyId,
524
521
identifier: Ident,
525
522
output_value: Value,
@@ -531,33 +528,48 @@ fn has_expected_pool_value(
531
528
let (quantity_b_policy_id, quantity_b_name, quantity_b_amt) = quantity_b
532
529
// Asset A *could* be ADA; in which case there should be 3 tokens on the output
533
530
// (ADA, Asset B, and the NFT)
534
- // We do this as an optimization, since constructing values is expensive
535
- // OPTIMIZATION: is it possible to check this with a single traversal? Each quantity_of represents a small linear scan
536
531
if quantity_a_policy_id == ada_policy_id {
537
- and {
538
- has_exact_token_count(output_value, 3),
539
- value.lovelace_of(output_value) == final_protocol_fees + quantity_a_amt,
540
- value.quantity_of(output_value, quantity_b_policy_id, quantity_b_name) == quantity_b_amt,
541
- value.quantity_of(
542
- output_value,
543
- pool_script_hash,
544
- pool_nft_name(identifier),
545
- ) == 1,
546
- }
532
+ // Rather than constructing a value directly (which can be expensive)
533
+ // we can just compare the expected token count and amounts with a single pass over the value
534
+ (3, final_protocol_fees + quantity_a_amt, quantity_b_amt, 1) ==
535
+ list.foldl(
536
+ value.flatten(output_value),
537
+ // (token count, lovelace amount, token b amount, pool nft amount)
538
+ (0, 0, 0, 0),
539
+ fn (asset, acc) {
540
+ let token_count = acc.1st + 1
541
+ if asset.1st == quantity_a_policy_id {
542
+ (token_count, acc.2nd + asset.3rd, acc.3rd, acc.4th)
543
+ } else if asset.1st == quantity_b_policy_id && asset.2nd == quantity_b_name {
544
+ (token_count, acc.2nd, acc.3rd + asset.3rd, acc.4th)
545
+ } else {
546
+ expect asset == (pool_script_hash, pool_nft_name(identifier), 1)
547
+ (token_count, acc.2nd, acc.3rd, acc.4th + 1)
548
+ }
549
+ }
550
+ )
547
551
} else {
548
- // Otherwise, we expect 4 tokens (ADA, Asset A, Asset B, and the NFT)
549
- // and the corresponding values
550
- and {
551
- has_exact_token_count(output_value, 4),
552
- value.lovelace_of(output_value) == final_protocol_fees,
553
- value.quantity_of(output_value, quantity_a_policy_id, quantity_a_name) == quantity_a_amt,
554
- value.quantity_of(output_value, quantity_b_policy_id, quantity_b_name) == quantity_b_amt,
555
- value.quantity_of(
556
- output_value,
557
- pool_script_hash,
558
- pool_nft_name(identifier),
559
- ) == 1,
560
- }
552
+ // Asset A isn't ADA, Asset B will *never* be ADA; in this case, there should be 4 tokens on the output:
553
+ // ADA, the Pool NFT, Asset A, and Asset B
554
+ (4, final_protocol_fees, quantity_a_amt, quantity_b_amt, 1) ==
555
+ list.foldl(
556
+ value.flatten(output_value),
557
+ // (token count, lovelace amount, token a amount, token b amount, pool nft amount)
558
+ (0, 0, 0, 0, 0),
559
+ fn (asset, acc) {
560
+ let token_count = acc.1st + 1
561
+ if asset.1st == ada_policy_id && asset.2nd == ada_asset_name {
562
+ (token_count, acc.2nd + asset.3rd, acc.3rd, acc.4th, acc.5th)
563
+ } else if asset.1st == quantity_a_policy_id && asset.2nd == quantity_a_name {
564
+ (token_count, acc.2nd, acc.3rd + asset.3rd, acc.4th, acc.5th)
565
+ } else if asset.1st == quantity_b_policy_id && asset.2nd == quantity_b_name {
566
+ (token_count, acc.2nd, acc.3rd, acc.4th + asset.3rd, acc.5th)
567
+ } else {
568
+ expect asset == (pool_script_hash, pool_nft_name(identifier), 1)
569
+ (token_count, acc.2nd, acc.3rd, acc.4th, acc.5th + 1)
570
+ }
571
+ }
572
+ )
561
573
}
562
574
}
563
575
@@ -576,4 +588,4 @@ fn compare_asset_class(a: AssetClass, b: AssetClass) {
576
588
pub fn int_to_ident(n: Int) -> Ident {
577
589
expect n < 256
578
590
bytearray.push(#"", n)
579
- }
591
+ }
0 commit comments