@@ -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