diff --git a/crates/vm_library/src/arena.rs b/crates/vm_library/src/arena.rs index e15a2df..1715f40 100644 --- a/crates/vm_library/src/arena.rs +++ b/crates/vm_library/src/arena.rs @@ -36,6 +36,8 @@ pub fn populate_predef(sender: String, self_: String, source: String) { map.insert("empty_set".to_owned(), Value::Set(ordset![])); map.insert("empty_map".to_owned(), Value::Map(ordmap! {})); map.insert("zero".to_owned(), Value::Int(0.into())); + map.insert("amount".to_owned(), Value::Int(0.into())); + map.insert("now".to_owned(), Value::Int(0.into())); } pub fn push_constants(vec: Vec<(i32, Value)>) { let map = unsafe { &mut CONSTANTS }; diff --git a/crates/vm_library/src/managed/imports.rs b/crates/vm_library/src/managed/imports.rs index 5c8434e..9b21359 100644 --- a/crates/vm_library/src/managed/imports.rs +++ b/crates/vm_library/src/managed/imports.rs @@ -96,11 +96,10 @@ pub fn neq(env: &Context, value: Value) -> VMResult { pub fn eq(env: &Context, value: Value) -> VMResult { env.update_gas(300)?; - let one: rug::Integer = rug::Integer::from(1); let res: VMResult = match value { - Value::Int(n) if n == Integer::ZERO => Ok(false), - Value::Int(n) if n == one => Ok(true), + Value::Int(n) if n == Integer::ZERO => Ok(true), + Value::Int(_) => Ok(false), _ => Err(FFIError::ExternError { value: (value).clone(), @@ -151,7 +150,7 @@ pub fn unpair(env: &Context, value: Value) -> VMResult<()> { } _ => Err(FFIError::ExternError { value: (value), - msg: "type mismatch, expected Pair".to_owned(), + msg: "unpair, type mismatch, expected Pair".to_owned(), } .into()), } @@ -162,7 +161,7 @@ pub fn car(env: &Context, value: Value) -> VMResult { Value::Pair { fst, snd: _ } => conversions::to_i64(fst.data().as_ffi()), _ => Err(FFIError::ExternError { value: (value), - msg: "type mismatch, expected Pair".to_owned(), + msg: "car, type mismatch, expected Pair".to_owned(), } .into()), } @@ -173,7 +172,7 @@ pub fn cdr(env: &Context, value: Value) -> VMResult { Value::Pair { fst: _, snd } => conversions::to_i64(snd.data().as_ffi()), _ => Err(FFIError::ExternError { value: (value), - msg: "type mismatch, expected Pair".to_owned(), + msg: "cdr, type mismatch, expected Pair".to_owned(), } .into()), } @@ -780,7 +779,7 @@ pub fn get_n(env: &Context, idx: u32, value: Value) -> VMResult { (_, value) => { return Err(FFIError::ExternError { value: (value), - msg: "type mismatch, expected Pair".to_owned(), + msg: "get_n, type mismatch, expected Pair".to_owned(), } .into()) } @@ -893,6 +892,7 @@ pub fn get_and_update(env: &Context, key: Value, value: Value, map: Value) -> VM .into()), } } + pub const fn call1(f: F) -> impl Fn(&Context, i64) -> VMResult where F: Fn(&Context, Value) -> VMResult, @@ -1183,6 +1183,10 @@ pub fn make_imports(env: &Context, store: &Store) -> ImportObject { "transfer_tokens", Function::new_native_with_env(store, env.clone(), call3(transfer_tokens)), ); + exports.insert( + "now", + Function::new_native_with_env(store, env.clone(), now), + ); exports.insert( "nil", Function::new_native_with_env(store, env.clone(), nil), @@ -1422,6 +1426,14 @@ fn read_ticket(env: &Context, payload: Value) -> VMResult<()> { )), } } +fn now(c: &Context) -> VMResult { + let predef = unsafe { &PREDEF }; + let now = predef + .get("now") + .map_or_else(|| Err(VmError::RuntimeErr("cant happen".to_owned())), Ok)?; + let bumped = c.bump(now.clone()); + conversions::to_i64(bumped) +} fn nil(c: &Context) -> VMResult { let predef = unsafe { &PREDEF }; let nil = predef diff --git a/crates/vm_library/tests/fa12.rs b/crates/vm_library/tests/fa12.rs index 0bc2b36..4ab7738 100644 --- a/crates/vm_library/tests/fa12.rs +++ b/crates/vm_library/tests/fa12.rs @@ -117,7 +117,8 @@ fn approve() { let arg = Value::Union(Union::Left(bump)); let (deser, module) = common::deser(payload); let tickets: Vec = vec![]; - let init = common::create_incoming_managed(&module, &deser, &tickets, arg, storage, &None); + let init = + common::create_incoming_managed(&module, &deser, &tickets, arg, storage.clone(), &None); let ExecutionResult { new_storage, .. } = invoke_managed(init).unwrap(); assert_eq!( serde_json::to_string(&new_storage).unwrap(), @@ -165,7 +166,8 @@ fn transfer() { let arg = Value::Union(Union::Right(bump)); let (deser, module) = common::deser(payload); let tickets: Vec = vec![]; - let init = common::create_incoming_managed(&module, &deser, &tickets, arg, storage, &None); + let init = + common::create_incoming_managed(&module, &deser, &tickets, arg, storage.clone(), &None); let ExecutionResult { new_storage, .. } = invoke_managed(init).unwrap(); assert_eq!( serde_json::to_string(&new_storage).unwrap(), diff --git a/crates/vm_library/tests/hashlock.rs b/crates/vm_library/tests/hashlock.rs new file mode 100644 index 0000000..31bd55f --- /dev/null +++ b/crates/vm_library/tests/hashlock.rs @@ -0,0 +1,73 @@ +use vm_library::{ + arena::ARENA, + execution_result::ExecutionResult, + instance::invoke_managed, + managed::value::Value, path::Path, +}; + +mod common; + +const PAYLOAD: &str = r#" +{ + "module_": "\n(module\n (import \"env\" \"dup_host\" (func $dup_host (param i64 ) (result)))\n(import \"env\" \"pair\" (func $pair (param i64 i64) (result i64)))\n(import \"env\" \"unpair\" (func $unpair (param i64)))\n(import \"env\" \"z_add\" (func $z_add (param i64 i64) (result i64)))\n(import \"env\" \"z_sub\" (func $z_sub (param i64 i64) (result i64)))\n(import \"env\" \"z_mul\" (func $z_mul (param i64 i64) (result i64)))\n(import \"env\" \"neg\" (func $neg (param i64) (result i64)))\n(import \"env\" \"lsl\" (func $lsl (param i64 i64) (result i64)))\n(import \"env\" \"concat\" (func $concat (param i64 i64) (result i64)))\n(import \"env\" \"lsr\" (func $lsr (param i64 i64) (result i64)))\n(import \"env\" \"compare\" (func $compare (param i64 i64) (result i64)))\n(import \"env\" \"car\" (func $car (param i64) (result i64)))\n(import \"env\" \"cdr\" (func $cdr (param i64) (result i64)))\n(import \"env\" \"some\" (func $some (param i64) (result i64)))\n(import \"env\" \"now\" (func $now (result i64)))\n(import \"env\" \"nil\" (func $nil (result i64)))\n(import \"env\" \"true\" (func $true (result i64)))\n(import \"env\" \"false\" (func $false (result i64)))\n(import \"env\" \"none\" (func $none (result i64)))\n(import \"env\" \"unit\" (func $unit (result i64)))\n(import \"env\" \"zero\" (func $zero (result i64)))\n(import \"env\" \"empty_map\" (func $empty_map (result i64)))\n(import \"env\" \"empty_set\" (func $empty_set (result i64)))\n(import \"env\" \"empty_big_map\" (func $empty_big_map (result i64)))\n(import \"env\" \"sender\" (func $sender (result i64)))\n(import \"env\" \"source\" (func $source (result i64)))\n(import \"env\" \"map_get\" (func $map_get (param i64 i64) (result i64)))\n(import \"env\" \"mem\" (func $mem (param i64 i64) (result i64)))\n(import \"env\" \"update\" (func $update (param i64 i64 i64) (result i64)))\n(import \"env\" \"iter\" (func $iter (param i64 i32) (result )))\n(import \"env\" \"map\" (func $map (param i64 i32) (result i64)))\n(import \"env\" \"if_left\" (func $if_left (param i64) (result i32)))\n(import \"env\" \"if_none\" (func $if_none (param i64) (result i32)))\n(import \"env\" \"if_cons\" (func $if_cons (param i64) (result i32)))\n(import \"env\" \"isnat\" (func $isnat (param i64) (result i64)))\n(import \"env\" \"not\" (func $not (param i64) (result i64)))\n(import \"env\" \"or\" (func $or (param i64 i64) (result i64)))\n(import \"env\" \"and\" (func $and (param i64 i64) (result i64)))\n(import \"env\" \"xor\" (func $xor (param i64 i64) (result i64)))\n(import \"env\" \"deref_bool\" (func $deref_bool (param i64) (result i32)))\n(import \"env\" \"neq\" (func $neq (param i64) (result i64)))\n(import \"env\" \"failwith\" (func $failwith (param i64)))\n(import \"env\" \"get_n\" (func $get_n (param i32 i64) (result i64)))\n(import \"env\" \"exec\" (func $exec (param i64 i64) (result i64)))\n(import \"env\" \"apply\" (func $apply (param i64 i64) (result i64)))\n(import \"env\" \"const\" (func $const (param i32) (result i64)))\n(import \"env\" \"abs\" (func $abs (param i64) (result i64)))\n(import \"env\" \"eq\" (func $eq (param i64) (result i64)))\n(import \"env\" \"gt\" (func $gt (param i64) (result i64)))\n(import \"env\" \"lt\" (func $lt (param i64) (result i64)))\n(import \"env\" \"closure\" (func $closure (param i32) (result i64)))\n(import \"env\" \"left\" (func $left (param i64) (result i64)))\n(import \"env\" \"right\" (func $right (param i64) (result i64)))\n(import \"env\" \"cons\" (func $cons (param i64 i64) (result i64)))\n(import \"env\" \"transfer_tokens\" (func $transfer_tokens (param i64 i64 i64) (result i64)))\n(import \"env\" \"address\" (func $address (param i64) (result i64)))\n(import \"env\" \"contract\" (func $contract (param i64) (result i64)))\n(import \"env\" \"self\" (func $self (result i64)))\n(import \"env\" \"self_address\" (func $self_address (result i64)))\n(import \"env\" \"get_and_update\" (func $get_and_update (param i64 i64 i64)))\n(import \"env\" \"read_ticket\" (func $read_ticket (param i64)))\n(import \"env\" \"ticket\" (func $ticket (param i64 i64) (result i64)))\n(import \"env\" \"join_tickets\" (func $join_tickets (param i64) (result i64)))\n(import \"env\" \"split_ticket\" (func $split_ticket (param i64 i64) (result i64)))\n(import \"env\" \"amount\" (func $amount (result i64)))\n(import \"env\" \"balance\" (func $balance (result i64)))\n(import \"env\" \"ediv\" (func $ediv (param i64 i64) (result i64)))\n(import \"env\" \"ge\" (func $ge (param i64) (result i64)))\n(import \"env\" \"le\" (func $le (param i64) (result i64)))\n(import \"env\" \"size\" (func $size (param i64) (result i64)))\n(import \"env\" \"int\" (func $int (param i64) (result i64)))\n(import \"env\" \"implicit_account\" (func $implicit_account (param i64) (result i64)))\n(import \"env\" \"blake2b\" (func $blake2b (param i64) (result i64)))\n(import \"env\" \"pack\" (func $pack (param i64) (result i64)))\n(import \"env\" \"unpack\" (func $unpack (param i64) (result i64)))\n(import \"env\" \"keccak\" (func $keccak (param i64) (result i64)))\n(import \"env\" \"sha256\" (func $sha256 (param i64) (result i64)))\n(import \"env\" \"sha3\" (func $sha3 (param i64) (result i64)))\n(import \"env\" \"sha512\" (func $sha512 (param i64) (result i64)))\n\n (global $mode i32 (i32.const 0))\n\n (memory 4)\n (global $sp (mut i32) (i32.const 4000)) ;; stack pointer\n (global $sh_sp (mut i32) (i32.const 1000)) ;;shadow_stack stack pointer\n\n (global $__stack_base i32 (i32.const 32768))\n\n (type $callback_t (func (param i64) (result i64)))\n (func $call_callback (param $arg1 i64) (param $idx i32) (result i64)\n (call_indirect (type $callback_t) (local.get $arg1) (local.get $idx)))\n\n (type $callback_t_unit (func (param i64) (result)))\n (func $call_callback_unit (param $arg1 i64) (param $idx i32) (result )\n (call_indirect (type $callback_t_unit)\n (local.get $arg1)\n (local.get $idx)))\n\n (func $dip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.set $stop (i32.const 0))\n (local.set $sp' (global.get $sp))\n (local.tee $sh_sp' (i32.sub (global.get $sh_sp) (local.get $n)))\n global.set $sh_sp\n (loop $l\n (i32.mul (i32.const 8) (i32.add (global.get $__stack_base) (i32.add (local.get $sh_sp') (local.get $stop))))\n (i64.load (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop))))\n i64.store\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n\n (global.set $sp\n (i32.add\n (local.get $sp') (local.get $n))))\n\n (func $undip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.tee $sp' (i32.sub (global.get $sp) (local.get $n)))\n global.set $sp\n (local.set $sh_sp' (global.get $sh_sp))\n (local.set $stop (i32.const 0))\n (loop $l\n (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop)))\n (i64.load\n (i32.add\n (global.get $__stack_base)\n (i32.mul (i32.const 8) (i32.add (local.get $sh_sp') (local.get $stop)))))\n (i64.store)\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n (global.set $sh_sp (i32.add (local.get $sh_sp') (local.get $n))))\n\n (func $dup (param $n i32) (result)\n (i64.load (i32.mul (i32.const 8) (i32.add (global.get $sp) (local.get $n))))\n (call $dup_host))\n\n (func $swap (param) (result)\n (local $v1 i64)\n (local $v2 i64)\n (local.set $v1 (call $pop))\n (local.set $v2 (call $pop))\n (call $push (local.get $v1))\n (call $push (local.get $v2)))\n\n (func $dug (param $n i32) (result)\n (local $idx i32)\n (local $loop_idx i32)\n (local $sp' i32)\n (local $top i64)\n (local.set $sp' (i32.add (global.get $sp) (local.get $n)))\n (local.tee $idx (global.get $sp))\n (local.tee $loop_idx)\n (i32.mul (i32.const 8))\n i64.load\n local.set $top\n (loop $loop\n (i32.mul (i32.const 8) (local.get $idx))\n (i32.add (local.get $loop_idx) (i32.const 1))\n local.tee $loop_idx\n (i32.mul (i32.const 8))\n i64.load\n i64.store\n (local.set $idx (i32.add (local.get $idx) (i32.const 1)))\n (local.get $idx)\n (local.get $sp')\n i32.lt_u\n br_if $loop)\n\n (i64.store (i32.mul (i32.const 8) (local.get $sp')) (local.get $top)))\n\n (func $dig (param $n i32) (result)\n (local $idx i32) (local $t i32) (local $digged i64)\n\n (local.set $digged\n (i64.load\n (i32.mul (i32.const 8)\n (local.tee $idx (i32.add (global.get $sp) (local.get $n))))))\n\n (loop $loop\n (local.set $t (i32.mul (i32.const 8) (local.get $idx)))\n\n (i64.store (local.get $t)\n (i64.load\n (i32.mul\n (i32.const 8)\n (local.tee $idx (i32.sub (local.get $idx) (i32.const 1))))))\n\n (br_if $loop\n (i32.lt_u (global.get $sp) (local.get $idx))))\n\n (i64.store (i32.mul (i32.const 8) (local.get $idx)) (local.get $digged)))\n\n (func $pop (result i64)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (global.get $sp)))\n i64.load\n (global.set $sp (i32.add (local.get $spp) (i32.const 1)))) ;;set stackptr\n\n (func $push (param $value i64) (result)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (i32.sub (global.get $sp) (i32.const 1)) ))\n (i64.store (local.get $value))\n (global.set $sp (local.get $spp))) ;;set stackptr\n\n (func $drop (param $n i32) (result)\n (global.set $sp (i32.add (global.get $sp) (local.get $n)))) ;;set stackptr\n\n (table $closures funcref (elem ))\n\n\n (func $main (param $v1 i64) (result i64)\n (local $1 i64)\n (call $push (local.get $v1))\n (call $unpair (call $pop)) ;; implicit return\n(call $if_left (call $pop)) (if (then (call $push (call $const (i32.const 0))) (; 86400 ;)\n(call $push (call $now))\n(call $push (call $z_add (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $dup (i32.const 1))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $swap)\n(call $push (call $some (call $pop)))\n(call $push (call $sender))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $dup (i32.const 1))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 2))\n(call $unpair (call $pop)) ;; implicit return\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))) (else (call $dup (i32.const 1))\n(call $push (call $cdr (call $pop)))\n(call $push (call $not (call $pop)))\n(call $deref_bool (call $pop)) (if (then (call $drop (i32.const 2))\n(call $push (call $const (i32.const 1))) (; \"This contract has already been used.\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dup (i32.const 1))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $push (call $sender))\n(call $push (call $map_get (call $pop) (call $pop)))\n(call $if_none (call $pop)) (if (then (call $push (call $const (i32.const 2))) (; \"You have not made a commitment to hash against yet.\" ;)\n(call $failwith (call $pop)) unreachable) (else ))\n(call $dup (i32.const 0))\n(call $push (call $car (call $pop)))\n(call $push (call $now))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $lt (call $pop)))\n(call $deref_bool (call $pop)) (if (then (call $drop (i32.const 3))\n(call $push (call $const (i32.const 3))) (; \"It has not been 24 hours since your commit yet.\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $push (call $sender))\n(call $push (call $pack (call $pop)))\n(call $dup (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $concat (call $pop) (call $pop)))\n(call $push (call $sha256 (call $pop)))\n(call $swap)\n(call $push (call $cdr (call $pop)))\n(call $swap)\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $neq (call $pop)))\n(call $deref_bool (call $pop)) (if (then (call $drop (i32.const 2))\n(call $push (call $const (i32.const 4))) (; \"This reveal does not match your commitment.\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dup (i32.const 0))\n(call $push (call $car (call $pop)))\n(call $push (call $sha256 (call $pop)))\n(call $dup (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then (call $push (call $const (i32.const 5)))\n(call $dig (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $unit))\n(call $dig (i32.const 2))\n(call $push (call $cdr (call $pop)))\n(call $swap)\n(call $push (call $exec (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))) (else (call $drop (i32.const 2))\n(call $push (call $const (i32.const 6))) (; \"Your commitment did not match the storage hash.\" ;)\n(call $failwith (call $pop)) unreachable))))))))))\n (call $pop))\n\n (export \"push\" (func $push))\n (export \"pop\" (func $push))\n (export \"main\" (func $main))\n (export \"closures\" (table $closures))\n (export \"call_callback\" (func $call_callback))\n (export \"call_callback_unit\" (func $call_callback_unit))\n )\n", + "constants": [ + [ 0, [ "Int", "86400" ] ], + [ 1, [ "String", "This contract has already been used." ] ], + [ + 2, [ "String", "You have not made a commitment to hash against yet." ] + ], + [ 3, [ "String", "It has not been 24 hours since your commit yet." ] ], + [ 4, [ "String", "This reveal does not match your commitment." ] ], + [ 5, [ "Bool", false ] ], + [ 6, [ "String", "Your commitment did not match the storage hash." ] ] + ], + "entrypoints": { "%commit": [ "Left" ], "%reveal": [ "Right" ] } +} +"#; + +#[test] +fn commit() { + let payload = PAYLOAD.to_string(); + + let arena = unsafe { &mut ARENA }; + let storage: Value = serde_json::from_str( + r#" + ["Pair", + ["Pair", + ["Map", + [ + [ + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"], + ["Pair", ["Int", "0"], ["Bytes", "hello"]] + ] + ] + ], + ["Bytes", "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"] + ], + ["Bool", false] + ] + "#, + ) + .unwrap(); + + let arg: Value = serde_json::from_str(r#" + ["Bytes", "Hello"] + "#).unwrap(); + // let bump = arena.insert(arg); + // let arg = Value::Union(Union::Left(bump)); + let (deser, module) = common::deser(payload); + let tickets = vec![]; + let path = Some(vec![Path::Left]); + let init = + common::create_incoming_managed(&module, &deser, &tickets, arg, storage.clone(), &path); + let ExecutionResult { + new_storage: _, + ops: _, + .. + } = invoke_managed(init).unwrap(); + + // assert_eq!( + // serde_json::to_string(&new_storage).unwrap(), + // serde_json::to_string(&desired_storage).unwrap() + // ); +} \ No newline at end of file diff --git a/crates/vm_library/tests/id_ticket.rs b/crates/vm_library/tests/id_ticket.rs new file mode 100644 index 0000000..ee025e6 --- /dev/null +++ b/crates/vm_library/tests/id_ticket.rs @@ -0,0 +1,408 @@ +use vm_library::{ + arena::{ARENA, TICKETABLE}, + execution_result::ExecutionResult, + instance::invoke_managed, + managed::value::{Union, Value}, + ticket_table::{Ticket, TicketId}, +}; + +mod common; + +const PAYLOAD: &str = r#" +{ + "module_": "\n(module\n (import \"env\" \"dup_host\" (func $dup_host (param i64 ) (result)))\n(import \"env\" \"pair\" (func $pair (param i64 i64) (result i64)))\n(import \"env\" \"unpair\" (func $unpair (param i64)))\n(import \"env\" \"z_add\" (func $z_add (param i64 i64) (result i64)))\n(import \"env\" \"z_sub\" (func $z_sub (param i64 i64) (result i64)))\n(import \"env\" \"z_mul\" (func $z_mul (param i64 i64) (result i64)))\n(import \"env\" \"neg\" (func $neg (param i64) (result i64)))\n(import \"env\" \"lsl\" (func $lsl (param i64 i64) (result i64)))\n(import \"env\" \"concat\" (func $concat (param i64 i64) (result i64)))\n(import \"env\" \"lsr\" (func $lsr (param i64 i64) (result i64)))\n(import \"env\" \"compare\" (func $compare (param i64 i64) (result i64)))\n(import \"env\" \"car\" (func $car (param i64) (result i64)))\n(import \"env\" \"cdr\" (func $cdr (param i64) (result i64)))\n(import \"env\" \"some\" (func $some (param i64) (result i64)))\n(import \"env\" \"nil\" (func $nil (result i64)))\n(import \"env\" \"true\" (func $true (result i64)))\n(import \"env\" \"false\" (func $false (result i64)))\n(import \"env\" \"none\" (func $none (result i64)))\n(import \"env\" \"unit\" (func $unit (result i64)))\n(import \"env\" \"zero\" (func $zero (result i64)))\n(import \"env\" \"empty_map\" (func $empty_map (result i64)))\n(import \"env\" \"empty_set\" (func $empty_set (result i64)))\n(import \"env\" \"empty_big_map\" (func $empty_big_map (result i64)))\n(import \"env\" \"sender\" (func $sender (result i64)))\n(import \"env\" \"source\" (func $source (result i64)))\n(import \"env\" \"map_get\" (func $map_get (param i64 i64) (result i64)))\n(import \"env\" \"mem\" (func $mem (param i64 i64) (result i64)))\n(import \"env\" \"update\" (func $update (param i64 i64 i64) (result i64)))\n(import \"env\" \"iter\" (func $iter (param i64 i32) (result )))\n(import \"env\" \"map\" (func $map (param i64 i32) (result i64)))\n(import \"env\" \"if_left\" (func $if_left (param i64) (result i32)))\n(import \"env\" \"if_none\" (func $if_none (param i64) (result i32)))\n(import \"env\" \"if_cons\" (func $if_cons (param i64) (result i32)))\n(import \"env\" \"isnat\" (func $isnat (param i64) (result i64)))\n(import \"env\" \"not\" (func $not (param i64) (result i64)))\n(import \"env\" \"or\" (func $or (param i64 i64) (result i64)))\n(import \"env\" \"and\" (func $and (param i64 i64) (result i64)))\n(import \"env\" \"xor\" (func $xor (param i64 i64) (result i64)))\n(import \"env\" \"deref_bool\" (func $deref_bool (param i64) (result i32)))\n(import \"env\" \"neq\" (func $neq (param i64) (result i64)))\n(import \"env\" \"failwith\" (func $failwith (param i64)))\n(import \"env\" \"get_n\" (func $get_n (param i32 i64) (result i64)))\n(import \"env\" \"exec\" (func $exec (param i64 i64) (result i64)))\n(import \"env\" \"apply\" (func $apply (param i64 i64) (result i64)))\n(import \"env\" \"const\" (func $const (param i32) (result i64)))\n(import \"env\" \"abs\" (func $abs (param i64) (result i64)))\n(import \"env\" \"eq\" (func $eq (param i64) (result i64)))\n(import \"env\" \"gt\" (func $gt (param i64) (result i64)))\n(import \"env\" \"lt\" (func $lt (param i64) (result i64)))\n(import \"env\" \"closure\" (func $closure (param i32) (result i64)))\n(import \"env\" \"left\" (func $left (param i64) (result i64)))\n(import \"env\" \"right\" (func $right (param i64) (result i64)))\n(import \"env\" \"cons\" (func $cons (param i64 i64) (result i64)))\n(import \"env\" \"transfer_tokens\" (func $transfer_tokens (param i64 i64 i64) (result i64)))\n(import \"env\" \"address\" (func $address (param i64) (result i64)))\n(import \"env\" \"contract\" (func $contract (param i64) (result i64)))\n(import \"env\" \"self\" (func $self (result i64)))\n(import \"env\" \"self_address\" (func $self_address (result i64)))\n(import \"env\" \"get_and_update\" (func $get_and_update (param i64 i64 i64)))\n(import \"env\" \"read_ticket\" (func $read_ticket (param i64)))\n(import \"env\" \"ticket\" (func $ticket (param i64 i64) (result i64)))\n(import \"env\" \"join_tickets\" (func $join_tickets (param i64) (result i64)))\n(import \"env\" \"split_ticket\" (func $split_ticket (param i64 i64) (result i64)))\n(import \"env\" \"amount\" (func $amount (result i64)))\n(import \"env\" \"balance\" (func $balance (result i64)))\n(import \"env\" \"ediv\" (func $ediv (param i64 i64) (result i64)))\n(import \"env\" \"ge\" (func $ge (param i64) (result i64)))\n(import \"env\" \"le\" (func $le (param i64) (result i64)))\n(import \"env\" \"size\" (func $size (param i64) (result i64)))\n(import \"env\" \"int\" (func $int (param i64) (result i64)))\n(import \"env\" \"implicit_account\" (func $implicit_account (param i64) (result i64)))\n(import \"env\" \"blake2b\" (func $blake2b (param i64) (result i64)))\n(import \"env\" \"pack\" (func $pack (param i64) (result i64)))\n(import \"env\" \"unpack\" (func $unpack (param i64) (result i64)))\n(import \"env\" \"keccak\" (func $keccak (param i64) (result i64)))\n(import \"env\" \"sha256\" (func $sha256 (param i64) (result i64)))\n(import \"env\" \"sha3\" (func $sha3 (param i64) (result i64)))\n(import \"env\" \"sha512\" (func $sha512 (param i64) (result i64)))\n\n (global $mode i32 (i32.const 0))\n\n (memory 4)\n (global $sp (mut i32) (i32.const 4000)) ;; stack pointer\n (global $sh_sp (mut i32) (i32.const 1000)) ;;shadow_stack stack pointer\n\n (global $__stack_base i32 (i32.const 32768))\n\n (type $callback_t (func (param i64) (result i64)))\n (func $call_callback (param $arg1 i64) (param $idx i32) (result i64)\n (call_indirect (type $callback_t) (local.get $arg1) (local.get $idx)))\n\n (type $callback_t_unit (func (param i64) (result)))\n (func $call_callback_unit (param $arg1 i64) (param $idx i32) (result )\n (call_indirect (type $callback_t_unit)\n (local.get $arg1)\n (local.get $idx)))\n\n (func $dip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.set $stop (i32.const 0))\n (local.set $sp' (global.get $sp))\n (local.tee $sh_sp' (i32.sub (global.get $sh_sp) (local.get $n)))\n global.set $sh_sp\n (loop $l\n (i32.mul (i32.const 8) (i32.add (global.get $__stack_base) (i32.add (local.get $sh_sp') (local.get $stop))))\n (i64.load (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop))))\n i64.store\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n\n (global.set $sp\n (i32.add\n (local.get $sp') (local.get $n))))\n\n (func $undip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.tee $sp' (i32.sub (global.get $sp) (local.get $n)))\n global.set $sp\n (local.set $sh_sp' (global.get $sh_sp))\n (local.set $stop (i32.const 0))\n (loop $l\n (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop)))\n (i64.load\n (i32.add\n (global.get $__stack_base)\n (i32.mul (i32.const 8) (i32.add (local.get $sh_sp') (local.get $stop)))))\n (i64.store)\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n (global.set $sh_sp (i32.add (local.get $sh_sp') (local.get $n))))\n\n (func $dup (param $n i32) (result)\n (i64.load (i32.mul (i32.const 8) (i32.add (global.get $sp) (local.get $n))))\n (call $dup_host))\n\n (func $swap (param) (result)\n (local $v1 i64)\n (local $v2 i64)\n (local.set $v1 (call $pop))\n (local.set $v2 (call $pop))\n (call $push (local.get $v1))\n (call $push (local.get $v2)))\n\n (func $dug (param $n i32) (result)\n (local $idx i32)\n (local $loop_idx i32)\n (local $sp' i32)\n (local $top i64)\n (local.set $sp' (i32.add (global.get $sp) (local.get $n)))\n (local.tee $idx (global.get $sp))\n (local.tee $loop_idx)\n (i32.mul (i32.const 8))\n i64.load\n local.set $top\n (loop $loop\n (i32.mul (i32.const 8) (local.get $idx))\n (i32.add (local.get $loop_idx) (i32.const 1))\n local.tee $loop_idx\n (i32.mul (i32.const 8))\n i64.load\n i64.store\n (local.set $idx (i32.add (local.get $idx) (i32.const 1)))\n (local.get $idx)\n (local.get $sp')\n i32.lt_u\n br_if $loop)\n\n (i64.store (i32.mul (i32.const 8) (local.get $sp')) (local.get $top)))\n\n (func $dig (param $n i32) (result)\n (local $idx i32) (local $t i32) (local $digged i64)\n\n (local.set $digged\n (i64.load\n (i32.mul (i32.const 8)\n (local.tee $idx (i32.add (global.get $sp) (local.get $n))))))\n\n (loop $loop\n (local.set $t (i32.mul (i32.const 8) (local.get $idx)))\n\n (i64.store (local.get $t)\n (i64.load\n (i32.mul\n (i32.const 8)\n (local.tee $idx (i32.sub (local.get $idx) (i32.const 1))))))\n\n (br_if $loop\n (i32.lt_u (global.get $sp) (local.get $idx))))\n\n (i64.store (i32.mul (i32.const 8) (local.get $idx)) (local.get $digged)))\n\n (func $pop (result i64)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (global.get $sp)))\n i64.load\n (global.set $sp (i32.add (local.get $spp) (i32.const 1)))) ;;set stackptr\n\n (func $push (param $value i64) (result)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (i32.sub (global.get $sp) (i32.const 1)) ))\n (i64.store (local.get $value))\n (global.set $sp (local.get $spp))) ;;set stackptr\n\n (func $drop (param $n i32) (result)\n (global.set $sp (i32.add (global.get $sp) (local.get $n)))) ;;set stackptr\n\n (table $closures funcref (elem ))\n\n\n (func $main (param $v1 i64) (result i64)\n (local $1 i64)\n (call $push (local.get $v1))\n (call $unpair (call $pop)) ;; implicit return\n(call $if_left (call $pop)) (if (then (call $if_left (call $pop)) (if (then (call $dup (i32.const 0))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $read_ticket (call $pop)) ;; implicit return\n(call $swap)\n(call $drop (i32.const 1))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dup (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $swap)\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"Incorrect amount paid.\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dup (i32.const 1))\n(call $push (call $cdr (call $pop)))\n(call $push (call $car (call $pop)))\n(call $dup (i32.const 1))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $if_none (call $pop)) (if (then (call $push (call $sender))) (else ))\n(call $dig (i32.const 2))\n(call $push (call $cdr (call $pop)))\n(call $push (call $sender))\n(call $dig (i32.const 2))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $dup (i32.const 2))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $push (call $const (i32.const 1))) (; 1 ;)\n(call $dup (i32.const 3))\n(call $push (call $z_add (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $dup (i32.const 3))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 4))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $dig (i32.const 3))\n(call $push (call $some (call $pop)))\n(call $dig (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))) (else (call $read_ticket (call $pop)) ;; implicit return\n(call $swap)\n(call $drop (i32.const 1))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dup (i32.const 1))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $swap)\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"Incorrect amount paid.\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dup (i32.const 0))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $push (call $const (i32.const 1))) (; 1 ;)\n(call $dup (i32.const 2))\n(call $push (call $cdr (call $pop)))\n(call $push (call $car (call $pop)))\n(call $push (call $z_add (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $dup (i32.const 1))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))) (else (call $if_left (call $pop)) (if (then (call $push (call $zero)) (; 0 ;)\n(call $push (call $amount))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $neq (call $pop)))\n(call $deref_bool (call $pop)) (if (then (call $drop (i32.const 2))\n(call $push (call $const (i32.const 2))) (; \"Updating details doesn't cost anything.\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dup (i32.const 0))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $dup (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $dup (i32.const 0))\n(call $dup (i32.const 2))\n(call $push (call $map_get (call $pop) (call $pop)))\n(call $if_none (call $pop)) (if (then (call $push (call $const (i32.const 3))) (; \"This ID does not exist.\" ;)\n(call $failwith (call $pop)) unreachable) (else ))\n(call $dup (i32.const 0))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $dup (i32.const 1))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $push (call $or (call $pop) (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 4))) (; \"You are not the owner or controller of this ID.\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dup (i32.const 4))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dup (i32.const 5))\n(call $push (call $cdr (call $pop)))\n(call $push (call $car (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $dig (i32.const 5))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 3))\n(call $dup (i32.const 5))\n(call $push (call $cdr (call $pop)))\n(call $if_none (call $pop)) (if (then (call $dup (i32.const 3))\n(call $push (call $cdr (call $pop)))) (else ))\n(call $dup (i32.const 4))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 7))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $if_none (call $pop)) (if (then (call $dig (i32.const 5))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))) (else (call $dig (i32.const 6))\n(call $drop (i32.const 1))))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $some (call $pop)))\n(call $dig (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $push (call $zero)) (; 0 ;)\n(call $push (call $amount))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $neq (call $pop)))\n(call $deref_bool (call $pop)) (if (then (call $drop (i32.const 2))\n(call $push (call $const (i32.const 5))) (; \"Updating owner doesn't cost anything.\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dup (i32.const 0))\n(call $push (call $car (call $pop)))\n(call $dup (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $dup (i32.const 0))\n(call $dup (i32.const 2))\n(call $push (call $map_get (call $pop) (call $pop)))\n(call $if_none (call $pop)) (if (then (call $push (call $const (i32.const 3))) (; \"This ID does not exist.\" ;)\n(call $failwith (call $pop)) unreachable) (else ))\n(call $dup (i32.const 0))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 6))) (; \"You are not the owner of this ID.\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dup (i32.const 4))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dup (i32.const 5))\n(call $push (call $cdr (call $pop)))\n(call $push (call $car (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $dig (i32.const 5))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 3))\n(call $dup (i32.const 3))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 6))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 5))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $some (call $pop)))\n(call $dig (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))))))))\n (call $pop))\n\n (export \"push\" (func $push))\n (export \"pop\" (func $push))\n (export \"main\" (func $main))\n (export \"closures\" (table $closures))\n (export \"call_callback\" (func $call_callback))\n (export \"call_callback_unit\" (func $call_callback_unit))\n )\n", + "constants": [ + [ 0, [ "String", "Incorrect amount paid." ] ], + [ 1, [ "Int", "1" ] ], + [ 2, [ "String", "Updating details doesn't cost anything." ] ], + [ 3, [ "String", "This ID does not exist." ] ], + [ 4, [ "String", "You are not the owner or controller of this ID." ] ], + [ 5, [ "String", "Updating owner doesn't cost anything." ] ], + [ 6, [ "String", "You are not the owner of this ID." ] ] + ], + "entrypoints": { + "%buy": [ "Left", "Left" ], + "%skip": [ "Left", "Right" ], + "%update_details": [ "Right", "Left" ], + "%update_owner": [ "Right", "Right" ] + } +} + +"#; + +#[test] +fn buy() { + let payload = PAYLOAD.to_string(); + + let arena = unsafe { &mut ARENA }; + let storage: Value = serde_json::from_str( + r#" + [ + "Pair", + ["Pair", + ["Map", + [ + [ + ["Int", "1"], + ["Pair", + ["Pair", + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"], + ["String", "tz2AcXz8WUu51YYdE5Rsnosxd1hkhW9tG7pd"] + ], + ["Bytes", "0"] + ] + ] + ] + ], + ["Int", "7"] + ], + ["Pair", + ["Int", "2"], + ["Int", "6"] + ] + ]"#, + ) + .unwrap(); + + let desired_storage: Value = serde_json::from_str( + r#" + [ + "Pair", + ["Pair", + ["Map", + [ + [ + ["Int", "1"], + ["Pair", + ["Pair", + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"], + ["String", "tz2AcXz8WUu51YYdE5Rsnosxd1hkhW9tG7pd"] + ], + ["Bytes", "0"] + ] + ], + [ + ["Int", "2"], + ["Pair", + ["Pair", + ["String", "tz2AcXz8WUu51YYdE5Rsnosxd1hkhW9tG7pd"], + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"] + ], + ["Bytes", "1"] + ] + ] + ] + ], + ["Int", "7"] + ], + ["Pair", + ["Int", "3"], + ["Int", "6"] + ] + ]"#, + ) + .unwrap(); + + let ticket = Ticket::new( + TicketId::new( + "KT1WiBZHtvv3EczaN628DkNob4cayHzTEDNK".to_string(), + String::new(), + ), + 7, + ); + let tickets: Vec = vec![ticket]; + let ticket_table = unsafe { &mut TICKETABLE }; + ticket_table.populate(&tickets); + let arg: Value = serde_json::from_str(r#" + ["Pair", + ["Pair", + ["Option", ["String", "tz2AcXz8WUu51YYdE5Rsnosxd1hkhW9tG7pd"]], + ["Ticket", {"ticket_id":{"ticketer":"KT1WiBZHtvv3EczaN628DkNob4cayHzTEDNK","data":""},"amount":7,"live":true}] + ], + ["Bytes", "1"] + ]"#).unwrap(); + let bump = arena.insert(arg); + let arg = Value::Union(Union::Left(bump)); + let bump = arena.insert(arg); + let arg = Value::Union(Union::Left(bump)); + let (deser, module) = common::deser(payload); + let init = + common::create_incoming_managed(&module, &deser, &tickets, arg, storage.clone(), &None); + let ExecutionResult { + new_storage, + ops: _, + .. + } = invoke_managed(init).unwrap(); + + assert_eq!( + serde_json::to_string(&new_storage).unwrap(), + serde_json::to_string(&desired_storage).unwrap() + ); +} + +#[test] +fn update_owner() { + let payload = PAYLOAD.to_string(); + + let arena = unsafe { &mut ARENA }; + let storage: Value = serde_json::from_str( + r#" + [ + "Pair", + ["Pair", + ["Map", + [ + [ + ["Int", "1"], + ["Pair", + ["Pair", + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"], + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"] + ], + ["Bytes", "0"] + ] + ] + ] + ], + ["Int", "7"] + ], + ["Pair", + ["Int", "2"], + ["Int", "6"] + ] + ]"#, + ) + .unwrap(); + + let desired_storage: Value = serde_json::from_str( + r#" + [ + "Pair", + ["Pair", + ["Map", + [ + [ + ["Int", "1"], + ["Pair", + ["Pair", + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"], + ["String", "tz2AcXz8WUu51YYdE5Rsnosxd1hkhW9tG7pd"] + ], + ["Bytes", "0"] + ] + ] + ] + ], + ["Int", "7"] + ], + ["Pair", + ["Int", "2"], + ["Int", "6"] + ] + ]"#, + ) + .unwrap(); + + let arg: Value = serde_json::from_str( + r#"["Pair", ["Int", "1"], ["String", "tz2AcXz8WUu51YYdE5Rsnosxd1hkhW9tG7pd"]]"#, + ) + .unwrap(); + let bump = arena.insert(arg); + let arg = Value::Union(Union::Right(bump)); + let bump = arena.insert(arg); + let arg = Value::Union(Union::Right(bump)); + let (deser, module) = common::deser(payload); + let tickets: Vec = vec![]; + let init = + common::create_incoming_managed(&module, &deser, &tickets, arg, storage.clone(), &None); + let ExecutionResult { + new_storage, + ops: _, + .. + } = invoke_managed(init).unwrap(); + + assert_eq!( + serde_json::to_string(&new_storage).unwrap(), + serde_json::to_string(&desired_storage).unwrap() + ); +} + +#[test] +fn update_details() { + let payload = PAYLOAD.to_string(); + + let arena = unsafe { &mut ARENA }; + let storage: Value = serde_json::from_str( + r#" + [ + "Pair", + ["Pair", + ["Map", + [ + [ + ["Int", "1"], + ["Pair", + ["Pair", + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"], + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"] + ], + ["Bytes", "0"] + ] + ] + ] + ], + ["Int", "7"] + ], + ["Pair", + ["Int", "2"], + ["Int", "6"] + ] + ]"#, + ) + .unwrap(); + + let desired_storage: Value = serde_json::from_str( + r#" + [ + "Pair", + ["Pair", + ["Map", + [ + [ + ["Int", "1"], + ["Pair", + ["Pair", + ["String", "tz2AcXz8WUu51YYdE5Rsnosxd1hkhW9tG7pd"], + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"] + ], + ["Bytes", "1"] + ] + ] + ] + ], + ["Int", "7"] + ], + ["Pair", + ["Int", "2"], + ["Int", "6"] + ] + ]"#, + ) + .unwrap(); + + let arg: Value = serde_json::from_str(r#"["Pair", ["Pair", ["Int", "1"], ["Option", ["String", "tz2AcXz8WUu51YYdE5Rsnosxd1hkhW9tG7pd"]]], ["Option", ["Bytes", "1"]]]"#).unwrap(); + let bump = arena.insert(arg); + let arg = Value::Union(Union::Left(bump)); + let bump = arena.insert(arg); + let arg = Value::Union(Union::Right(bump)); + let (deser, module) = common::deser(payload); + let tickets: Vec = vec![]; + let init = + common::create_incoming_managed(&module, &deser, &tickets, arg, storage.clone(), &None); + let ExecutionResult { + new_storage, + ops: _, + .. + } = invoke_managed(init).unwrap(); + + assert_eq!( + serde_json::to_string(&new_storage).unwrap(), + serde_json::to_string(&desired_storage).unwrap() + ); +} + +#[test] +fn skip() { + let payload = PAYLOAD.to_string(); + + let arena = unsafe { &mut ARENA }; + let storage: Value = serde_json::from_str( + r#" + [ + "Pair", + ["Pair", + ["Map", + [ + [ + ["Int", "1"], + ["Pair", + ["Pair", + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"], + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"] + ], + ["Bytes", "0"] + ] + ] + ] + ], + ["Int", "7"] + ], + ["Pair", + ["Int", "2"], + ["Int", "6"] + ] + ]"#, + ) + .unwrap(); + + let desired_storage: Value = serde_json::from_str( + r#" + [ + "Pair", + ["Pair", + ["Map", + [ + [ + ["Int", "1"], + ["Pair", + ["Pair", + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"], + ["String", "tz1gvF4cD2dDtqitL3ZTraggSR1Mju2BKFEM"] + ], + ["Bytes", "0"] + ] + ] + ] + ], + ["Int", "7"] + ], + ["Pair", + ["Int", "3"], + ["Int", "6"] + ] + ]"#, + ) + .unwrap(); + + let ticket = Ticket::new( + TicketId::new( + "KT1WiBZHtvv3EczaN628DkNob4cayHzTEDNK".to_string(), + String::new(), + ), + 6, + ); + let tickets: Vec = vec![ticket]; + let ticket_table = unsafe { &mut TICKETABLE }; + ticket_table.populate(&tickets); + let arg: Value = serde_json::from_str(r#" + ["Ticket", {"ticket_id":{"ticketer":"KT1WiBZHtvv3EczaN628DkNob4cayHzTEDNK","data":""},"amount":6,"live":true}] + "#).unwrap(); + let bump = arena.insert(arg); + let arg = Value::Union(Union::Right(bump)); + let bump = arena.insert(arg); + let arg = Value::Union(Union::Left(bump)); + let (deser, module) = common::deser(payload); + let tickets: Vec = vec![]; + let init = + common::create_incoming_managed(&module, &deser, &tickets, arg, storage.clone(), &None); + let ExecutionResult { + new_storage, + ops: _, + .. + } = invoke_managed(init).unwrap(); + + assert_eq!( + serde_json::to_string(&new_storage).unwrap(), + serde_json::to_string(&desired_storage).unwrap() + ); +} diff --git a/crates/vm_library/tests/increment.rs b/crates/vm_library/tests/increment.rs index 1d494b0..1f0c35c 100644 --- a/crates/vm_library/tests/increment.rs +++ b/crates/vm_library/tests/increment.rs @@ -25,7 +25,8 @@ fn increment() { let arg = Value::Union(Union::Left(bump)); let (deser, module) = common::deser(payload); let tickets: Vec = vec![]; - let init = common::create_incoming_managed(&module, &deser, &tickets, arg, storage, &None); + let init = + common::create_incoming_managed(&module, &deser, &tickets, arg, storage.clone(), &None); let ExecutionResult { new_storage, .. } = invoke_managed(init).unwrap(); assert_eq!(new_storage, Value::Int(5.into())) } @@ -45,7 +46,8 @@ fn decrement() { let arg = Value::Union(Union::Left(bump)); let (deser, module) = common::deser(payload); let tickets: Vec = vec![]; - let init = common::create_incoming_managed(&module, &deser, &tickets, arg, storage, &None); + let init = + common::create_incoming_managed(&module, &deser, &tickets, arg, storage.clone(), &None); let ExecutionResult { new_storage, .. } = invoke_managed(init).unwrap(); assert_eq!(new_storage, Value::Int(2.into())) } @@ -63,7 +65,8 @@ fn reset() { let arg = Value::Union(Union::Right(bump)); let (deser, module) = common::deser(payload); let tickets: Vec = vec![]; - let init = common::create_incoming_managed(&module, &deser, &tickets, arg, storage, &None); + let init = + common::create_incoming_managed(&module, &deser, &tickets, arg, storage.clone(), &None); let ExecutionResult { new_storage, .. } = invoke_managed(init).unwrap(); assert_eq!(new_storage, Value::Int(0.into())) } diff --git a/dune b/dune index a5cb6ba..15f1738 100644 --- a/dune +++ b/dune @@ -1,6 +1,6 @@ (env (dev (flags - (:standard -w +A-48-42-44-70-66 -warn-error +A-3)))) + (:standard -w +A-48-58-42-44-70-66 -warn-error +A-3)))) (dirs :standard \ target crates) diff --git a/packages/tunac/bin/tunacc_test.ml b/packages/tunac/bin/tunacc_test.ml index 8d77ad9..a792126 100644 --- a/packages/tunac/bin/tunacc_test.ml +++ b/packages/tunac/bin/tunacc_test.ml @@ -8,6 +8,7 @@ let compile_contract filename = let wat, constants, entrypoints = filename |> read_file |> Tunac.Compiler.compile |> Result.get_ok in + let out = Tunac.Output.make wat constants entrypoints |> Result.get_ok in print_endline @@ Yojson.Safe.pretty_to_string @@ Tunac.Output.yojson_of_t out diff --git a/packages/tunac/lib/compiler.ml b/packages/tunac/lib/compiler.ml index 1be2903..ce28a96 100644 --- a/packages/tunac/lib/compiler.ml +++ b/packages/tunac/lib/compiler.ml @@ -36,6 +36,15 @@ let compile_constant ~ctx value = let rec compile_instruction ~ctx instruction = match instruction with | Prim (_, I_UNPAIR, _, _) -> "(call $unpair (call $pop)) ;; implicit return" + | Prim (_, I_PAIR, [ Int (_, x) ], _) -> + let int = Z.to_int x - 2 in + let rec go num acc = + if num = 0 then acc + else + go (num - 1) + (acc ^ "\n" ^ "(call $push (call $pair (call $pop) (call $pop)))") + in + go int "(call $push (call $pair (call $pop) (call $pop)))" | Prim (_, I_PAIR, _, _) -> "(call $push (call $pair (call $pop) (call $pop)))" | Prim (_, I_ADD, _, _) -> @@ -223,6 +232,10 @@ let rec compile_instruction ~ctx instruction = Printf.sprintf "%s (; \"%s\" ;)" (compile_constant ~ctx (Values.String s)) s | Prim (_, I_PUSH, [ _; Bytes (_, b) ], _) -> compile_constant ~ctx (Values.Bytes b) + | Prim (_, I_PUSH, [ _; Prim (_, D_False, [], _) ], _) -> + compile_constant ~ctx (Values.Bool 0) + | Prim (_, I_PUSH, [ _; Prim (_, D_True, [], _) ], _) -> + compile_constant ~ctx (Values.Bool 1) | Prim (_, I_LAMBDA, [ _; _; Seq (_, body) ], _) -> let name = gen_symbol ~ctx "$lambda" in let lambda = compile_lambda ~ctx ~unit:false name body in @@ -323,7 +336,8 @@ let compile code = let* parsed = match Parser.parse_expr code with | Ok expr -> Ok (root expr) - | (Error (`Parsing_error _) | Error (`Prim_parsing_error _)) as x -> x + | (Error (`Parsing_error _) | Error (`Prim_parsing_error _)) as x -> + x in match parsed with | Seq diff --git a/packages/tunac/tests/hashlock.t b/packages/tunac/tests/hashlock.t new file mode 100644 index 0000000..16b65bb --- /dev/null +++ b/packages/tunac/tests/hashlock.t @@ -0,0 +1,9 @@ +hashlock + $ ../bin/tunacc_test.exe contract hashlock.tz + Module validation error at 261:18 - 261:22: unknown function $nowFatal error: exception Invalid_argument("result is Error _") + Raised at Stdlib.invalid_arg in file "stdlib.ml", line 30, characters 20-45 + Called from Stdlib__Result.get_ok in file "result.ml" (inlined), line 21, characters 45-76 + Called from Dune__exe__Tunacc_test.compile_contract in file "packages/tunac/bin/tunacc_test.ml", line 12, characters 12-72 + Called from Dune__exe__Tunacc_test in file "packages/tunac/bin/tunacc_test.ml", line 23, characters 18-47 + [2] + diff --git a/packages/tunac/tests/hashlock.tz b/packages/tunac/tests/hashlock.tz new file mode 100644 index 0000000..ff60f77 --- /dev/null +++ b/packages/tunac/tests/hashlock.tz @@ -0,0 +1,88 @@ +{ parameter + (or (bytes %commit) + (pair %reveal (bytes %hashable) (lambda %message unit (list operation)))) ; + storage + (pair (pair (big_map %commits address (pair (timestamp %date) (bytes %salted_hash))) + (bytes %hashed)) + (bool %unused)) ; + code { UNPAIR ; + IF_LEFT + { PUSH int 86400 ; + NOW ; + ADD ; + PAIR ; + DUP 2 ; + CAR ; + CAR ; + SWAP ; + SOME ; + SENDER ; + PAIR 3 ; + DUP 2 ; + CDR ; + DIG 2 ; + CAR ; + CDR ; + DIG 2 ; + UNPAIR 3 ; + UPDATE ; + PAIR ; + PAIR ; + NIL operation ; + PAIR } + { DUP 2 ; + CDR ; + NOT ; + IF { DROP 2 ; PUSH string "This contract has already been used." ; FAILWITH } + { DUP 2 ; + CAR ; + CAR ; + SENDER ; + GET ; + IF_NONE + { PUSH string "You have not made a commitment to hash against yet." ; + FAILWITH } + {} ; + DUP ; + CAR ; + NOW ; + COMPARE ; + LT ; + IF { DROP 3 ; + PUSH string "It has not been 24 hours since your commit yet." ; + FAILWITH } + { SENDER ; + PACK ; + DUP 3 ; + CAR ; + CONCAT ; + SHA256 ; + SWAP ; + CDR ; + SWAP ; + COMPARE ; + NEQ ; + IF { DROP 2 ; + PUSH string "This reveal does not match your commitment." ; + FAILWITH } + { DUP ; + CAR ; + SHA256 ; + DUP 3 ; + CAR ; + CDR ; + COMPARE ; + EQ ; + IF { PUSH bool False ; + DIG 2 ; + CAR ; + PAIR ; + UNIT ; + DIG 2 ; + CDR ; + SWAP ; + EXEC ; + PAIR } + { DROP 2 ; + PUSH string "Your commitment did not match the storage hash." ; + FAILWITH } } } } } } } diff --git a/packages/tunac/tests/id.tz b/packages/tunac/tests/id.tz new file mode 100644 index 0000000..bb65a1c --- /dev/null +++ b/packages/tunac/tests/id.tz @@ -0,0 +1,189 @@ +{ parameter + (or (or (pair %buy (option %initial_controller address) (bytes %profile)) (unit %skip)) + (or (pair %update_details + (pair (int %id) (option %new_controller address)) + (option %new_profile bytes)) + (pair %update_owner (int %id) (address %new_owner)))) ; + storage + (pair (pair (big_map %identities + int + (pair (pair (address %controller) (address %owner)) (bytes %profile))) + (mutez %name_price)) + (int %next_id) + (mutez %skip_price)) ; + code { UNPAIR ; + IF_LEFT + { IF_LEFT + { DUP 2 ; + CAR ; + CDR ; + AMOUNT ; + COMPARE ; + EQ ; + IF {} { PUSH string "Incorrect amount paid." ; FAILWITH } ; + DUP 2 ; + CDR ; + CAR ; + DUP 2 ; + CAR ; + IF_NONE { SENDER } {} ; + DIG 2 ; + CDR ; + SENDER ; + DIG 2 ; + PAIR ; + PAIR ; + DUP 3 ; + CDR ; + CDR ; + PUSH int 1 ; + DUP 4 ; + ADD ; + PAIR ; + DUP 4 ; + CAR ; + CDR ; + DIG 4 ; + CAR ; + CAR ; + DIG 3 ; + SOME ; + DIG 4 ; + UPDATE } + { DROP ; + DUP ; + CDR ; + CDR ; + AMOUNT ; + COMPARE ; + EQ ; + IF {} { PUSH string "Incorrect amount paid." ; FAILWITH } ; + DUP ; + CDR ; + CDR ; + PUSH int 1 ; + DUP 3 ; + CDR ; + CAR ; + ADD ; + PAIR ; + DUP 2 ; + CAR ; + CDR ; + DIG 2 ; + CAR ; + CAR } ; + PAIR ; + PAIR ; + NIL operation ; + PAIR } + { IF_LEFT + { PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + NEQ ; + IF { DROP 2 ; PUSH string "Updating details doesn't cost anything." ; FAILWITH } + { DUP ; + CAR ; + CAR ; + DUP 3 ; + CAR ; + CAR ; + DUP ; + DUP 3 ; + GET ; + IF_NONE { PUSH string "This ID does not exist." ; FAILWITH } {} ; + DUP ; + CAR ; + CDR ; + SENDER ; + COMPARE ; + EQ ; + DUP 2 ; + CAR ; + CAR ; + SENDER ; + COMPARE ; + EQ ; + OR ; + IF {} + { PUSH string "You are not the owner or controller of this ID." ; FAILWITH } ; + DUP 5 ; + CDR ; + CDR ; + DUP 6 ; + CDR ; + CAR ; + PAIR ; + DIG 5 ; + CAR ; + CDR ; + DIG 3 ; + DUP 6 ; + CDR ; + IF_NONE { DUP 4 ; CDR } {} ; + DUP 5 ; + CAR ; + CDR ; + DIG 7 ; + CAR ; + CDR ; + IF_NONE { DIG 5 ; CAR ; CAR } { DIG 6 ; DROP } ; + PAIR ; + PAIR ; + SOME ; + DIG 4 ; + UPDATE ; + PAIR ; + PAIR ; + NIL operation ; + PAIR } } + { PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + NEQ ; + IF { DROP 2 ; PUSH string "Updating owner doesn't cost anything." ; FAILWITH } + { DUP ; + CAR ; + DUP 3 ; + CAR ; + CAR ; + DUP ; + DUP 3 ; + GET ; + IF_NONE { PUSH string "This ID does not exist." ; FAILWITH } {} ; + DUP ; + CAR ; + CDR ; + SENDER ; + COMPARE ; + EQ ; + IF {} { PUSH string "You are not the owner of this ID." ; FAILWITH } ; + DUP 5 ; + CDR ; + CDR ; + DUP 6 ; + CDR ; + CAR ; + PAIR ; + DIG 5 ; + CAR ; + CDR ; + DIG 3 ; + DUP 4 ; + CDR ; + DIG 6 ; + CDR ; + DIG 5 ; + CAR ; + CAR ; + PAIR ; + PAIR ; + SOME ; + DIG 4 ; + UPDATE ; + PAIR ; + PAIR ; + NIL operation ; + PAIR } } } } } + diff --git a/packages/tunac/tests/id_ticket.t b/packages/tunac/tests/id_ticket.t new file mode 100644 index 0000000..9759546 --- /dev/null +++ b/packages/tunac/tests/id_ticket.t @@ -0,0 +1,20 @@ +id_ticket + $ ../bin/tunacc_test.exe contract id_ticket.tz + { + "module_": "\n(module\n (import \"env\" \"dup_host\" (func $dup_host (param i64 ) (result)))\n(import \"env\" \"pair\" (func $pair (param i64 i64) (result i64)))\n(import \"env\" \"unpair\" (func $unpair (param i64)))\n(import \"env\" \"z_add\" (func $z_add (param i64 i64) (result i64)))\n(import \"env\" \"z_sub\" (func $z_sub (param i64 i64) (result i64)))\n(import \"env\" \"z_mul\" (func $z_mul (param i64 i64) (result i64)))\n(import \"env\" \"neg\" (func $neg (param i64) (result i64)))\n(import \"env\" \"lsl\" (func $lsl (param i64 i64) (result i64)))\n(import \"env\" \"concat\" (func $concat (param i64 i64) (result i64)))\n(import \"env\" \"lsr\" (func $lsr (param i64 i64) (result i64)))\n(import \"env\" \"compare\" (func $compare (param i64 i64) (result i64)))\n(import \"env\" \"car\" (func $car (param i64) (result i64)))\n(import \"env\" \"cdr\" (func $cdr (param i64) (result i64)))\n(import \"env\" \"some\" (func $some (param i64) (result i64)))\n(import \"env\" \"nil\" (func $nil (result i64)))\n(import \"env\" \"true\" (func $true (result i64)))\n(import \"env\" \"false\" (func $false (result i64)))\n(import \"env\" \"none\" (func $none (result i64)))\n(import \"env\" \"unit\" (func $unit (result i64)))\n(import \"env\" \"zero\" (func $zero (result i64)))\n(import \"env\" \"empty_map\" (func $empty_map (result i64)))\n(import \"env\" \"empty_set\" (func $empty_set (result i64)))\n(import \"env\" \"empty_big_map\" (func $empty_big_map (result i64)))\n(import \"env\" \"sender\" (func $sender (result i64)))\n(import \"env\" \"source\" (func $source (result i64)))\n(import \"env\" \"map_get\" (func $map_get (param i64 i64) (result i64)))\n(import \"env\" \"mem\" (func $mem (param i64 i64) (result i64)))\n(import \"env\" \"update\" (func $update (param i64 i64 i64) (result i64)))\n(import \"env\" \"iter\" (func $iter (param i64 i32) (result )))\n(import \"env\" \"map\" (func $map (param i64 i32) (result i64)))\n(import \"env\" \"if_left\" (func $if_left (param i64) (result i32)))\n(import \"env\" \"if_none\" (func $if_none (param i64) (result i32)))\n(import \"env\" \"if_cons\" (func $if_cons (param i64) (result i32)))\n(import \"env\" \"isnat\" (func $isnat (param i64) (result i64)))\n(import \"env\" \"not\" (func $not (param i64) (result i64)))\n(import \"env\" \"or\" (func $or (param i64 i64) (result i64)))\n(import \"env\" \"and\" (func $and (param i64 i64) (result i64)))\n(import \"env\" \"xor\" (func $xor (param i64 i64) (result i64)))\n(import \"env\" \"deref_bool\" (func $deref_bool (param i64) (result i32)))\n(import \"env\" \"neq\" (func $neq (param i64) (result i64)))\n(import \"env\" \"failwith\" (func $failwith (param i64)))\n(import \"env\" \"get_n\" (func $get_n (param i32 i64) (result i64)))\n(import \"env\" \"exec\" (func $exec (param i64 i64) (result i64)))\n(import \"env\" \"apply\" (func $apply (param i64 i64) (result i64)))\n(import \"env\" \"const\" (func $const (param i32) (result i64)))\n(import \"env\" \"abs\" (func $abs (param i64) (result i64)))\n(import \"env\" \"eq\" (func $eq (param i64) (result i64)))\n(import \"env\" \"gt\" (func $gt (param i64) (result i64)))\n(import \"env\" \"lt\" (func $lt (param i64) (result i64)))\n(import \"env\" \"closure\" (func $closure (param i32) (result i64)))\n(import \"env\" \"left\" (func $left (param i64) (result i64)))\n(import \"env\" \"right\" (func $right (param i64) (result i64)))\n(import \"env\" \"cons\" (func $cons (param i64 i64) (result i64)))\n(import \"env\" \"transfer_tokens\" (func $transfer_tokens (param i64 i64 i64) (result i64)))\n(import \"env\" \"address\" (func $address (param i64) (result i64)))\n(import \"env\" \"contract\" (func $contract (param i64) (result i64)))\n(import \"env\" \"self\" (func $self (result i64)))\n(import \"env\" \"self_address\" (func $self_address (result i64)))\n(import \"env\" \"get_and_update\" (func $get_and_update (param i64 i64 i64)))\n(import \"env\" \"read_ticket\" (func $read_ticket (param i64)))\n(import \"env\" \"ticket\" (func $ticket (param i64 i64) (result i64)))\n(import \"env\" \"join_tickets\" (func $join_tickets (param i64) (result i64)))\n(import \"env\" \"split_ticket\" (func $split_ticket (param i64 i64) (result i64)))\n(import \"env\" \"amount\" (func $amount (result i64)))\n(import \"env\" \"balance\" (func $balance (result i64)))\n(import \"env\" \"ediv\" (func $ediv (param i64 i64) (result i64)))\n(import \"env\" \"ge\" (func $ge (param i64) (result i64)))\n(import \"env\" \"le\" (func $le (param i64) (result i64)))\n(import \"env\" \"size\" (func $size (param i64) (result i64)))\n(import \"env\" \"int\" (func $int (param i64) (result i64)))\n(import \"env\" \"implicit_account\" (func $implicit_account (param i64) (result i64)))\n(import \"env\" \"blake2b\" (func $blake2b (param i64) (result i64)))\n(import \"env\" \"pack\" (func $pack (param i64) (result i64)))\n(import \"env\" \"unpack\" (func $unpack (param i64) (result i64)))\n(import \"env\" \"keccak\" (func $keccak (param i64) (result i64)))\n(import \"env\" \"sha256\" (func $sha256 (param i64) (result i64)))\n(import \"env\" \"sha3\" (func $sha3 (param i64) (result i64)))\n(import \"env\" \"sha512\" (func $sha512 (param i64) (result i64)))\n\n (global $mode i32 (i32.const 0))\n\n (memory 4)\n (global $sp (mut i32) (i32.const 4000)) ;; stack pointer\n (global $sh_sp (mut i32) (i32.const 1000)) ;;shadow_stack stack pointer\n\n (global $__stack_base i32 (i32.const 32768))\n\n (type $callback_t (func (param i64) (result i64)))\n (func $call_callback (param $arg1 i64) (param $idx i32) (result i64)\n (call_indirect (type $callback_t) (local.get $arg1) (local.get $idx)))\n\n (type $callback_t_unit (func (param i64) (result)))\n (func $call_callback_unit (param $arg1 i64) (param $idx i32) (result )\n (call_indirect (type $callback_t_unit)\n (local.get $arg1)\n (local.get $idx)))\n\n (func $dip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.set $stop (i32.const 0))\n (local.set $sp' (global.get $sp))\n (local.tee $sh_sp' (i32.sub (global.get $sh_sp) (local.get $n)))\n global.set $sh_sp\n (loop $l\n (i32.mul (i32.const 8) (i32.add (global.get $__stack_base) (i32.add (local.get $sh_sp') (local.get $stop))))\n (i64.load (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop))))\n i64.store\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n\n (global.set $sp\n (i32.add\n (local.get $sp') (local.get $n))))\n\n (func $undip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.tee $sp' (i32.sub (global.get $sp) (local.get $n)))\n global.set $sp\n (local.set $sh_sp' (global.get $sh_sp))\n (local.set $stop (i32.const 0))\n (loop $l\n (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop)))\n (i64.load\n (i32.add\n (global.get $__stack_base)\n (i32.mul (i32.const 8) (i32.add (local.get $sh_sp') (local.get $stop)))))\n (i64.store)\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n (global.set $sh_sp (i32.add (local.get $sh_sp') (local.get $n))))\n\n (func $dup (param $n i32) (result)\n (i64.load (i32.mul (i32.const 8) (i32.add (global.get $sp) (local.get $n))))\n (call $dup_host))\n\n (func $swap (param) (result)\n (local $v1 i64)\n (local $v2 i64)\n (local.set $v1 (call $pop))\n (local.set $v2 (call $pop))\n (call $push (local.get $v1))\n (call $push (local.get $v2)))\n\n (func $dug (param $n i32) (result)\n (local $idx i32)\n (local $loop_idx i32)\n (local $sp' i32)\n (local $top i64)\n (local.set $sp' (i32.add (global.get $sp) (local.get $n)))\n (local.tee $idx (global.get $sp))\n (local.tee $loop_idx)\n (i32.mul (i32.const 8))\n i64.load\n local.set $top\n (loop $loop\n (i32.mul (i32.const 8) (local.get $idx))\n (i32.add (local.get $loop_idx) (i32.const 1))\n local.tee $loop_idx\n (i32.mul (i32.const 8))\n i64.load\n i64.store\n (local.set $idx (i32.add (local.get $idx) (i32.const 1)))\n (local.get $idx)\n (local.get $sp')\n i32.lt_u\n br_if $loop)\n\n (i64.store (i32.mul (i32.const 8) (local.get $sp')) (local.get $top)))\n\n (func $dig (param $n i32) (result)\n (local $idx i32) (local $t i32) (local $digged i64)\n\n (local.set $digged\n (i64.load\n (i32.mul (i32.const 8)\n (local.tee $idx (i32.add (global.get $sp) (local.get $n))))))\n\n (loop $loop\n (local.set $t (i32.mul (i32.const 8) (local.get $idx)))\n\n (i64.store (local.get $t)\n (i64.load\n (i32.mul\n (i32.const 8)\n (local.tee $idx (i32.sub (local.get $idx) (i32.const 1))))))\n\n (br_if $loop\n (i32.lt_u (global.get $sp) (local.get $idx))))\n\n (i64.store (i32.mul (i32.const 8) (local.get $idx)) (local.get $digged)))\n\n (func $pop (result i64)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (global.get $sp)))\n i64.load\n (global.set $sp (i32.add (local.get $spp) (i32.const 1)))) ;;set stackptr\n\n (func $push (param $value i64) (result)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (i32.sub (global.get $sp) (i32.const 1)) ))\n (i64.store (local.get $value))\n (global.set $sp (local.get $spp))) ;;set stackptr\n\n (func $drop (param $n i32) (result)\n (global.set $sp (i32.add (global.get $sp) (local.get $n)))) ;;set stackptr\n\n (table $closures funcref (elem ))\n\n\n (func $main (param $v1 i64) (result i64)\n (local $1 i64)\n (call $push (local.get $v1))\n (call $unpair (call $pop)) ;; implicit return\n(call $if_left (call $pop)) (if (then (call $if_left (call $pop)) (if (then (call $dup (i32.const 0))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $read_ticket (call $pop)) ;; implicit return\n(call $swap)\n(call $drop (i32.const 1))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dup (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $swap)\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"Incorrect amount paid.\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dup (i32.const 1))\n(call $push (call $cdr (call $pop)))\n(call $push (call $car (call $pop)))\n(call $dup (i32.const 1))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $if_none (call $pop)) (if (then (call $push (call $sender))) (else ))\n(call $dig (i32.const 2))\n(call $push (call $cdr (call $pop)))\n(call $push (call $sender))\n(call $dig (i32.const 2))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $dup (i32.const 2))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $push (call $const (i32.const 1))) (; 1 ;)\n(call $dup (i32.const 3))\n(call $push (call $z_add (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $dup (i32.const 3))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 4))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $dig (i32.const 3))\n(call $push (call $some (call $pop)))\n(call $dig (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))) (else (call $read_ticket (call $pop)) ;; implicit return\n(call $swap)\n(call $drop (i32.const 1))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dup (i32.const 1))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $swap)\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"Incorrect amount paid.\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dup (i32.const 0))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $push (call $const (i32.const 1))) (; 1 ;)\n(call $dup (i32.const 2))\n(call $push (call $cdr (call $pop)))\n(call $push (call $car (call $pop)))\n(call $push (call $z_add (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $dup (i32.const 1))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))) (else (call $if_left (call $pop)) (if (then (call $push (call $zero)) (; 0 ;)\n(call $push (call $amount))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $neq (call $pop)))\n(call $deref_bool (call $pop)) (if (then (call $drop (i32.const 2))\n(call $push (call $const (i32.const 2))) (; \"Updating details doesn't cost anything.\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dup (i32.const 0))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $dup (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $dup (i32.const 0))\n(call $dup (i32.const 2))\n(call $push (call $map_get (call $pop) (call $pop)))\n(call $if_none (call $pop)) (if (then (call $push (call $const (i32.const 3))) (; \"This ID does not exist.\" ;)\n(call $failwith (call $pop)) unreachable) (else ))\n(call $dup (i32.const 0))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $dup (i32.const 1))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $push (call $or (call $pop) (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 4))) (; \"You are not the owner or controller of this ID.\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dup (i32.const 4))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dup (i32.const 5))\n(call $push (call $cdr (call $pop)))\n(call $push (call $car (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $dig (i32.const 5))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 3))\n(call $dup (i32.const 5))\n(call $push (call $cdr (call $pop)))\n(call $if_none (call $pop)) (if (then (call $dup (i32.const 3))\n(call $push (call $cdr (call $pop)))) (else ))\n(call $dup (i32.const 4))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 7))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $if_none (call $pop)) (if (then (call $dig (i32.const 5))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))) (else (call $dig (i32.const 6))\n(call $drop (i32.const 1))))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $some (call $pop)))\n(call $dig (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $push (call $zero)) (; 0 ;)\n(call $push (call $amount))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $neq (call $pop)))\n(call $deref_bool (call $pop)) (if (then (call $drop (i32.const 2))\n(call $push (call $const (i32.const 5))) (; \"Updating owner doesn't cost anything.\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dup (i32.const 0))\n(call $push (call $car (call $pop)))\n(call $dup (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $dup (i32.const 0))\n(call $dup (i32.const 2))\n(call $push (call $map_get (call $pop) (call $pop)))\n(call $if_none (call $pop)) (if (then (call $push (call $const (i32.const 3))) (; \"This ID does not exist.\" ;)\n(call $failwith (call $pop)) unreachable) (else ))\n(call $dup (i32.const 0))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 6))) (; \"You are not the owner of this ID.\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dup (i32.const 4))\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dup (i32.const 5))\n(call $push (call $cdr (call $pop)))\n(call $push (call $car (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $dig (i32.const 5))\n(call $push (call $car (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 3))\n(call $dup (i32.const 3))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 6))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 5))\n(call $push (call $car (call $pop)))\n(call $push (call $car (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $some (call $pop)))\n(call $dig (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))))))))\n (call $pop))\n\n (export \"push\" (func $push))\n (export \"pop\" (func $push))\n (export \"main\" (func $main))\n (export \"closures\" (table $closures))\n (export \"call_callback\" (func $call_callback))\n (export \"call_callback_unit\" (func $call_callback_unit))\n )\n", + "constants": [ + [ 0, [ "String", "Incorrect amount paid." ] ], + [ 1, [ "Int", "1" ] ], + [ 2, [ "String", "Updating details doesn't cost anything." ] ], + [ 3, [ "String", "This ID does not exist." ] ], + [ 4, [ "String", "You are not the owner or controller of this ID." ] ], + [ 5, [ "String", "Updating owner doesn't cost anything." ] ], + [ 6, [ "String", "You are not the owner of this ID." ] ] + ], + "entrypoints": { + "%buy": [ "Left", "Left" ], + "%skip": [ "Left", "Right" ], + "%update_details": [ "Right", "Left" ], + "%update_owner": [ "Right", "Right" ] + } + } diff --git a/packages/tunac/tests/id_ticket.tz b/packages/tunac/tests/id_ticket.tz new file mode 100644 index 0000000..959749c --- /dev/null +++ b/packages/tunac/tests/id_ticket.tz @@ -0,0 +1,205 @@ +{ parameter + (or (or (pair %buy + (pair (option %initial_controller address) (ticket %payment unit)) + (bytes %profile)) + (ticket %skip unit)) + (or (pair %update_details + (pair (int %id) (option %new_controller address)) + (option %new_profile bytes)) + (pair %update_owner (int %id) (address %new_owner)))) ; + storage + (pair (pair (big_map %identities + int + (pair (pair (address %controller) (address %owner)) (bytes %profile))) + (nat %name_price)) + (int %next_id) + (nat %skip_price)) ; + code { UNPAIR ; + IF_LEFT + { IF_LEFT + { DUP ; + CAR ; + CDR ; + READ_TICKET ; + SWAP ; + DROP ; + CDR ; + CDR ; + DUP 3 ; + CAR ; + CDR ; + SWAP ; + COMPARE ; + EQ ; + IF {} { PUSH string "Incorrect amount paid." ; FAILWITH } ; + DUP 2 ; + CDR ; + CAR ; + DUP 2 ; + CAR ; + CAR ; + IF_NONE { SENDER } {} ; + DIG 2 ; + CDR ; + SENDER ; + DIG 2 ; + PAIR ; + PAIR ; + DUP 3 ; + CDR ; + CDR ; + PUSH int 1 ; + DUP 4 ; + ADD ; + PAIR ; + DUP 4 ; + CAR ; + CDR ; + DIG 4 ; + CAR ; + CAR ; + DIG 3 ; + SOME ; + DIG 4 ; + UPDATE } + { READ_TICKET ; + SWAP ; + DROP ; + CDR ; + CDR ; + DUP 2 ; + CDR ; + CDR ; + SWAP ; + COMPARE ; + EQ ; + IF {} { PUSH string "Incorrect amount paid." ; FAILWITH } ; + DUP ; + CDR ; + CDR ; + PUSH int 1 ; + DUP 3 ; + CDR ; + CAR ; + ADD ; + PAIR ; + DUP 2 ; + CAR ; + CDR ; + DIG 2 ; + CAR ; + CAR } ; + PAIR ; + PAIR ; + NIL operation ; + PAIR } + { IF_LEFT + { PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + NEQ ; + IF { DROP 2 ; PUSH string "Updating details doesn't cost anything." ; FAILWITH } + { DUP ; + CAR ; + CAR ; + DUP 3 ; + CAR ; + CAR ; + DUP ; + DUP 3 ; + GET ; + IF_NONE { PUSH string "This ID does not exist." ; FAILWITH } {} ; + DUP ; + CAR ; + CDR ; + SENDER ; + COMPARE ; + EQ ; + DUP 2 ; + CAR ; + CAR ; + SENDER ; + COMPARE ; + EQ ; + OR ; + IF {} + { PUSH string "You are not the owner or controller of this ID." ; FAILWITH } ; + DUP 5 ; + CDR ; + CDR ; + DUP 6 ; + CDR ; + CAR ; + PAIR ; + DIG 5 ; + CAR ; + CDR ; + DIG 3 ; + DUP 6 ; + CDR ; + IF_NONE { DUP 4 ; CDR } {} ; + DUP 5 ; + CAR ; + CDR ; + DIG 7 ; + CAR ; + CDR ; + IF_NONE { DIG 5 ; CAR ; CAR } { DIG 6 ; DROP } ; + PAIR ; + PAIR ; + SOME ; + DIG 4 ; + UPDATE ; + PAIR ; + PAIR ; + NIL operation ; + PAIR } } + { PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + NEQ ; + IF { DROP 2 ; PUSH string "Updating owner doesn't cost anything." ; FAILWITH } + { DUP ; + CAR ; + DUP 3 ; + CAR ; + CAR ; + DUP ; + DUP 3 ; + GET ; + IF_NONE { PUSH string "This ID does not exist." ; FAILWITH } {} ; + DUP ; + CAR ; + CDR ; + SENDER ; + COMPARE ; + EQ ; + IF {} { PUSH string "You are not the owner of this ID." ; FAILWITH } ; + DUP 5 ; + CDR ; + CDR ; + DUP 6 ; + CDR ; + CAR ; + PAIR ; + DIG 5 ; + CAR ; + CDR ; + DIG 3 ; + DUP 4 ; + CDR ; + DIG 6 ; + CDR ; + DIG 5 ; + CAR ; + CAR ; + PAIR ; + PAIR ; + SOME ; + DIG 4 ; + UPDATE ; + PAIR ; + PAIR ; + NIL operation ; + PAIR } } } } } + diff --git a/packages/tunac/tests/nft_auction.t b/packages/tunac/tests/nft_auction.t index c757943..b98f1cd 100644 --- a/packages/tunac/tests/nft_auction.t +++ b/packages/tunac/tests/nft_auction.t @@ -1,7 +1,7 @@ NFT Auction $ ../bin/tunacc_test.exe contract nft_auction.tz { - "module_": "\n(module\n (import \"env\" \"dup_host\" (func $dup_host (param i64 ) (result)))\n(import \"env\" \"pair\" (func $pair (param i64 i64) (result i64)))\n(import \"env\" \"unpair\" (func $unpair (param i64)))\n(import \"env\" \"z_add\" (func $z_add (param i64 i64) (result i64)))\n(import \"env\" \"z_sub\" (func $z_sub (param i64 i64) (result i64)))\n(import \"env\" \"z_mul\" (func $z_mul (param i64 i64) (result i64)))\n(import \"env\" \"neg\" (func $neg (param i64) (result i64)))\n(import \"env\" \"lsl\" (func $lsl (param i64 i64) (result i64)))\n(import \"env\" \"concat\" (func $concat (param i64 i64) (result i64)))\n(import \"env\" \"lsr\" (func $lsr (param i64 i64) (result i64)))\n(import \"env\" \"compare\" (func $compare (param i64 i64) (result i64)))\n(import \"env\" \"car\" (func $car (param i64) (result i64)))\n(import \"env\" \"cdr\" (func $cdr (param i64) (result i64)))\n(import \"env\" \"some\" (func $some (param i64) (result i64)))\n(import \"env\" \"nil\" (func $nil (result i64)))\n(import \"env\" \"true\" (func $true (result i64)))\n(import \"env\" \"false\" (func $false (result i64)))\n(import \"env\" \"none\" (func $none (result i64)))\n(import \"env\" \"unit\" (func $unit (result i64)))\n(import \"env\" \"zero\" (func $zero (result i64)))\n(import \"env\" \"empty_map\" (func $empty_map (result i64)))\n(import \"env\" \"empty_set\" (func $empty_set (result i64)))\n(import \"env\" \"empty_big_map\" (func $empty_big_map (result i64)))\n(import \"env\" \"sender\" (func $sender (result i64)))\n(import \"env\" \"source\" (func $source (result i64)))\n(import \"env\" \"map_get\" (func $map_get (param i64 i64) (result i64)))\n(import \"env\" \"mem\" (func $mem (param i64 i64) (result i64)))\n(import \"env\" \"update\" (func $update (param i64 i64 i64) (result i64)))\n(import \"env\" \"iter\" (func $iter (param i64 i32) (result )))\n(import \"env\" \"map\" (func $map (param i64 i32) (result i64)))\n(import \"env\" \"if_left\" (func $if_left (param i64) (result i32)))\n(import \"env\" \"if_none\" (func $if_none (param i64) (result i32)))\n(import \"env\" \"if_cons\" (func $if_cons (param i64) (result i32)))\n(import \"env\" \"isnat\" (func $isnat (param i64) (result i64)))\n(import \"env\" \"not\" (func $not (param i64) (result i64)))\n(import \"env\" \"or\" (func $or (param i64 i64) (result i64)))\n(import \"env\" \"and\" (func $and (param i64 i64) (result i64)))\n(import \"env\" \"xor\" (func $xor (param i64 i64) (result i64)))\n(import \"env\" \"deref_bool\" (func $deref_bool (param i64) (result i32)))\n(import \"env\" \"neq\" (func $neq (param i64) (result i64)))\n(import \"env\" \"failwith\" (func $failwith (param i64)))\n(import \"env\" \"get_n\" (func $get_n (param i32 i64) (result i64)))\n(import \"env\" \"exec\" (func $exec (param i64 i64) (result i64)))\n(import \"env\" \"apply\" (func $apply (param i64 i64) (result i64)))\n(import \"env\" \"const\" (func $const (param i32) (result i64)))\n(import \"env\" \"abs\" (func $abs (param i64) (result i64)))\n(import \"env\" \"eq\" (func $eq (param i64) (result i64)))\n(import \"env\" \"gt\" (func $gt (param i64) (result i64)))\n(import \"env\" \"lt\" (func $lt (param i64) (result i64)))\n(import \"env\" \"closure\" (func $closure (param i32) (result i64)))\n(import \"env\" \"left\" (func $left (param i64) (result i64)))\n(import \"env\" \"right\" (func $right (param i64) (result i64)))\n(import \"env\" \"cons\" (func $cons (param i64 i64) (result i64)))\n(import \"env\" \"transfer_tokens\" (func $transfer_tokens (param i64 i64 i64) (result i64)))\n(import \"env\" \"address\" (func $address (param i64) (result i64)))\n(import \"env\" \"contract\" (func $contract (param i64) (result i64)))\n(import \"env\" \"self\" (func $self (result i64)))\n(import \"env\" \"self_address\" (func $self_address (result i64)))\n(import \"env\" \"get_and_update\" (func $get_and_update (param i64 i64 i64)))\n(import \"env\" \"read_ticket\" (func $read_ticket (param i64)))\n(import \"env\" \"ticket\" (func $ticket (param i64 i64) (result i64)))\n(import \"env\" \"join_tickets\" (func $join_tickets (param i64) (result i64)))\n(import \"env\" \"split_ticket\" (func $split_ticket (param i64 i64) (result i64)))\n(import \"env\" \"amount\" (func $amount (result i64)))\n(import \"env\" \"balance\" (func $balance (result i64)))\n(import \"env\" \"ediv\" (func $ediv (param i64 i64) (result i64)))\n(import \"env\" \"ge\" (func $ge (param i64) (result i64)))\n(import \"env\" \"le\" (func $le (param i64) (result i64)))\n(import \"env\" \"size\" (func $size (param i64) (result i64)))\n(import \"env\" \"int\" (func $int (param i64) (result i64)))\n(import \"env\" \"implicit_account\" (func $implicit_account (param i64) (result i64)))\n(import \"env\" \"blake2b\" (func $blake2b (param i64) (result i64)))\n(import \"env\" \"pack\" (func $pack (param i64) (result i64)))\n(import \"env\" \"unpack\" (func $unpack (param i64) (result i64)))\n(import \"env\" \"keccak\" (func $keccak (param i64) (result i64)))\n(import \"env\" \"sha256\" (func $sha256 (param i64) (result i64)))\n(import \"env\" \"sha3\" (func $sha3 (param i64) (result i64)))\n(import \"env\" \"sha512\" (func $sha512 (param i64) (result i64)))\n\n (global $mode i32 (i32.const 0))\n\n (memory 4)\n (global $sp (mut i32) (i32.const 4000)) ;; stack pointer\n (global $sh_sp (mut i32) (i32.const 1000)) ;;shadow_stack stack pointer\n\n (global $__stack_base i32 (i32.const 32768))\n\n (type $callback_t (func (param i64) (result i64)))\n (func $call_callback (param $arg1 i64) (param $idx i32) (result i64)\n (call_indirect (type $callback_t) (local.get $arg1) (local.get $idx)))\n\n (type $callback_t_unit (func (param i64) (result)))\n (func $call_callback_unit (param $arg1 i64) (param $idx i32) (result )\n (call_indirect (type $callback_t_unit)\n (local.get $arg1)\n (local.get $idx)))\n\n (func $dip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.set $stop (i32.const 0))\n (local.set $sp' (global.get $sp))\n (local.tee $sh_sp' (i32.sub (global.get $sh_sp) (local.get $n)))\n global.set $sh_sp\n (loop $l\n (i32.mul (i32.const 8) (i32.add (global.get $__stack_base) (i32.add (local.get $sh_sp') (local.get $stop))))\n (i64.load (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop))))\n i64.store\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n\n (global.set $sp\n (i32.add\n (local.get $sp') (local.get $n))))\n\n (func $undip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.tee $sp' (i32.sub (global.get $sp) (local.get $n)))\n global.set $sp\n (local.set $sh_sp' (global.get $sh_sp))\n (local.set $stop (i32.const 0))\n (loop $l\n (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop)))\n (i64.load\n (i32.add\n (global.get $__stack_base)\n (i32.mul (i32.const 8) (i32.add (local.get $sh_sp') (local.get $stop)))))\n (i64.store)\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n (global.set $sh_sp (i32.add (local.get $sh_sp') (local.get $n))))\n\n (func $dup (param $n i32) (result)\n (i64.load (i32.mul (i32.const 8) (i32.add (global.get $sp) (local.get $n))))\n (call $dup_host))\n\n (func $swap (param) (result)\n (local $v1 i64)\n (local $v2 i64)\n (local.set $v1 (call $pop))\n (local.set $v2 (call $pop))\n (call $push (local.get $v1))\n (call $push (local.get $v2)))\n\n (func $dug (param $n i32) (result)\n (local $idx i32)\n (local $loop_idx i32)\n (local $sp' i32)\n (local $top i64)\n (local.set $sp' (i32.add (global.get $sp) (local.get $n)))\n (local.tee $idx (global.get $sp))\n (local.tee $loop_idx)\n (i32.mul (i32.const 8))\n i64.load\n local.set $top\n (loop $loop\n (i32.mul (i32.const 8) (local.get $idx))\n (i32.add (local.get $loop_idx) (i32.const 1))\n local.tee $loop_idx\n (i32.mul (i32.const 8))\n i64.load\n i64.store\n (local.set $idx (i32.add (local.get $idx) (i32.const 1)))\n (local.get $idx)\n (local.get $sp')\n i32.lt_u\n br_if $loop)\n\n (i64.store (i32.mul (i32.const 8) (local.get $sp')) (local.get $top)))\n\n (func $dig (param $n i32) (result)\n (local $idx i32) (local $t i32) (local $digged i64)\n\n (local.set $digged\n (i64.load\n (i32.mul (i32.const 8)\n (local.tee $idx (i32.add (global.get $sp) (local.get $n))))))\n\n (loop $loop\n (local.set $t (i32.mul (i32.const 8) (local.get $idx)))\n\n (i64.store (local.get $t)\n (i64.load\n (i32.mul\n (i32.const 8)\n (local.tee $idx (i32.sub (local.get $idx) (i32.const 1))))))\n\n (br_if $loop\n (i32.lt_u (global.get $sp) (local.get $idx))))\n\n (i64.store (i32.mul (i32.const 8) (local.get $idx)) (local.get $digged)))\n\n (func $pop (result i64)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (global.get $sp)))\n i64.load\n (global.set $sp (i32.add (local.get $spp) (i32.const 1)))) ;;set stackptr\n\n (func $push (param $value i64) (result)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (i32.sub (global.get $sp) (i32.const 1)) ))\n (i64.store (local.get $value))\n (global.set $sp (local.get $spp))) ;;set stackptr\n\n (func $drop (param $n i32) (result)\n (global.set $sp (i32.add (global.get $sp) (local.get $n)))) ;;set stackptr\n\n (table $closures funcref (elem ))\n\n\n (func $main (param $v1 i64) (result i64)\n (local $1 i64)\n (call $push (local.get $v1))\n (call $push (call $zero)) (; 0 ;)\n(call $push (call $amount))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $unpair (call $pop)) ;; implicit return\n(call $swap)\n(call $unpair (call $pop)) ;; implicit return\n(call $dig (i32.const 4))\n(call $if_left (call $pop)) (if (then (call $if_left (call $pop)) (if (then (call $if_left (call $pop)) (if (then (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 2))\n(call $push (call $none))\n(call $dup (i32.const 2))\n(call $push (call $get_n (i32.const 10) (call $pop)))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $if_none (call $pop)) (if (then (call $drop (i32.const 5))\n(call $push (call $const (i32.const 1))) (; \"no tickets\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dup (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $zero)) (; 0 ;)\n(call $dig (i32.const 2))\n(call $dup (i32.const 4))\n(call $push (call $get_n (i32.const 9) (call $pop)))\n(call $dup (i32.const 5))\n(call $push (call $get_n (i32.const 7) (call $pop)))\n(call $dup (i32.const 6))\n(call $push (call $get_n (i32.const 5) (call $pop)))\n(call $dig (i32.const 7))\n(call $push (call $get_n (i32.const 3) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $transfer_tokens (call $pop) (call $pop) (call $pop)))\n(call $dig (i32.const 4))\n(call $dig (i32.const 4))\n(call $dig (i32.const 3))\n(call $dig (i32.const 4))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $dig (i32.const 2))\n(call $push (call $cons (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 4))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 5))\n(call $push (call $z_add (call $pop) (call $pop)))\n(call $dig (i32.const 4))\n(call $push (call $none))\n(call $dig (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $dig (i32.const 3))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $if_left (call $pop)) (if (then (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dup (i32.const 4))\n(call $push (call $ticket (call $pop) (call $pop)))\n(call $dig (i32.const 3))\n(call $swap)\n(call $push (call $some (call $pop)))\n(call $dup (i32.const 4))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $drop (i32.const 1))\n(call $dig (i32.const 4))\n(call $dig (i32.const 2))\n(call $dup (i32.const 4))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $some (call $pop)))\n(call $dup (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 4))\n(call $push (call $z_add (call $pop) (call $pop)))) (else (call $read_ticket (call $pop)) ;; implicit return\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 3))\n(call $dig (i32.const 2))\n(call $push (call $some (call $pop)))\n(call $dup (i32.const 4))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $drop (i32.const 1))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 2))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 3))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 4))\n(call $push (call $z_add (call $pop) (call $pop)))))\n(call $dig (i32.const 2))\n(call $dig (i32.const 3))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 2))\n(call $push (call $none))\n(call $dup (i32.const 2))\n(call $push (call $cdr (call $pop)))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $if_none (call $pop)) (if (then (call $drop (i32.const 5))\n(call $push (call $const (i32.const 1))) (; \"no tickets\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dig (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $zero)) (; 0 ;)\n(call $dig (i32.const 2))\n(call $push (call $transfer_tokens (call $pop) (call $pop) (call $pop)))\n(call $dig (i32.const 4))\n(call $dig (i32.const 4))\n(call $dig (i32.const 3))\n(call $dig (i32.const 4))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $dig (i32.const 2))\n(call $push (call $cons (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))))))\n (call $pop))\n\n (export \"push\" (func $push))\n (export \"pop\" (func $push))\n (export \"main\" (func $main))\n (export \"closures\" (table $closures))\n (export \"call_callback\" (func $call_callback))\n (export \"call_callback_unit\" (func $call_callback_unit))\n )\n", + "module_": "\n(module\n (import \"env\" \"dup_host\" (func $dup_host (param i64 ) (result)))\n(import \"env\" \"pair\" (func $pair (param i64 i64) (result i64)))\n(import \"env\" \"unpair\" (func $unpair (param i64)))\n(import \"env\" \"z_add\" (func $z_add (param i64 i64) (result i64)))\n(import \"env\" \"z_sub\" (func $z_sub (param i64 i64) (result i64)))\n(import \"env\" \"z_mul\" (func $z_mul (param i64 i64) (result i64)))\n(import \"env\" \"neg\" (func $neg (param i64) (result i64)))\n(import \"env\" \"lsl\" (func $lsl (param i64 i64) (result i64)))\n(import \"env\" \"concat\" (func $concat (param i64 i64) (result i64)))\n(import \"env\" \"lsr\" (func $lsr (param i64 i64) (result i64)))\n(import \"env\" \"compare\" (func $compare (param i64 i64) (result i64)))\n(import \"env\" \"car\" (func $car (param i64) (result i64)))\n(import \"env\" \"cdr\" (func $cdr (param i64) (result i64)))\n(import \"env\" \"some\" (func $some (param i64) (result i64)))\n(import \"env\" \"nil\" (func $nil (result i64)))\n(import \"env\" \"true\" (func $true (result i64)))\n(import \"env\" \"false\" (func $false (result i64)))\n(import \"env\" \"none\" (func $none (result i64)))\n(import \"env\" \"unit\" (func $unit (result i64)))\n(import \"env\" \"zero\" (func $zero (result i64)))\n(import \"env\" \"empty_map\" (func $empty_map (result i64)))\n(import \"env\" \"empty_set\" (func $empty_set (result i64)))\n(import \"env\" \"empty_big_map\" (func $empty_big_map (result i64)))\n(import \"env\" \"sender\" (func $sender (result i64)))\n(import \"env\" \"source\" (func $source (result i64)))\n(import \"env\" \"map_get\" (func $map_get (param i64 i64) (result i64)))\n(import \"env\" \"mem\" (func $mem (param i64 i64) (result i64)))\n(import \"env\" \"update\" (func $update (param i64 i64 i64) (result i64)))\n(import \"env\" \"iter\" (func $iter (param i64 i32) (result )))\n(import \"env\" \"map\" (func $map (param i64 i32) (result i64)))\n(import \"env\" \"if_left\" (func $if_left (param i64) (result i32)))\n(import \"env\" \"if_none\" (func $if_none (param i64) (result i32)))\n(import \"env\" \"if_cons\" (func $if_cons (param i64) (result i32)))\n(import \"env\" \"isnat\" (func $isnat (param i64) (result i64)))\n(import \"env\" \"not\" (func $not (param i64) (result i64)))\n(import \"env\" \"or\" (func $or (param i64 i64) (result i64)))\n(import \"env\" \"and\" (func $and (param i64 i64) (result i64)))\n(import \"env\" \"xor\" (func $xor (param i64 i64) (result i64)))\n(import \"env\" \"deref_bool\" (func $deref_bool (param i64) (result i32)))\n(import \"env\" \"neq\" (func $neq (param i64) (result i64)))\n(import \"env\" \"failwith\" (func $failwith (param i64)))\n(import \"env\" \"get_n\" (func $get_n (param i32 i64) (result i64)))\n(import \"env\" \"exec\" (func $exec (param i64 i64) (result i64)))\n(import \"env\" \"apply\" (func $apply (param i64 i64) (result i64)))\n(import \"env\" \"const\" (func $const (param i32) (result i64)))\n(import \"env\" \"abs\" (func $abs (param i64) (result i64)))\n(import \"env\" \"eq\" (func $eq (param i64) (result i64)))\n(import \"env\" \"gt\" (func $gt (param i64) (result i64)))\n(import \"env\" \"lt\" (func $lt (param i64) (result i64)))\n(import \"env\" \"closure\" (func $closure (param i32) (result i64)))\n(import \"env\" \"left\" (func $left (param i64) (result i64)))\n(import \"env\" \"right\" (func $right (param i64) (result i64)))\n(import \"env\" \"cons\" (func $cons (param i64 i64) (result i64)))\n(import \"env\" \"transfer_tokens\" (func $transfer_tokens (param i64 i64 i64) (result i64)))\n(import \"env\" \"address\" (func $address (param i64) (result i64)))\n(import \"env\" \"contract\" (func $contract (param i64) (result i64)))\n(import \"env\" \"self\" (func $self (result i64)))\n(import \"env\" \"self_address\" (func $self_address (result i64)))\n(import \"env\" \"get_and_update\" (func $get_and_update (param i64 i64 i64)))\n(import \"env\" \"read_ticket\" (func $read_ticket (param i64)))\n(import \"env\" \"ticket\" (func $ticket (param i64 i64) (result i64)))\n(import \"env\" \"join_tickets\" (func $join_tickets (param i64) (result i64)))\n(import \"env\" \"split_ticket\" (func $split_ticket (param i64 i64) (result i64)))\n(import \"env\" \"amount\" (func $amount (result i64)))\n(import \"env\" \"balance\" (func $balance (result i64)))\n(import \"env\" \"ediv\" (func $ediv (param i64 i64) (result i64)))\n(import \"env\" \"ge\" (func $ge (param i64) (result i64)))\n(import \"env\" \"le\" (func $le (param i64) (result i64)))\n(import \"env\" \"size\" (func $size (param i64) (result i64)))\n(import \"env\" \"int\" (func $int (param i64) (result i64)))\n(import \"env\" \"implicit_account\" (func $implicit_account (param i64) (result i64)))\n(import \"env\" \"blake2b\" (func $blake2b (param i64) (result i64)))\n(import \"env\" \"pack\" (func $pack (param i64) (result i64)))\n(import \"env\" \"unpack\" (func $unpack (param i64) (result i64)))\n(import \"env\" \"keccak\" (func $keccak (param i64) (result i64)))\n(import \"env\" \"sha256\" (func $sha256 (param i64) (result i64)))\n(import \"env\" \"sha3\" (func $sha3 (param i64) (result i64)))\n(import \"env\" \"sha512\" (func $sha512 (param i64) (result i64)))\n\n (global $mode i32 (i32.const 0))\n\n (memory 4)\n (global $sp (mut i32) (i32.const 4000)) ;; stack pointer\n (global $sh_sp (mut i32) (i32.const 1000)) ;;shadow_stack stack pointer\n\n (global $__stack_base i32 (i32.const 32768))\n\n (type $callback_t (func (param i64) (result i64)))\n (func $call_callback (param $arg1 i64) (param $idx i32) (result i64)\n (call_indirect (type $callback_t) (local.get $arg1) (local.get $idx)))\n\n (type $callback_t_unit (func (param i64) (result)))\n (func $call_callback_unit (param $arg1 i64) (param $idx i32) (result )\n (call_indirect (type $callback_t_unit)\n (local.get $arg1)\n (local.get $idx)))\n\n (func $dip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.set $stop (i32.const 0))\n (local.set $sp' (global.get $sp))\n (local.tee $sh_sp' (i32.sub (global.get $sh_sp) (local.get $n)))\n global.set $sh_sp\n (loop $l\n (i32.mul (i32.const 8) (i32.add (global.get $__stack_base) (i32.add (local.get $sh_sp') (local.get $stop))))\n (i64.load (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop))))\n i64.store\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n\n (global.set $sp\n (i32.add\n (local.get $sp') (local.get $n))))\n\n (func $undip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.tee $sp' (i32.sub (global.get $sp) (local.get $n)))\n global.set $sp\n (local.set $sh_sp' (global.get $sh_sp))\n (local.set $stop (i32.const 0))\n (loop $l\n (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop)))\n (i64.load\n (i32.add\n (global.get $__stack_base)\n (i32.mul (i32.const 8) (i32.add (local.get $sh_sp') (local.get $stop)))))\n (i64.store)\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n (global.set $sh_sp (i32.add (local.get $sh_sp') (local.get $n))))\n\n (func $dup (param $n i32) (result)\n (i64.load (i32.mul (i32.const 8) (i32.add (global.get $sp) (local.get $n))))\n (call $dup_host))\n\n (func $swap (param) (result)\n (local $v1 i64)\n (local $v2 i64)\n (local.set $v1 (call $pop))\n (local.set $v2 (call $pop))\n (call $push (local.get $v1))\n (call $push (local.get $v2)))\n\n (func $dug (param $n i32) (result)\n (local $idx i32)\n (local $loop_idx i32)\n (local $sp' i32)\n (local $top i64)\n (local.set $sp' (i32.add (global.get $sp) (local.get $n)))\n (local.tee $idx (global.get $sp))\n (local.tee $loop_idx)\n (i32.mul (i32.const 8))\n i64.load\n local.set $top\n (loop $loop\n (i32.mul (i32.const 8) (local.get $idx))\n (i32.add (local.get $loop_idx) (i32.const 1))\n local.tee $loop_idx\n (i32.mul (i32.const 8))\n i64.load\n i64.store\n (local.set $idx (i32.add (local.get $idx) (i32.const 1)))\n (local.get $idx)\n (local.get $sp')\n i32.lt_u\n br_if $loop)\n\n (i64.store (i32.mul (i32.const 8) (local.get $sp')) (local.get $top)))\n\n (func $dig (param $n i32) (result)\n (local $idx i32) (local $t i32) (local $digged i64)\n\n (local.set $digged\n (i64.load\n (i32.mul (i32.const 8)\n (local.tee $idx (i32.add (global.get $sp) (local.get $n))))))\n\n (loop $loop\n (local.set $t (i32.mul (i32.const 8) (local.get $idx)))\n\n (i64.store (local.get $t)\n (i64.load\n (i32.mul\n (i32.const 8)\n (local.tee $idx (i32.sub (local.get $idx) (i32.const 1))))))\n\n (br_if $loop\n (i32.lt_u (global.get $sp) (local.get $idx))))\n\n (i64.store (i32.mul (i32.const 8) (local.get $idx)) (local.get $digged)))\n\n (func $pop (result i64)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (global.get $sp)))\n i64.load\n (global.set $sp (i32.add (local.get $spp) (i32.const 1)))) ;;set stackptr\n\n (func $push (param $value i64) (result)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (i32.sub (global.get $sp) (i32.const 1)) ))\n (i64.store (local.get $value))\n (global.set $sp (local.get $spp))) ;;set stackptr\n\n (func $drop (param $n i32) (result)\n (global.set $sp (i32.add (global.get $sp) (local.get $n)))) ;;set stackptr\n\n (table $closures funcref (elem ))\n\n\n (func $main (param $v1 i64) (result i64)\n (local $1 i64)\n (call $push (local.get $v1))\n (call $push (call $zero)) (; 0 ;)\n(call $push (call $amount))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $unpair (call $pop)) ;; implicit return\n(call $swap)\n(call $unpair (call $pop)) ;; implicit return\n(call $dig (i32.const 4))\n(call $if_left (call $pop)) (if (then (call $if_left (call $pop)) (if (then (call $if_left (call $pop)) (if (then (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 2))\n(call $push (call $none))\n(call $dup (i32.const 2))\n(call $push (call $get_n (i32.const 10) (call $pop)))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $if_none (call $pop)) (if (then (call $drop (i32.const 5))\n(call $push (call $const (i32.const 1))) (; \"no tickets\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dup (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $zero)) (; 0 ;)\n(call $dig (i32.const 2))\n(call $dup (i32.const 4))\n(call $push (call $get_n (i32.const 9) (call $pop)))\n(call $dup (i32.const 5))\n(call $push (call $get_n (i32.const 7) (call $pop)))\n(call $dup (i32.const 6))\n(call $push (call $get_n (i32.const 5) (call $pop)))\n(call $dig (i32.const 7))\n(call $push (call $get_n (i32.const 3) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $transfer_tokens (call $pop) (call $pop) (call $pop)))\n(call $dig (i32.const 4))\n(call $dig (i32.const 4))\n(call $dig (i32.const 3))\n(call $dig (i32.const 4))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $dig (i32.const 2))\n(call $push (call $cons (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 4))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 5))\n(call $push (call $z_add (call $pop) (call $pop)))\n(call $dig (i32.const 4))\n(call $push (call $none))\n(call $dig (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $dig (i32.const 3))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $if_left (call $pop)) (if (then (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dup (i32.const 4))\n(call $push (call $ticket (call $pop) (call $pop)))\n(call $dig (i32.const 3))\n(call $swap)\n(call $push (call $some (call $pop)))\n(call $dup (i32.const 4))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $drop (i32.const 1))\n(call $dig (i32.const 4))\n(call $dig (i32.const 2))\n(call $dup (i32.const 4))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $some (call $pop)))\n(call $dup (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 4))\n(call $push (call $z_add (call $pop) (call $pop)))) (else (call $read_ticket (call $pop)) ;; implicit return\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 3))\n(call $dig (i32.const 2))\n(call $push (call $some (call $pop)))\n(call $dup (i32.const 4))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $drop (i32.const 1))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 2))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 3))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 4))\n(call $push (call $z_add (call $pop) (call $pop)))))\n(call $dig (i32.const 2))\n(call $dig (i32.const 3))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 2))\n(call $push (call $none))\n(call $dup (i32.const 2))\n(call $push (call $cdr (call $pop)))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $if_none (call $pop)) (if (then (call $drop (i32.const 5))\n(call $push (call $const (i32.const 1))) (; \"no tickets\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dig (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $zero)) (; 0 ;)\n(call $dig (i32.const 2))\n(call $push (call $transfer_tokens (call $pop) (call $pop) (call $pop)))\n(call $dig (i32.const 4))\n(call $dig (i32.const 4))\n(call $dig (i32.const 3))\n(call $dig (i32.const 4))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $dig (i32.const 2))\n(call $push (call $cons (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))))))\n (call $pop))\n\n (export \"push\" (func $push))\n (export \"pop\" (func $push))\n (export \"main\" (func $main))\n (export \"closures\" (table $closures))\n (export \"call_callback\" (func $call_callback))\n (export \"call_callback_unit\" (func $call_callback_unit))\n )\n", "constants": [ [ 0, [ "String", "failed assertion" ] ], [ 1, [ "String", "no tickets" ] ], diff --git a/packages/tunac/tests/nft_wallet.t b/packages/tunac/tests/nft_wallet.t index abca684..05e725e 100644 --- a/packages/tunac/tests/nft_wallet.t +++ b/packages/tunac/tests/nft_wallet.t @@ -1,7 +1,7 @@ NFT Wallet $ ../bin/tunacc_test.exe contract nft_wallet.tz { - "module_": "\n(module\n (import \"env\" \"dup_host\" (func $dup_host (param i64 ) (result)))\n(import \"env\" \"pair\" (func $pair (param i64 i64) (result i64)))\n(import \"env\" \"unpair\" (func $unpair (param i64)))\n(import \"env\" \"z_add\" (func $z_add (param i64 i64) (result i64)))\n(import \"env\" \"z_sub\" (func $z_sub (param i64 i64) (result i64)))\n(import \"env\" \"z_mul\" (func $z_mul (param i64 i64) (result i64)))\n(import \"env\" \"neg\" (func $neg (param i64) (result i64)))\n(import \"env\" \"lsl\" (func $lsl (param i64 i64) (result i64)))\n(import \"env\" \"concat\" (func $concat (param i64 i64) (result i64)))\n(import \"env\" \"lsr\" (func $lsr (param i64 i64) (result i64)))\n(import \"env\" \"compare\" (func $compare (param i64 i64) (result i64)))\n(import \"env\" \"car\" (func $car (param i64) (result i64)))\n(import \"env\" \"cdr\" (func $cdr (param i64) (result i64)))\n(import \"env\" \"some\" (func $some (param i64) (result i64)))\n(import \"env\" \"nil\" (func $nil (result i64)))\n(import \"env\" \"true\" (func $true (result i64)))\n(import \"env\" \"false\" (func $false (result i64)))\n(import \"env\" \"none\" (func $none (result i64)))\n(import \"env\" \"unit\" (func $unit (result i64)))\n(import \"env\" \"zero\" (func $zero (result i64)))\n(import \"env\" \"empty_map\" (func $empty_map (result i64)))\n(import \"env\" \"empty_set\" (func $empty_set (result i64)))\n(import \"env\" \"empty_big_map\" (func $empty_big_map (result i64)))\n(import \"env\" \"sender\" (func $sender (result i64)))\n(import \"env\" \"source\" (func $source (result i64)))\n(import \"env\" \"map_get\" (func $map_get (param i64 i64) (result i64)))\n(import \"env\" \"mem\" (func $mem (param i64 i64) (result i64)))\n(import \"env\" \"update\" (func $update (param i64 i64 i64) (result i64)))\n(import \"env\" \"iter\" (func $iter (param i64 i32) (result )))\n(import \"env\" \"map\" (func $map (param i64 i32) (result i64)))\n(import \"env\" \"if_left\" (func $if_left (param i64) (result i32)))\n(import \"env\" \"if_none\" (func $if_none (param i64) (result i32)))\n(import \"env\" \"if_cons\" (func $if_cons (param i64) (result i32)))\n(import \"env\" \"isnat\" (func $isnat (param i64) (result i64)))\n(import \"env\" \"not\" (func $not (param i64) (result i64)))\n(import \"env\" \"or\" (func $or (param i64 i64) (result i64)))\n(import \"env\" \"and\" (func $and (param i64 i64) (result i64)))\n(import \"env\" \"xor\" (func $xor (param i64 i64) (result i64)))\n(import \"env\" \"deref_bool\" (func $deref_bool (param i64) (result i32)))\n(import \"env\" \"neq\" (func $neq (param i64) (result i64)))\n(import \"env\" \"failwith\" (func $failwith (param i64)))\n(import \"env\" \"get_n\" (func $get_n (param i32 i64) (result i64)))\n(import \"env\" \"exec\" (func $exec (param i64 i64) (result i64)))\n(import \"env\" \"apply\" (func $apply (param i64 i64) (result i64)))\n(import \"env\" \"const\" (func $const (param i32) (result i64)))\n(import \"env\" \"abs\" (func $abs (param i64) (result i64)))\n(import \"env\" \"eq\" (func $eq (param i64) (result i64)))\n(import \"env\" \"gt\" (func $gt (param i64) (result i64)))\n(import \"env\" \"lt\" (func $lt (param i64) (result i64)))\n(import \"env\" \"closure\" (func $closure (param i32) (result i64)))\n(import \"env\" \"left\" (func $left (param i64) (result i64)))\n(import \"env\" \"right\" (func $right (param i64) (result i64)))\n(import \"env\" \"cons\" (func $cons (param i64 i64) (result i64)))\n(import \"env\" \"transfer_tokens\" (func $transfer_tokens (param i64 i64 i64) (result i64)))\n(import \"env\" \"address\" (func $address (param i64) (result i64)))\n(import \"env\" \"contract\" (func $contract (param i64) (result i64)))\n(import \"env\" \"self\" (func $self (result i64)))\n(import \"env\" \"self_address\" (func $self_address (result i64)))\n(import \"env\" \"get_and_update\" (func $get_and_update (param i64 i64 i64)))\n(import \"env\" \"read_ticket\" (func $read_ticket (param i64)))\n(import \"env\" \"ticket\" (func $ticket (param i64 i64) (result i64)))\n(import \"env\" \"join_tickets\" (func $join_tickets (param i64) (result i64)))\n(import \"env\" \"split_ticket\" (func $split_ticket (param i64 i64) (result i64)))\n(import \"env\" \"amount\" (func $amount (result i64)))\n(import \"env\" \"balance\" (func $balance (result i64)))\n(import \"env\" \"ediv\" (func $ediv (param i64 i64) (result i64)))\n(import \"env\" \"ge\" (func $ge (param i64) (result i64)))\n(import \"env\" \"le\" (func $le (param i64) (result i64)))\n(import \"env\" \"size\" (func $size (param i64) (result i64)))\n(import \"env\" \"int\" (func $int (param i64) (result i64)))\n(import \"env\" \"implicit_account\" (func $implicit_account (param i64) (result i64)))\n(import \"env\" \"blake2b\" (func $blake2b (param i64) (result i64)))\n(import \"env\" \"pack\" (func $pack (param i64) (result i64)))\n(import \"env\" \"unpack\" (func $unpack (param i64) (result i64)))\n(import \"env\" \"keccak\" (func $keccak (param i64) (result i64)))\n(import \"env\" \"sha256\" (func $sha256 (param i64) (result i64)))\n(import \"env\" \"sha3\" (func $sha3 (param i64) (result i64)))\n(import \"env\" \"sha512\" (func $sha512 (param i64) (result i64)))\n\n (global $mode i32 (i32.const 0))\n\n (memory 4)\n (global $sp (mut i32) (i32.const 4000)) ;; stack pointer\n (global $sh_sp (mut i32) (i32.const 1000)) ;;shadow_stack stack pointer\n\n (global $__stack_base i32 (i32.const 32768))\n\n (type $callback_t (func (param i64) (result i64)))\n (func $call_callback (param $arg1 i64) (param $idx i32) (result i64)\n (call_indirect (type $callback_t) (local.get $arg1) (local.get $idx)))\n\n (type $callback_t_unit (func (param i64) (result)))\n (func $call_callback_unit (param $arg1 i64) (param $idx i32) (result )\n (call_indirect (type $callback_t_unit)\n (local.get $arg1)\n (local.get $idx)))\n\n (func $dip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.set $stop (i32.const 0))\n (local.set $sp' (global.get $sp))\n (local.tee $sh_sp' (i32.sub (global.get $sh_sp) (local.get $n)))\n global.set $sh_sp\n (loop $l\n (i32.mul (i32.const 8) (i32.add (global.get $__stack_base) (i32.add (local.get $sh_sp') (local.get $stop))))\n (i64.load (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop))))\n i64.store\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n\n (global.set $sp\n (i32.add\n (local.get $sp') (local.get $n))))\n\n (func $undip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.tee $sp' (i32.sub (global.get $sp) (local.get $n)))\n global.set $sp\n (local.set $sh_sp' (global.get $sh_sp))\n (local.set $stop (i32.const 0))\n (loop $l\n (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop)))\n (i64.load\n (i32.add\n (global.get $__stack_base)\n (i32.mul (i32.const 8) (i32.add (local.get $sh_sp') (local.get $stop)))))\n (i64.store)\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n (global.set $sh_sp (i32.add (local.get $sh_sp') (local.get $n))))\n\n (func $dup (param $n i32) (result)\n (i64.load (i32.mul (i32.const 8) (i32.add (global.get $sp) (local.get $n))))\n (call $dup_host))\n\n (func $swap (param) (result)\n (local $v1 i64)\n (local $v2 i64)\n (local.set $v1 (call $pop))\n (local.set $v2 (call $pop))\n (call $push (local.get $v1))\n (call $push (local.get $v2)))\n\n (func $dug (param $n i32) (result)\n (local $idx i32)\n (local $loop_idx i32)\n (local $sp' i32)\n (local $top i64)\n (local.set $sp' (i32.add (global.get $sp) (local.get $n)))\n (local.tee $idx (global.get $sp))\n (local.tee $loop_idx)\n (i32.mul (i32.const 8))\n i64.load\n local.set $top\n (loop $loop\n (i32.mul (i32.const 8) (local.get $idx))\n (i32.add (local.get $loop_idx) (i32.const 1))\n local.tee $loop_idx\n (i32.mul (i32.const 8))\n i64.load\n i64.store\n (local.set $idx (i32.add (local.get $idx) (i32.const 1)))\n (local.get $idx)\n (local.get $sp')\n i32.lt_u\n br_if $loop)\n\n (i64.store (i32.mul (i32.const 8) (local.get $sp')) (local.get $top)))\n\n (func $dig (param $n i32) (result)\n (local $idx i32) (local $t i32) (local $digged i64)\n\n (local.set $digged\n (i64.load\n (i32.mul (i32.const 8)\n (local.tee $idx (i32.add (global.get $sp) (local.get $n))))))\n\n (loop $loop\n (local.set $t (i32.mul (i32.const 8) (local.get $idx)))\n\n (i64.store (local.get $t)\n (i64.load\n (i32.mul\n (i32.const 8)\n (local.tee $idx (i32.sub (local.get $idx) (i32.const 1))))))\n\n (br_if $loop\n (i32.lt_u (global.get $sp) (local.get $idx))))\n\n (i64.store (i32.mul (i32.const 8) (local.get $idx)) (local.get $digged)))\n\n (func $pop (result i64)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (global.get $sp)))\n i64.load\n (global.set $sp (i32.add (local.get $spp) (i32.const 1)))) ;;set stackptr\n\n (func $push (param $value i64) (result)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (i32.sub (global.get $sp) (i32.const 1)) ))\n (i64.store (local.get $value))\n (global.set $sp (local.get $spp))) ;;set stackptr\n\n (func $drop (param $n i32) (result)\n (global.set $sp (i32.add (global.get $sp) (local.get $n)))) ;;set stackptr\n\n (table $closures funcref (elem ))\n\n\n (func $main (param $v1 i64) (result i64)\n (local $1 i64)\n (call $push (local.get $v1))\n (call $push (call $zero)) (; 0 ;)\n(call $push (call $amount))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $unpair (call $pop)) ;; implicit return\n(call $swap)\n(call $unpair (call $pop)) ;; implicit return\n(call $dig (i32.const 4))\n(call $if_left (call $pop)) (if (then (call $if_left (call $pop)) (if (then (call $if_left (call $pop)) (if (then (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 2))\n(call $push (call $none))\n(call $dup (i32.const 2))\n(call $push (call $get_n (i32.const 10) (call $pop)))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $if_none (call $pop)) (if (then (call $drop (i32.const 5))\n(call $push (call $const (i32.const 1))) (; \"no tickets\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dup (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $zero)) (; 0 ;)\n(call $dig (i32.const 2))\n(call $dup (i32.const 4))\n(call $push (call $get_n (i32.const 9) (call $pop)))\n(call $dup (i32.const 5))\n(call $push (call $get_n (i32.const 7) (call $pop)))\n(call $dup (i32.const 6))\n(call $push (call $get_n (i32.const 5) (call $pop)))\n(call $dig (i32.const 7))\n(call $push (call $get_n (i32.const 3) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $transfer_tokens (call $pop) (call $pop) (call $pop)))\n(call $dig (i32.const 4))\n(call $dig (i32.const 4))\n(call $dig (i32.const 3))\n(call $dig (i32.const 4))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $dig (i32.const 2))\n(call $push (call $cons (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 4))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 5))\n(call $push (call $z_add (call $pop) (call $pop)))\n(call $dig (i32.const 4))\n(call $push (call $none))\n(call $dig (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $dig (i32.const 3))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $if_left (call $pop)) (if (then (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dup (i32.const 4))\n(call $push (call $ticket (call $pop) (call $pop)))\n(call $dig (i32.const 3))\n(call $swap)\n(call $push (call $some (call $pop)))\n(call $dup (i32.const 4))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $drop (i32.const 1))\n(call $dig (i32.const 4))\n(call $dig (i32.const 2))\n(call $dup (i32.const 4))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $some (call $pop)))\n(call $dup (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 4))\n(call $push (call $z_add (call $pop) (call $pop)))) (else (call $read_ticket (call $pop)) ;; implicit return\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 3))\n(call $dig (i32.const 2))\n(call $push (call $some (call $pop)))\n(call $dup (i32.const 4))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $drop (i32.const 1))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 2))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 3))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 4))\n(call $push (call $z_add (call $pop) (call $pop)))))\n(call $dig (i32.const 2))\n(call $dig (i32.const 3))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 2))\n(call $push (call $none))\n(call $dup (i32.const 2))\n(call $push (call $cdr (call $pop)))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $if_none (call $pop)) (if (then (call $drop (i32.const 5))\n(call $push (call $const (i32.const 1))) (; \"no tickets\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dig (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $zero)) (; 0 ;)\n(call $dig (i32.const 2))\n(call $push (call $transfer_tokens (call $pop) (call $pop) (call $pop)))\n(call $dig (i32.const 4))\n(call $dig (i32.const 4))\n(call $dig (i32.const 3))\n(call $dig (i32.const 4))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $dig (i32.const 2))\n(call $push (call $cons (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))))))\n (call $pop))\n\n (export \"push\" (func $push))\n (export \"pop\" (func $push))\n (export \"main\" (func $main))\n (export \"closures\" (table $closures))\n (export \"call_callback\" (func $call_callback))\n (export \"call_callback_unit\" (func $call_callback_unit))\n )\n", + "module_": "\n(module\n (import \"env\" \"dup_host\" (func $dup_host (param i64 ) (result)))\n(import \"env\" \"pair\" (func $pair (param i64 i64) (result i64)))\n(import \"env\" \"unpair\" (func $unpair (param i64)))\n(import \"env\" \"z_add\" (func $z_add (param i64 i64) (result i64)))\n(import \"env\" \"z_sub\" (func $z_sub (param i64 i64) (result i64)))\n(import \"env\" \"z_mul\" (func $z_mul (param i64 i64) (result i64)))\n(import \"env\" \"neg\" (func $neg (param i64) (result i64)))\n(import \"env\" \"lsl\" (func $lsl (param i64 i64) (result i64)))\n(import \"env\" \"concat\" (func $concat (param i64 i64) (result i64)))\n(import \"env\" \"lsr\" (func $lsr (param i64 i64) (result i64)))\n(import \"env\" \"compare\" (func $compare (param i64 i64) (result i64)))\n(import \"env\" \"car\" (func $car (param i64) (result i64)))\n(import \"env\" \"cdr\" (func $cdr (param i64) (result i64)))\n(import \"env\" \"some\" (func $some (param i64) (result i64)))\n(import \"env\" \"nil\" (func $nil (result i64)))\n(import \"env\" \"true\" (func $true (result i64)))\n(import \"env\" \"false\" (func $false (result i64)))\n(import \"env\" \"none\" (func $none (result i64)))\n(import \"env\" \"unit\" (func $unit (result i64)))\n(import \"env\" \"zero\" (func $zero (result i64)))\n(import \"env\" \"empty_map\" (func $empty_map (result i64)))\n(import \"env\" \"empty_set\" (func $empty_set (result i64)))\n(import \"env\" \"empty_big_map\" (func $empty_big_map (result i64)))\n(import \"env\" \"sender\" (func $sender (result i64)))\n(import \"env\" \"source\" (func $source (result i64)))\n(import \"env\" \"map_get\" (func $map_get (param i64 i64) (result i64)))\n(import \"env\" \"mem\" (func $mem (param i64 i64) (result i64)))\n(import \"env\" \"update\" (func $update (param i64 i64 i64) (result i64)))\n(import \"env\" \"iter\" (func $iter (param i64 i32) (result )))\n(import \"env\" \"map\" (func $map (param i64 i32) (result i64)))\n(import \"env\" \"if_left\" (func $if_left (param i64) (result i32)))\n(import \"env\" \"if_none\" (func $if_none (param i64) (result i32)))\n(import \"env\" \"if_cons\" (func $if_cons (param i64) (result i32)))\n(import \"env\" \"isnat\" (func $isnat (param i64) (result i64)))\n(import \"env\" \"not\" (func $not (param i64) (result i64)))\n(import \"env\" \"or\" (func $or (param i64 i64) (result i64)))\n(import \"env\" \"and\" (func $and (param i64 i64) (result i64)))\n(import \"env\" \"xor\" (func $xor (param i64 i64) (result i64)))\n(import \"env\" \"deref_bool\" (func $deref_bool (param i64) (result i32)))\n(import \"env\" \"neq\" (func $neq (param i64) (result i64)))\n(import \"env\" \"failwith\" (func $failwith (param i64)))\n(import \"env\" \"get_n\" (func $get_n (param i32 i64) (result i64)))\n(import \"env\" \"exec\" (func $exec (param i64 i64) (result i64)))\n(import \"env\" \"apply\" (func $apply (param i64 i64) (result i64)))\n(import \"env\" \"const\" (func $const (param i32) (result i64)))\n(import \"env\" \"abs\" (func $abs (param i64) (result i64)))\n(import \"env\" \"eq\" (func $eq (param i64) (result i64)))\n(import \"env\" \"gt\" (func $gt (param i64) (result i64)))\n(import \"env\" \"lt\" (func $lt (param i64) (result i64)))\n(import \"env\" \"closure\" (func $closure (param i32) (result i64)))\n(import \"env\" \"left\" (func $left (param i64) (result i64)))\n(import \"env\" \"right\" (func $right (param i64) (result i64)))\n(import \"env\" \"cons\" (func $cons (param i64 i64) (result i64)))\n(import \"env\" \"transfer_tokens\" (func $transfer_tokens (param i64 i64 i64) (result i64)))\n(import \"env\" \"address\" (func $address (param i64) (result i64)))\n(import \"env\" \"contract\" (func $contract (param i64) (result i64)))\n(import \"env\" \"self\" (func $self (result i64)))\n(import \"env\" \"self_address\" (func $self_address (result i64)))\n(import \"env\" \"get_and_update\" (func $get_and_update (param i64 i64 i64)))\n(import \"env\" \"read_ticket\" (func $read_ticket (param i64)))\n(import \"env\" \"ticket\" (func $ticket (param i64 i64) (result i64)))\n(import \"env\" \"join_tickets\" (func $join_tickets (param i64) (result i64)))\n(import \"env\" \"split_ticket\" (func $split_ticket (param i64 i64) (result i64)))\n(import \"env\" \"amount\" (func $amount (result i64)))\n(import \"env\" \"balance\" (func $balance (result i64)))\n(import \"env\" \"ediv\" (func $ediv (param i64 i64) (result i64)))\n(import \"env\" \"ge\" (func $ge (param i64) (result i64)))\n(import \"env\" \"le\" (func $le (param i64) (result i64)))\n(import \"env\" \"size\" (func $size (param i64) (result i64)))\n(import \"env\" \"int\" (func $int (param i64) (result i64)))\n(import \"env\" \"implicit_account\" (func $implicit_account (param i64) (result i64)))\n(import \"env\" \"blake2b\" (func $blake2b (param i64) (result i64)))\n(import \"env\" \"pack\" (func $pack (param i64) (result i64)))\n(import \"env\" \"unpack\" (func $unpack (param i64) (result i64)))\n(import \"env\" \"keccak\" (func $keccak (param i64) (result i64)))\n(import \"env\" \"sha256\" (func $sha256 (param i64) (result i64)))\n(import \"env\" \"sha3\" (func $sha3 (param i64) (result i64)))\n(import \"env\" \"sha512\" (func $sha512 (param i64) (result i64)))\n\n (global $mode i32 (i32.const 0))\n\n (memory 4)\n (global $sp (mut i32) (i32.const 4000)) ;; stack pointer\n (global $sh_sp (mut i32) (i32.const 1000)) ;;shadow_stack stack pointer\n\n (global $__stack_base i32 (i32.const 32768))\n\n (type $callback_t (func (param i64) (result i64)))\n (func $call_callback (param $arg1 i64) (param $idx i32) (result i64)\n (call_indirect (type $callback_t) (local.get $arg1) (local.get $idx)))\n\n (type $callback_t_unit (func (param i64) (result)))\n (func $call_callback_unit (param $arg1 i64) (param $idx i32) (result )\n (call_indirect (type $callback_t_unit)\n (local.get $arg1)\n (local.get $idx)))\n\n (func $dip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.set $stop (i32.const 0))\n (local.set $sp' (global.get $sp))\n (local.tee $sh_sp' (i32.sub (global.get $sh_sp) (local.get $n)))\n global.set $sh_sp\n (loop $l\n (i32.mul (i32.const 8) (i32.add (global.get $__stack_base) (i32.add (local.get $sh_sp') (local.get $stop))))\n (i64.load (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop))))\n i64.store\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n\n (global.set $sp\n (i32.add\n (local.get $sp') (local.get $n))))\n\n (func $undip (param $n i32) (result)\n (local $stop i32)\n (local $sp' i32)\n (local $sh_sp' i32)\n (local.tee $sp' (i32.sub (global.get $sp) (local.get $n)))\n global.set $sp\n (local.set $sh_sp' (global.get $sh_sp))\n (local.set $stop (i32.const 0))\n (loop $l\n (i32.mul (i32.const 8) (i32.add (local.get $sp') (local.get $stop)))\n (i64.load\n (i32.add\n (global.get $__stack_base)\n (i32.mul (i32.const 8) (i32.add (local.get $sh_sp') (local.get $stop)))))\n (i64.store)\n (local.tee $stop (i32.add (local.get $stop) (i32.const 1)))\n (local.get $n)\n i32.ne\n br_if $l)\n (global.set $sh_sp (i32.add (local.get $sh_sp') (local.get $n))))\n\n (func $dup (param $n i32) (result)\n (i64.load (i32.mul (i32.const 8) (i32.add (global.get $sp) (local.get $n))))\n (call $dup_host))\n\n (func $swap (param) (result)\n (local $v1 i64)\n (local $v2 i64)\n (local.set $v1 (call $pop))\n (local.set $v2 (call $pop))\n (call $push (local.get $v1))\n (call $push (local.get $v2)))\n\n (func $dug (param $n i32) (result)\n (local $idx i32)\n (local $loop_idx i32)\n (local $sp' i32)\n (local $top i64)\n (local.set $sp' (i32.add (global.get $sp) (local.get $n)))\n (local.tee $idx (global.get $sp))\n (local.tee $loop_idx)\n (i32.mul (i32.const 8))\n i64.load\n local.set $top\n (loop $loop\n (i32.mul (i32.const 8) (local.get $idx))\n (i32.add (local.get $loop_idx) (i32.const 1))\n local.tee $loop_idx\n (i32.mul (i32.const 8))\n i64.load\n i64.store\n (local.set $idx (i32.add (local.get $idx) (i32.const 1)))\n (local.get $idx)\n (local.get $sp')\n i32.lt_u\n br_if $loop)\n\n (i64.store (i32.mul (i32.const 8) (local.get $sp')) (local.get $top)))\n\n (func $dig (param $n i32) (result)\n (local $idx i32) (local $t i32) (local $digged i64)\n\n (local.set $digged\n (i64.load\n (i32.mul (i32.const 8)\n (local.tee $idx (i32.add (global.get $sp) (local.get $n))))))\n\n (loop $loop\n (local.set $t (i32.mul (i32.const 8) (local.get $idx)))\n\n (i64.store (local.get $t)\n (i64.load\n (i32.mul\n (i32.const 8)\n (local.tee $idx (i32.sub (local.get $idx) (i32.const 1))))))\n\n (br_if $loop\n (i32.lt_u (global.get $sp) (local.get $idx))))\n\n (i64.store (i32.mul (i32.const 8) (local.get $idx)) (local.get $digged)))\n\n (func $pop (result i64)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (global.get $sp)))\n i64.load\n (global.set $sp (i32.add (local.get $spp) (i32.const 1)))) ;;set stackptr\n\n (func $push (param $value i64) (result)\n (local $spp i32)\n (i32.mul (i32.const 8) (local.tee $spp (i32.sub (global.get $sp) (i32.const 1)) ))\n (i64.store (local.get $value))\n (global.set $sp (local.get $spp))) ;;set stackptr\n\n (func $drop (param $n i32) (result)\n (global.set $sp (i32.add (global.get $sp) (local.get $n)))) ;;set stackptr\n\n (table $closures funcref (elem ))\n\n\n (func $main (param $v1 i64) (result i64)\n (local $1 i64)\n (call $push (local.get $v1))\n (call $push (call $zero)) (; 0 ;)\n(call $push (call $amount))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $unpair (call $pop)) ;; implicit return\n(call $swap)\n(call $unpair (call $pop)) ;; implicit return\n(call $dig (i32.const 4))\n(call $if_left (call $pop)) (if (then (call $if_left (call $pop)) (if (then (call $if_left (call $pop)) (if (then (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 2))\n(call $push (call $none))\n(call $dup (i32.const 2))\n(call $push (call $get_n (i32.const 10) (call $pop)))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $if_none (call $pop)) (if (then (call $drop (i32.const 5))\n(call $push (call $const (i32.const 1))) (; \"no tickets\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dup (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $zero)) (; 0 ;)\n(call $dig (i32.const 2))\n(call $dup (i32.const 4))\n(call $push (call $get_n (i32.const 9) (call $pop)))\n(call $dup (i32.const 5))\n(call $push (call $get_n (i32.const 7) (call $pop)))\n(call $dup (i32.const 6))\n(call $push (call $get_n (i32.const 5) (call $pop)))\n(call $dig (i32.const 7))\n(call $push (call $get_n (i32.const 3) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $transfer_tokens (call $pop) (call $pop) (call $pop)))\n(call $dig (i32.const 4))\n(call $dig (i32.const 4))\n(call $dig (i32.const 3))\n(call $dig (i32.const 4))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $dig (i32.const 2))\n(call $push (call $cons (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 4))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 5))\n(call $push (call $z_add (call $pop) (call $pop)))\n(call $dig (i32.const 4))\n(call $push (call $none))\n(call $dig (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $dig (i32.const 3))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $if_left (call $pop)) (if (then (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dup (i32.const 4))\n(call $push (call $ticket (call $pop) (call $pop)))\n(call $dig (i32.const 3))\n(call $swap)\n(call $push (call $some (call $pop)))\n(call $dup (i32.const 4))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $drop (i32.const 1))\n(call $dig (i32.const 4))\n(call $dig (i32.const 2))\n(call $dup (i32.const 4))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $some (call $pop)))\n(call $dup (i32.const 4))\n(call $push (call $update (call $pop) (call $pop) (call $pop)))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 4))\n(call $push (call $z_add (call $pop) (call $pop)))) (else (call $read_ticket (call $pop)) ;; implicit return\n(call $push (call $cdr (call $pop)))\n(call $push (call $cdr (call $pop)))\n(call $dig (i32.const 3))\n(call $dig (i32.const 2))\n(call $push (call $some (call $pop)))\n(call $dup (i32.const 4))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $drop (i32.const 1))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 2))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 3))\n(call $push (call $const (i32.const 2))) (; 1 ;)\n(call $dig (i32.const 4))\n(call $push (call $z_add (call $pop) (call $pop)))))\n(call $dig (i32.const 2))\n(call $dig (i32.const 3))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $push (call $pair (call $pop) (call $pop)))))) (else (call $dup (i32.const 1))\n(call $push (call $sender))\n(call $push (call $compare (call $pop) (call $pop)))\n(call $push (call $eq (call $pop)))\n(call $deref_bool (call $pop)) (if (then ) (else (call $push (call $const (i32.const 0))) (; \"failed assertion\" ;)\n(call $failwith (call $pop)) unreachable))\n(call $dig (i32.const 2))\n(call $push (call $none))\n(call $dup (i32.const 2))\n(call $push (call $cdr (call $pop)))\n(call $get_and_update (call $pop) (call $pop) (call $pop)) ;; implicit update\n(call $if_none (call $pop)) (if (then (call $drop (i32.const 5))\n(call $push (call $const (i32.const 1))) (; \"no tickets\" ;)\n(call $failwith (call $pop)) unreachable) (else (call $dig (i32.const 2))\n(call $push (call $car (call $pop)))\n(call $push (call $zero)) (; 0 ;)\n(call $dig (i32.const 2))\n(call $push (call $transfer_tokens (call $pop) (call $pop) (call $pop)))\n(call $dig (i32.const 4))\n(call $dig (i32.const 4))\n(call $dig (i32.const 3))\n(call $dig (i32.const 4))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))\n(call $push (call $nil))\n(call $dig (i32.const 2))\n(call $push (call $cons (call $pop) (call $pop)))\n(call $push (call $pair (call $pop) (call $pop)))))))\n (call $pop))\n\n (export \"push\" (func $push))\n (export \"pop\" (func $push))\n (export \"main\" (func $main))\n (export \"closures\" (table $closures))\n (export \"call_callback\" (func $call_callback))\n (export \"call_callback_unit\" (func $call_callback_unit))\n )\n", "constants": [ [ 0, [ "String", "failed assertion" ] ], [ 1, [ "String", "no tickets" ] ],