diff --git a/contracts/discovery-params.fc b/contracts/discovery-params.fc new file mode 100644 index 0000000..d4e3f8a --- /dev/null +++ b/contracts/discovery-params.fc @@ -0,0 +1,10 @@ +;; moved to the separate file to keep hex of the previous codes unchanged + +int op::provide_wallet_address() asm "0x2c76b973 PUSHINT"; +int op::take_wallet_address() asm "0xd1735400 PUSHINT"; + +int is_resolvable?(slice addr) inline { + (int wc, _) = parse_std_addr(addr); + + return wc == workchain(); +} diff --git a/contracts/imports/burn-token.fif b/contracts/imports/burn-token.fif new file mode 100644 index 0000000..8bd61ae --- /dev/null +++ b/contracts/imports/burn-token.fif @@ -0,0 +1,10 @@ +"Asm.fif" include +"TonUtil.fif" include +smca 2drop Addr, +b> +2 boc+>B + +"burn-token.boc" B>file + + diff --git a/contracts/imports/jetton-discovery.fif b/contracts/imports/jetton-discovery.fif new file mode 100644 index 0000000..ee85b39 --- /dev/null +++ b/contracts/imports/jetton-discovery.fif @@ -0,0 +1,172 @@ +"Asm.fif" include +// automatically generated from `../stdlib.fc` `params.fc` `op-codes.fc` `discovery-params.fc` `jetton-utils.fc` `jetton-discovery.fc` +PROGRAM{ + DECLPROC force_chain + DECLPROC is_resolvable? + DECLPROC pack_jetton_wallet_data + DECLPROC calculate_jetton_wallet_state_init + DECLPROC calculate_jetton_wallet_address + DECLPROC calculate_user_jetton_wallet_address + DECLPROC load_data + DECLPROC recv_internal + force_chain PROC:<{ + // addr + REWRITESTDADDR // _8 _9 + DROP // wc + 0 PUSHINT // wc _5 + EQUAL // _6 + 333 THROWIFNOT + }> + is_resolvable? PROCINLINE:<{ + // addr + REWRITESTDADDR // _6 _7 + DROP // wc + 0 PUSHINT // wc _4 + EQUAL // _5 + }> + pack_jetton_wallet_data PROCINLINE:<{ + // balance owner_address jetton_master_address jetton_wallet_code + NEWC // balance owner_address jetton_master_address jetton_wallet_code _4 + s0 s4 XCHG2 // jetton_wallet_code owner_address jetton_master_address _4 balance + STVARUINT16 // jetton_wallet_code owner_address jetton_master_address _5 + ROT // jetton_wallet_code jetton_master_address _5 owner_address + STSLICER // jetton_wallet_code jetton_master_address _6 + SWAP // jetton_wallet_code _6 jetton_master_address + STSLICER // jetton_wallet_code _7 + STREF // _8 + ENDC // _9 + }> + calculate_jetton_wallet_state_init PROCINLINE:<{ + // owner_address jetton_master_address jetton_wallet_code + 0 PUSHINT // owner_address jetton_master_address jetton_wallet_code _3=0 + s0 s1 s2 XCPUXC + s4 s0 s3 XC2PU // _3=0 jetton_wallet_code _4=0 owner_address jetton_master_address jetton_wallet_code + pack_jetton_wallet_data INLINECALLDICT // _3=0 jetton_wallet_code _5 + s2 PUSH // _3=0 jetton_wallet_code _5 _6=0 + NEWC // _3=0 jetton_wallet_code _5 _6=0 _7 + 2 STU // _3=0 jetton_wallet_code _5 _9 + s1 s2 XCHG // _3=0 _5 jetton_wallet_code _9 + STDICT // _3=0 _5 _10 + STDICT // _3=0 _11 + 1 STU // _13 + ENDC // _14 + }> + calculate_jetton_wallet_address PROCINLINE:<{ + // state_init + HASHCU // _1 + 0 PUSHINT // _1 _2 + 4 PUSHINT // _1 _2 _3=4 + NEWC // _1 _2 _3=4 _4 + 3 STU // _1 _2 _6 + 8 STI // _1 _8 + 256 STU // _10 + ENDC // _11 + CTOS // _12 + }> + calculate_user_jetton_wallet_address PROCINLINE:<{ + // owner_address jetton_master_address jetton_wallet_code + calculate_jetton_wallet_state_init INLINECALLDICT // _3 + calculate_jetton_wallet_address INLINECALLDICT // _4 + }> + load_data PROCINLINE:<{ + // + c4 PUSH // _1 + CTOS // ds + LDMSGADDR // _3 ds + LDREF // _3 _10 _9 + DROP // _3 _5 + }> + recv_internal PROC:<{ + // msg_value in_msg_full in_msg_body + DUP // msg_value in_msg_full in_msg_body in_msg_body + SEMPTY // msg_value in_msg_full in_msg_body _3 + IFJMP:<{ // msg_value in_msg_full in_msg_body + 3 BLKDROP // + }> // msg_value in_msg_full in_msg_body + SWAP // msg_value in_msg_body in_msg_full + CTOS // msg_value in_msg_body cs + 4 LDU // msg_value in_msg_body flags cs + SWAP + 1 PUSHINT // msg_value in_msg_body cs flags _10=1 + AND // msg_value in_msg_body cs _11 + IFJMP:<{ // msg_value in_msg_body cs + 3 BLKDROP // + }> // msg_value in_msg_body cs + LDMSGADDR // msg_value in_msg_body sender_address cs + LDMSGADDR // msg_value in_msg_body sender_address _106 _105 + NIP // msg_value in_msg_body sender_address cs + LDVARUINT16 // msg_value in_msg_body sender_address _108 _107 + NIP // msg_value in_msg_body sender_address cs + 1 PUSHINT // msg_value in_msg_body sender_address cs _20=1 + SDSKIPFIRST // msg_value in_msg_body sender_address cs + LDVARUINT16 // msg_value in_msg_body sender_address _110 _109 + NIP // msg_value in_msg_body sender_address cs + LDVARUINT16 // msg_value in_msg_body sender_address _112 _111 + DROP // msg_value in_msg_body sender_address _25 + 3 PUSHINT // msg_value in_msg_body sender_address _25 _27=3 + 1 MULRSHIFT# // msg_value in_msg_body sender_address fwd_fee + s0 s2 XCHG // msg_value fwd_fee sender_address in_msg_body + 32 LDU // msg_value fwd_fee sender_address op in_msg_body + 64 LDU // msg_value fwd_fee sender_address op query_id in_msg_body + 0x2c76b973 PUSHINT // msg_value fwd_fee sender_address op query_id in_msg_body _38 + s1 s3 XCHG // msg_value fwd_fee sender_address in_msg_body query_id op _38 + EQUAL // msg_value fwd_fee sender_address in_msg_body query_id _39 + IFJMP:<{ // msg_value fwd_fee sender_address in_msg_body query_id + 10000000 PUSHINT // msg_value fwd_fee sender_address in_msg_body query_id _41 + s1 s4 XCHG // msg_value query_id sender_address in_msg_body fwd_fee _41 + ADD // msg_value query_id sender_address in_msg_body _42 + s1 s4 XCHG // in_msg_body query_id sender_address msg_value _42 + GREATER // in_msg_body query_id sender_address _43 + 75 THROWIFNOT + load_data INLINECALLDICT // in_msg_body query_id sender_address jetton_minter_address jetton_wallet_code + s0 s4 XCHG // jetton_wallet_code query_id sender_address jetton_minter_address in_msg_body + LDMSGADDR // jetton_wallet_code query_id sender_address jetton_minter_address owner_address in_msg_body + 1 LDU // jetton_wallet_code query_id sender_address jetton_minter_address owner_address _122 _121 + DROP // jetton_wallet_code query_id sender_address jetton_minter_address owner_address include_address? + IF:<{ // jetton_wallet_code query_id sender_address jetton_minter_address owner_address + NEWC // jetton_wallet_code query_id sender_address jetton_minter_address owner_address _57 + OVER // jetton_wallet_code query_id sender_address jetton_minter_address owner_address _57 owner_address + STSLICER // jetton_wallet_code query_id sender_address jetton_minter_address owner_address _58 + ENDC // jetton_wallet_code query_id sender_address jetton_minter_address owner_address _56 + }>ELSE<{ // jetton_wallet_code query_id sender_address jetton_minter_address owner_address + PUSHNULL // jetton_wallet_code query_id sender_address jetton_minter_address owner_address _56 + }> // jetton_wallet_code query_id sender_address jetton_minter_address owner_address included_address + 0xd1735400 PUSHINT // jetton_wallet_code query_id sender_address jetton_minter_address owner_address included_address _62 + 0 PUSHINT // jetton_wallet_code query_id sender_address jetton_minter_address owner_address included_address _62 _63=0 + 24 PUSHINT // jetton_wallet_code query_id sender_address jetton_minter_address owner_address included_address _62 _63=0 _64=24 + NEWC // jetton_wallet_code query_id sender_address jetton_minter_address owner_address included_address _62 _63=0 _64=24 _65 + 6 STU // jetton_wallet_code query_id sender_address jetton_minter_address owner_address included_address _62 _63=0 _67 + s0 s6 XCHG2 // jetton_wallet_code query_id _63=0 jetton_minter_address owner_address included_address _62 _67 sender_address + STSLICER // jetton_wallet_code query_id _63=0 jetton_minter_address owner_address included_address _62 _68 + s5 PUSH // jetton_wallet_code query_id _63=0 jetton_minter_address owner_address included_address _62 _68 _69=0 + STVARUINT16 // jetton_wallet_code query_id _63=0 jetton_minter_address owner_address included_address _62 _70 + s1 s5 XCHG // jetton_wallet_code query_id _62 jetton_minter_address owner_address included_address _63=0 _70 + 107 STU // jetton_wallet_code query_id _62 jetton_minter_address owner_address included_address _84 + s1 s4 XCHG // jetton_wallet_code query_id included_address jetton_minter_address owner_address _62 _84 + 32 STU // jetton_wallet_code query_id included_address jetton_minter_address owner_address _86 + s1 s4 XCHG // jetton_wallet_code owner_address included_address jetton_minter_address query_id _86 + 64 STU // jetton_wallet_code owner_address included_address jetton_minter_address msg + s3 PUSH // jetton_wallet_code owner_address included_address jetton_minter_address msg owner_address + is_resolvable? INLINECALLDICT // jetton_wallet_code owner_address included_address jetton_minter_address msg _89 + IF:<{ // jetton_wallet_code owner_address included_address jetton_minter_address msg + s3 s1 s4 XCHG3 // msg included_address owner_address jetton_minter_address jetton_wallet_code + calculate_user_jetton_wallet_address INLINECALLDICT // msg included_address _90 + s1 s2 XCHG // included_address msg _90 + STSLICER // included_address msg + }>ELSE<{ // jetton_wallet_code owner_address included_address jetton_minter_address msg + NIP + 2 2 BLKDROP2 // included_address msg + 0 PUSHINT // included_address msg _92=0 + SWAP // included_address _92=0 msg + 2 STU // included_address msg + }> + STOPTREF // _95 + ENDC // _96 + 64 PUSHINT // _96 _97=64 + SENDRAWMSG + }> // msg_value fwd_fee sender_address in_msg_body query_id + 5 BLKDROP // + 16 PUSHPOW2DEC // _99=65535 + THROWANY + }> +}END>c diff --git a/contracts/imports/jetton-minter-ICO.fif b/contracts/imports/jetton-minter-ICO.fif new file mode 100644 index 0000000..1a5f22b --- /dev/null +++ b/contracts/imports/jetton-minter-ICO.fif @@ -0,0 +1,256 @@ +"Asm.fif" include +// automatically generated from `imports/stdlib.fc` `params.fc` `op-codes.fc` `jetton-utils.fc` `jetton-minter-ICO.fc` +PROGRAM{ + DECLPROC force_chain + DECLPROC pack_jetton_wallet_data + DECLPROC calculate_jetton_wallet_state_init + DECLPROC calculate_jetton_wallet_address + DECLPROC calculate_user_jetton_wallet_address + DECLPROC load_data + DECLPROC save_data + DECLPROC mint_tokens + DECLPROC recv_internal + 106029 DECLMETHOD get_jetton_data + 103289 DECLMETHOD get_wallet_address + force_chain PROC:<{ + // addr + REWRITESTDADDR // _8 _9 + DROP // wc + 0 PUSHINT // wc _5 + EQUAL // _6 + 333 THROWIFNOT + }> + pack_jetton_wallet_data PROCINLINE:<{ + // balance owner_address jetton_master_address jetton_wallet_code + NEWC // balance owner_address jetton_master_address jetton_wallet_code _4 + s0 s4 XCHG2 // jetton_wallet_code owner_address jetton_master_address _4 balance + STVARUINT16 // jetton_wallet_code owner_address jetton_master_address _5 + ROT // jetton_wallet_code jetton_master_address _5 owner_address + STSLICER // jetton_wallet_code jetton_master_address _6 + SWAP // jetton_wallet_code _6 jetton_master_address + STSLICER // jetton_wallet_code _7 + STREF // _8 + ENDC // _9 + }> + calculate_jetton_wallet_state_init PROCINLINE:<{ + // owner_address jetton_master_address jetton_wallet_code + 0 PUSHINT // owner_address jetton_master_address jetton_wallet_code _3=0 + s0 s1 s2 XCPUXC + s4 s0 s3 XC2PU // _3=0 jetton_wallet_code _4=0 owner_address jetton_master_address jetton_wallet_code + pack_jetton_wallet_data INLINECALLDICT // _3=0 jetton_wallet_code _5 + s2 PUSH // _3=0 jetton_wallet_code _5 _6=0 + NEWC // _3=0 jetton_wallet_code _5 _6=0 _7 + 2 STU // _3=0 jetton_wallet_code _5 _9 + s1 s2 XCHG // _3=0 _5 jetton_wallet_code _9 + STDICT // _3=0 _5 _10 + STDICT // _3=0 _11 + 1 STU // _13 + ENDC // _14 + }> + calculate_jetton_wallet_address PROCINLINE:<{ + // state_init + HASHCU // _1 + 0 PUSHINT // _1 _2 + 4 PUSHINT // _1 _2 _3=4 + NEWC // _1 _2 _3=4 _4 + 3 STU // _1 _2 _6 + 8 STI // _1 _8 + 256 STU // _10 + ENDC // _11 + CTOS // _12 + }> + calculate_user_jetton_wallet_address PROCINLINE:<{ + // owner_address jetton_master_address jetton_wallet_code + calculate_jetton_wallet_state_init INLINECALLDICT // _3 + calculate_jetton_wallet_address INLINECALLDICT // _4 + }> + load_data PROCINLINE:<{ + // + c4 PUSH // _1 + CTOS // ds + LDVARUINT16 // _3 ds + LDMSGADDR // _3 _5 ds + LDREF // _3 _5 _7 ds + LDREF // _3 _5 _7 _18 _17 + DROP // _3 _5 _7 _9 + }> + save_data PROCINLINE:<{ + // total_supply admin_address content jetton_wallet_code + NEWC // total_supply admin_address content jetton_wallet_code _4 + s0 s4 XCHG2 // jetton_wallet_code admin_address content _4 total_supply + STVARUINT16 // jetton_wallet_code admin_address content _5 + ROT // jetton_wallet_code content _5 admin_address + STSLICER // jetton_wallet_code content _6 + STREF // jetton_wallet_code _7 + STREF // _8 + ENDC // _9 + c4 POP + }> + mint_tokens PROC:<{ + // to_address jetton_wallet_code amount master_msg + MYADDR // to_address jetton_wallet_code amount master_msg _5 + s4 s0 s3 XCHG3 // amount master_msg to_address _5 jetton_wallet_code + calculate_jetton_wallet_state_init INLINECALLDICT // amount master_msg state_init + DUP // amount master_msg state_init state_init + calculate_jetton_wallet_address INLINECALLDICT // amount master_msg state_init to_wallet_address + 7 PUSHINT // amount master_msg state_init to_wallet_address _14 + 24 PUSHINT // amount master_msg state_init to_wallet_address _14 _15=24 + NEWC // amount master_msg state_init to_wallet_address _14 _15=24 _16 + 6 STU // amount master_msg state_init to_wallet_address _14 _18 + ROT // amount master_msg state_init _14 _18 to_wallet_address + STSLICER // amount master_msg state_init _14 _19 + s0 s4 XCHG2 // _14 master_msg state_init _19 amount + STVARUINT16 // _14 master_msg state_init _20 + s1 s3 XCHG // state_init master_msg _14 _20 + 108 STU // state_init master_msg _36 + s1 s2 XCHG // master_msg state_init _36 + STREF // master_msg _37 + STREF // msg + ENDC // _39 + 1 PUSHINT // _39 _40=1 + SENDRAWMSG + }> + recv_internal PROC:<{ + // msg_value in_msg_full in_msg_body + SWAP // msg_value in_msg_body in_msg_full + CTOS // msg_value in_msg_body cs + 4 LDU // msg_value in_msg_body flags cs + SWAP + 1 PUSHINT // msg_value in_msg_body cs flags _9=1 + AND // msg_value in_msg_body cs _10 + IFJMP:<{ // msg_value in_msg_body cs + 3 BLKDROP // + }> // msg_value in_msg_body cs + LDMSGADDR // msg_value in_msg_body _145 _144 + DROP // msg_value in_msg_body sender_address + load_data INLINECALLDICT // msg_value in_msg_body sender_address total_supply admin_address content jetton_wallet_code + s5 PUSH // msg_value in_msg_body sender_address total_supply admin_address content jetton_wallet_code in_msg_body + SEMPTY // msg_value in_msg_body sender_address total_supply admin_address content jetton_wallet_code _19 + IFJMP:<{ // msg_value in_msg_body sender_address total_supply admin_address content jetton_wallet_code + s5 POP // msg_value jetton_wallet_code sender_address total_supply admin_address content + 10000000 PUSHINT // msg_value jetton_wallet_code sender_address total_supply admin_address content amount=10000000 + s6 s6 XCPU // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content msg_value amount=10000000 + SUB // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content buy_amount + DUP // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content buy_amount buy_amount + 0 GTINT // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content buy_amount _26 + 76 THROWIFNOT // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount + 0 PUSHINT // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 + DUP // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _31=0 + 0x178d4519 PUSHINT // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _31=0 _32 + NEWC // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _31=0 _32 _33 + 32 STU // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _31=0 _35 + 64 STU // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _37 + s2 PUSH // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _37 jetton_amount + STVARUINT16 // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _38 + MYADDR // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _38 _39 + STSLICER // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _40 + s6 PUSH // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _40 sender_address + STSLICER // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _41 + OVER // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _41 _42=0 + STVARUINT16 // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _30=0 _43 + 1 STU // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount _45 + ENDC // amount=10000000 jetton_wallet_code sender_address total_supply admin_address content jetton_amount master_msg + s6 PUSH + s3 s6 XCHG + s0 s8 s8 XCHG3 // jetton_amount jetton_wallet_code content total_supply admin_address sender_address jetton_wallet_code amount=10000000 master_msg + mint_tokens CALLDICT + s0 s4 XCHG // admin_address jetton_wallet_code content total_supply jetton_amount + ADD // admin_address jetton_wallet_code content _48 + s3 s1 s3 XCHG3 // _48 admin_address content jetton_wallet_code + save_data INLINECALLDICT + }> // msg_value in_msg_body sender_address total_supply admin_address content jetton_wallet_code + s6 POP // jetton_wallet_code in_msg_body sender_address total_supply admin_address content + s0 s4 XCHG // jetton_wallet_code content sender_address total_supply admin_address in_msg_body + 32 LDU // jetton_wallet_code content sender_address total_supply admin_address op in_msg_body + 64 LDU // jetton_wallet_code content sender_address total_supply admin_address op query_id in_msg_body + 21 PUSHINT // jetton_wallet_code content sender_address total_supply admin_address op query_id in_msg_body _58 + s3 s(-1) PUXC // jetton_wallet_code content sender_address total_supply admin_address op query_id in_msg_body op _58 + EQUAL // jetton_wallet_code content sender_address total_supply admin_address op query_id in_msg_body _59 + IFJMP:<{ // jetton_wallet_code content sender_address total_supply admin_address op query_id in_msg_body + 2 1 BLKDROP2 // jetton_wallet_code content sender_address total_supply admin_address in_msg_body + s3 s1 XCPU // jetton_wallet_code content in_msg_body total_supply admin_address sender_address admin_address + SDEQ // jetton_wallet_code content in_msg_body total_supply admin_address _61 + 73 THROWIFNOT + s0 s2 XCHG // jetton_wallet_code content admin_address total_supply in_msg_body + LDMSGADDR // jetton_wallet_code content admin_address total_supply to_address in_msg_body + LDVARUINT16 // jetton_wallet_code content admin_address total_supply to_address amount in_msg_body + LDREF // jetton_wallet_code content admin_address total_supply to_address amount _159 _158 + DROP // jetton_wallet_code content admin_address total_supply to_address amount master_msg + DUP // jetton_wallet_code content admin_address total_supply to_address amount master_msg master_msg + CTOS // jetton_wallet_code content admin_address total_supply to_address amount master_msg master_msg_cs + 96 PUSHINT // jetton_wallet_code content admin_address total_supply to_address amount master_msg master_msg_cs _77 + SDSKIPFIRST // jetton_wallet_code content admin_address total_supply to_address amount master_msg master_msg_cs + LDVARUINT16 // jetton_wallet_code content admin_address total_supply to_address amount master_msg _161 _160 + DROP // jetton_wallet_code content admin_address total_supply to_address amount master_msg jetton_amount + s7 PUSH + s3 s4 XCHG + s4 s2 XCHG2 // jetton_wallet_code content admin_address total_supply jetton_amount to_address jetton_wallet_code amount master_msg + mint_tokens CALLDICT + ADD // jetton_wallet_code content admin_address _83 + s2 s3 XCHG2 // _83 admin_address content jetton_wallet_code + save_data INLINECALLDICT + }> // jetton_wallet_code content sender_address total_supply admin_address op query_id in_msg_body + 0x7bdd97de PUSHINT // jetton_wallet_code content sender_address total_supply admin_address op query_id in_msg_body _85 + s1 s3 XCHG // jetton_wallet_code content sender_address total_supply admin_address in_msg_body query_id op _85 + EQUAL // jetton_wallet_code content sender_address total_supply admin_address in_msg_body query_id _86 + IFJMP:<{ // jetton_wallet_code content sender_address total_supply admin_address in_msg_body query_id + SWAP // jetton_wallet_code content sender_address total_supply admin_address query_id in_msg_body + LDVARUINT16 // jetton_wallet_code content sender_address total_supply admin_address query_id jetton_amount in_msg_body + LDMSGADDR // jetton_wallet_code content sender_address total_supply admin_address query_id jetton_amount from_address in_msg_body + MYADDR // jetton_wallet_code content sender_address total_supply admin_address query_id jetton_amount from_address in_msg_body _94 + s2 s0 s9 XC2PU // jetton_wallet_code content sender_address total_supply admin_address query_id jetton_amount in_msg_body from_address _94 jetton_wallet_code + calculate_user_jetton_wallet_address INLINECALLDICT // jetton_wallet_code content sender_address total_supply admin_address query_id jetton_amount in_msg_body _95 + s0 s6 XCHG2 // jetton_wallet_code content in_msg_body total_supply admin_address query_id jetton_amount _95 sender_address + SDEQ // jetton_wallet_code content in_msg_body total_supply admin_address query_id jetton_amount _96 + 74 THROWIFNOT + s1 s3 XCHG // jetton_wallet_code content in_msg_body query_id admin_address total_supply jetton_amount + SUB // jetton_wallet_code content in_msg_body query_id admin_address _98 + s0 s3 XCHG + s1 s4 s5 XCHG3 // in_msg_body query_id _98 admin_address content jetton_wallet_code + save_data INLINECALLDICT + SWAP // query_id in_msg_body + LDMSGADDR // query_id _167 _166 + DROP // query_id response_address + DUP // query_id response_address response_address + 2 PLDU // query_id response_address _104 + 0 NEQINT // query_id response_address _106 + IF:<{ // query_id response_address + 0xd53276db PUSHINT // query_id response_address _108 + 0 PUSHINT // query_id response_address _108 _109=0 + 16 PUSHINT // query_id response_address _108 _109=0 _110=16 + NEWC // query_id response_address _108 _109=0 _110=16 _111 + 6 STU // query_id response_address _108 _109=0 _113 + s0 s3 XCHG2 // query_id _109=0 _108 _113 response_address + STSLICER // query_id _109=0 _108 _114 + s2 PUSH // query_id _109=0 _108 _114 _115=0 + STVARUINT16 // query_id _109=0 _108 _116 + s1 s2 XCHG // query_id _108 _109=0 _116 + 107 STU // query_id _108 _130 + 32 STU // query_id _132 + 64 STU // msg + ENDC // _135 + 66 PUSHINT // _135 _138 + SENDRAWMSG + }>ELSE<{ + 2DROP // + }> + }> // jetton_wallet_code content sender_address total_supply admin_address in_msg_body query_id + 7 BLKDROP // + 16 PUSHPOW2DEC // _140=65535 + THROWANY + }> + get_jetton_data PROC:<{ + // + load_data INLINECALLDICT // total_supply admin_address content jetton_wallet_code + -1 PUSHINT // total_supply admin_address content jetton_wallet_code _5=-1 + 3 -ROLL // total_supply _5=-1 admin_address content jetton_wallet_code + }> + get_wallet_address PROC:<{ + // owner_address + load_data INLINECALLDICT // owner_address _8 _9 _10 _11 + 3 1 BLKDROP2 // owner_address jetton_wallet_code + MYADDR // owner_address jetton_wallet_code _6 + SWAP // owner_address _6 jetton_wallet_code + calculate_user_jetton_wallet_address INLINECALLDICT // _7 + }> +}END>c diff --git a/contracts/imports/jetton-minter-discoverable.fif b/contracts/imports/jetton-minter-discoverable.fif new file mode 100644 index 0000000..9979ee7 --- /dev/null +++ b/contracts/imports/jetton-minter-discoverable.fif @@ -0,0 +1,335 @@ +"Asm.fif" include +// automatically generated from `imports/stdlib.fc` `params.fc` `op-codes.fc` `discovery-params.fc` `jetton-utils.fc` `jetton-minter-discoverable.fc` +PROGRAM{ + DECLPROC force_chain + DECLPROC is_resolvable? + DECLPROC pack_jetton_wallet_data + DECLPROC calculate_jetton_wallet_state_init + DECLPROC calculate_jetton_wallet_address + DECLPROC calculate_user_jetton_wallet_address + DECLPROC load_data + DECLPROC save_data + DECLPROC mint_tokens + DECLPROC recv_internal + 106029 DECLMETHOD get_jetton_data + 103289 DECLMETHOD get_wallet_address + force_chain PROC:<{ + // addr + REWRITESTDADDR // _8 _9 + DROP // wc + 0 PUSHINT // wc _5 + EQUAL // _6 + 333 THROWIFNOT + }> + is_resolvable? PROCINLINE:<{ + // addr + REWRITESTDADDR // _6 _7 + DROP // wc + 0 PUSHINT // wc _4 + EQUAL // _5 + }> + pack_jetton_wallet_data PROCINLINE:<{ + // balance owner_address jetton_master_address jetton_wallet_code + NEWC // balance owner_address jetton_master_address jetton_wallet_code _4 + s0 s4 XCHG2 // jetton_wallet_code owner_address jetton_master_address _4 balance + STVARUINT16 // jetton_wallet_code owner_address jetton_master_address _5 + ROT // jetton_wallet_code jetton_master_address _5 owner_address + STSLICER // jetton_wallet_code jetton_master_address _6 + SWAP // jetton_wallet_code _6 jetton_master_address + STSLICER // jetton_wallet_code _7 + STREF // _8 + ENDC // _9 + }> + calculate_jetton_wallet_state_init PROCINLINE:<{ + // owner_address jetton_master_address jetton_wallet_code + 0 PUSHINT // owner_address jetton_master_address jetton_wallet_code _3=0 + s0 s1 s2 XCPUXC + s4 s0 s3 XC2PU // _3=0 jetton_wallet_code _4=0 owner_address jetton_master_address jetton_wallet_code + pack_jetton_wallet_data INLINECALLDICT // _3=0 jetton_wallet_code _5 + s2 PUSH // _3=0 jetton_wallet_code _5 _6=0 + NEWC // _3=0 jetton_wallet_code _5 _6=0 _7 + 2 STU // _3=0 jetton_wallet_code _5 _9 + s1 s2 XCHG // _3=0 _5 jetton_wallet_code _9 + STDICT // _3=0 _5 _10 + STDICT // _3=0 _11 + 1 STU // _13 + ENDC // _14 + }> + calculate_jetton_wallet_address PROCINLINE:<{ + // state_init + HASHCU // _1 + 0 PUSHINT // _1 _2 + 4 PUSHINT // _1 _2 _3=4 + NEWC // _1 _2 _3=4 _4 + 3 STU // _1 _2 _6 + 8 STI // _1 _8 + 256 STU // _10 + ENDC // _11 + CTOS // _12 + }> + calculate_user_jetton_wallet_address PROCINLINE:<{ + // owner_address jetton_master_address jetton_wallet_code + calculate_jetton_wallet_state_init INLINECALLDICT // _3 + calculate_jetton_wallet_address INLINECALLDICT // _4 + }> + load_data PROCINLINE:<{ + // + c4 PUSH // _1 + CTOS // ds + LDVARUINT16 // _3 ds + LDMSGADDR // _3 _5 ds + LDREF // _3 _5 _7 ds + LDREF // _3 _5 _7 _18 _17 + DROP // _3 _5 _7 _9 + }> + save_data PROCINLINE:<{ + // total_supply admin_address content jetton_wallet_code + NEWC // total_supply admin_address content jetton_wallet_code _4 + s0 s4 XCHG2 // jetton_wallet_code admin_address content _4 total_supply + STVARUINT16 // jetton_wallet_code admin_address content _5 + ROT // jetton_wallet_code content _5 admin_address + STSLICER // jetton_wallet_code content _6 + STREF // jetton_wallet_code _7 + STREF // _8 + ENDC // _9 + c4 POP + }> + mint_tokens PROC:<{ + // to_address jetton_wallet_code amount master_msg + MYADDR // to_address jetton_wallet_code amount master_msg _5 + s4 s0 s3 XCHG3 // amount master_msg to_address _5 jetton_wallet_code + calculate_jetton_wallet_state_init INLINECALLDICT // amount master_msg state_init + DUP // amount master_msg state_init state_init + calculate_jetton_wallet_address INLINECALLDICT // amount master_msg state_init to_wallet_address + 7 PUSHINT // amount master_msg state_init to_wallet_address _14 + 24 PUSHINT // amount master_msg state_init to_wallet_address _14 _15=24 + NEWC // amount master_msg state_init to_wallet_address _14 _15=24 _16 + 6 STU // amount master_msg state_init to_wallet_address _14 _18 + ROT // amount master_msg state_init _14 _18 to_wallet_address + STSLICER // amount master_msg state_init _14 _19 + s0 s4 XCHG2 // _14 master_msg state_init _19 amount + STVARUINT16 // _14 master_msg state_init _20 + s1 s3 XCHG // state_init master_msg _14 _20 + 108 STU // state_init master_msg _36 + s1 s2 XCHG // master_msg state_init _36 + STREF // master_msg _37 + STREF // msg + ENDC // _39 + 1 PUSHINT // _39 _40=1 + SENDRAWMSG + }> + recv_internal PROC:<{ + // msg_value in_msg_full in_msg_body + DUP // msg_value in_msg_full in_msg_body in_msg_body + SEMPTY // msg_value in_msg_full in_msg_body _3 + IFJMP:<{ // msg_value in_msg_full in_msg_body + 3 BLKDROP // + }> // msg_value in_msg_full in_msg_body + SWAP // msg_value in_msg_body in_msg_full + CTOS // msg_value in_msg_body cs + 4 LDU // msg_value in_msg_body flags cs + SWAP + 1 PUSHINT // msg_value in_msg_body cs flags _10=1 + AND // msg_value in_msg_body cs _11 + IFJMP:<{ // msg_value in_msg_body cs + 3 BLKDROP // + }> // msg_value in_msg_body cs + LDMSGADDR // msg_value in_msg_body sender_address cs + LDMSGADDR // msg_value in_msg_body sender_address _208 _207 + NIP // msg_value in_msg_body sender_address cs + LDVARUINT16 // msg_value in_msg_body sender_address _210 _209 + NIP // msg_value in_msg_body sender_address cs + 1 PUSHINT // msg_value in_msg_body sender_address cs _20=1 + SDSKIPFIRST // msg_value in_msg_body sender_address cs + LDVARUINT16 // msg_value in_msg_body sender_address _212 _211 + NIP // msg_value in_msg_body sender_address cs + LDVARUINT16 // msg_value in_msg_body sender_address _214 _213 + DROP // msg_value in_msg_body sender_address _25 + 3 PUSHINT // msg_value in_msg_body sender_address _25 _27=3 + 1 MULRSHIFT# // msg_value in_msg_body sender_address fwd_fee + s0 s2 XCHG // msg_value fwd_fee sender_address in_msg_body + 32 LDU // msg_value fwd_fee sender_address op in_msg_body + 64 LDU // msg_value fwd_fee sender_address op query_id in_msg_body + load_data INLINECALLDICT // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code + 21 PUSHINT // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code _43 + s7 s(-1) PUXC // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code op _43 + EQUAL // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code _44 + IFJMP:<{ // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code + s5 POP + s5 POP + s6 POP + s6 POP // total_supply admin_address sender_address content jetton_wallet_code in_msg_body + s3 s4 XCPU // total_supply admin_address in_msg_body content jetton_wallet_code sender_address admin_address + SDEQ // total_supply admin_address in_msg_body content jetton_wallet_code _46 + 73 THROWIFNOT + s0 s2 XCHG // total_supply admin_address jetton_wallet_code content in_msg_body + LDMSGADDR // total_supply admin_address jetton_wallet_code content to_address in_msg_body + LDVARUINT16 // total_supply admin_address jetton_wallet_code content to_address amount in_msg_body + LDREF // total_supply admin_address jetton_wallet_code content to_address amount _228 _227 + DROP // total_supply admin_address jetton_wallet_code content to_address amount master_msg + DUP // total_supply admin_address jetton_wallet_code content to_address amount master_msg master_msg + CTOS // total_supply admin_address jetton_wallet_code content to_address amount master_msg master_msg_cs + 96 PUSHINT // total_supply admin_address jetton_wallet_code content to_address amount master_msg master_msg_cs _62 + SDSKIPFIRST // total_supply admin_address jetton_wallet_code content to_address amount master_msg master_msg_cs + LDVARUINT16 // total_supply admin_address jetton_wallet_code content to_address amount master_msg _230 _229 + DROP // total_supply admin_address jetton_wallet_code content to_address amount master_msg jetton_amount + s5 PUSH + s3 s4 XCHG + s4 s2 XCHG2 // total_supply admin_address jetton_wallet_code content jetton_amount to_address jetton_wallet_code amount master_msg + mint_tokens CALLDICT + s1 s4 XCHG // content admin_address jetton_wallet_code total_supply jetton_amount + ADD // content admin_address jetton_wallet_code _68 + s3 s3 XCHG2 // _68 admin_address content jetton_wallet_code + save_data INLINECALLDICT + }> // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code + 0x7bdd97de PUSHINT // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code _70 + s7 s(-1) PUXC // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code op _70 + EQUAL // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code _71 + IFJMP:<{ // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code + s6 POP + s7 POP + s7 POP // admin_address content sender_address jetton_wallet_code query_id in_msg_body total_supply + SWAP // admin_address content sender_address jetton_wallet_code query_id total_supply in_msg_body + LDVARUINT16 // admin_address content sender_address jetton_wallet_code query_id total_supply jetton_amount in_msg_body + LDMSGADDR // admin_address content sender_address jetton_wallet_code query_id total_supply jetton_amount from_address in_msg_body + MYADDR // admin_address content sender_address jetton_wallet_code query_id total_supply jetton_amount from_address in_msg_body _79 + s2 s0 s6 XC2PU // admin_address content sender_address jetton_wallet_code query_id total_supply jetton_amount in_msg_body from_address _79 jetton_wallet_code + calculate_user_jetton_wallet_address INLINECALLDICT // admin_address content sender_address jetton_wallet_code query_id total_supply jetton_amount in_msg_body _80 + s0 s6 XCHG2 // admin_address content in_msg_body jetton_wallet_code query_id total_supply jetton_amount _80 sender_address + SDEQ // admin_address content in_msg_body jetton_wallet_code query_id total_supply jetton_amount _81 + 74 THROWIFNOT + SUB // admin_address content in_msg_body jetton_wallet_code query_id _83 + s0 s3 XCHG + s5 s4 s5 XCHG3 // in_msg_body query_id _83 admin_address content jetton_wallet_code + save_data INLINECALLDICT + SWAP // query_id in_msg_body + LDMSGADDR // query_id _236 _235 + DROP // query_id response_address + DUP // query_id response_address response_address + 2 PLDU // query_id response_address _89 + 0 NEQINT // query_id response_address _91 + IF:<{ // query_id response_address + 0xd53276db PUSHINT // query_id response_address _93 + 0 PUSHINT // query_id response_address _93 _94=0 + 16 PUSHINT // query_id response_address _93 _94=0 _95=16 + NEWC // query_id response_address _93 _94=0 _95=16 _96 + 6 STU // query_id response_address _93 _94=0 _98 + s0 s3 XCHG2 // query_id _94=0 _93 _98 response_address + STSLICER // query_id _94=0 _93 _99 + s2 PUSH // query_id _94=0 _93 _99 _100=0 + STVARUINT16 // query_id _94=0 _93 _101 + s1 s2 XCHG // query_id _93 _94=0 _101 + 107 STU // query_id _93 _115 + 32 STU // query_id _117 + 64 STU // msg + ENDC // _120 + 66 PUSHINT // _120 _123 + SENDRAWMSG + }>ELSE<{ + 2DROP // + }> + }> // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code + 0x2c76b973 PUSHINT // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code _125 + s7 s(-1) PUXC // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code op _125 + EQUAL // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code _126 + IFJMP:<{ // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code + s6 POP + 3 BLKDROP // msg_value fwd_fee sender_address jetton_wallet_code query_id in_msg_body + 10000000 PUSHINT // msg_value fwd_fee sender_address jetton_wallet_code query_id in_msg_body _128 + s1 s5 XCHG // msg_value in_msg_body sender_address jetton_wallet_code query_id fwd_fee _128 + ADD // msg_value in_msg_body sender_address jetton_wallet_code query_id _129 + s1 s5 XCHG // query_id in_msg_body sender_address jetton_wallet_code msg_value _129 + GREATER // query_id in_msg_body sender_address jetton_wallet_code _130 + 75 THROWIFNOT + s0 s2 XCHG // query_id jetton_wallet_code sender_address in_msg_body + LDMSGADDR // query_id jetton_wallet_code sender_address owner_address in_msg_body + 1 LDU // query_id jetton_wallet_code sender_address owner_address _240 _239 + DROP // query_id jetton_wallet_code sender_address owner_address include_address? + IF:<{ // query_id jetton_wallet_code sender_address owner_address + NEWC // query_id jetton_wallet_code sender_address owner_address _141 + OVER // query_id jetton_wallet_code sender_address owner_address _141 owner_address + STSLICER // query_id jetton_wallet_code sender_address owner_address _142 + ENDC // query_id jetton_wallet_code sender_address owner_address _140 + }>ELSE<{ // query_id jetton_wallet_code sender_address owner_address + PUSHNULL // query_id jetton_wallet_code sender_address owner_address _140 + }> // query_id jetton_wallet_code sender_address owner_address included_address + 0xd1735400 PUSHINT // query_id jetton_wallet_code sender_address owner_address included_address _146 + 0 PUSHINT // query_id jetton_wallet_code sender_address owner_address included_address _146 _147=0 + 24 PUSHINT // query_id jetton_wallet_code sender_address owner_address included_address _146 _147=0 _148=24 + NEWC // query_id jetton_wallet_code sender_address owner_address included_address _146 _147=0 _148=24 _149 + 6 STU // query_id jetton_wallet_code sender_address owner_address included_address _146 _147=0 _151 + s0 s5 XCHG2 // query_id jetton_wallet_code _147=0 owner_address included_address _146 _151 sender_address + STSLICER // query_id jetton_wallet_code _147=0 owner_address included_address _146 _152 + s4 PUSH // query_id jetton_wallet_code _147=0 owner_address included_address _146 _152 _153=0 + STVARUINT16 // query_id jetton_wallet_code _147=0 owner_address included_address _146 _154 + s1 s4 XCHG // query_id jetton_wallet_code _146 owner_address included_address _147=0 _154 + 107 STU // query_id jetton_wallet_code _146 owner_address included_address _168 + s1 s3 XCHG // query_id jetton_wallet_code included_address owner_address _146 _168 + 32 STU // query_id jetton_wallet_code included_address owner_address _170 + s1 s4 XCHG // owner_address jetton_wallet_code included_address query_id _170 + 64 STU // owner_address jetton_wallet_code included_address msg + s3 PUSH // owner_address jetton_wallet_code included_address msg owner_address + is_resolvable? INLINECALLDICT // owner_address jetton_wallet_code included_address msg _173 + IF:<{ // owner_address jetton_wallet_code included_address msg + MYADDR // owner_address jetton_wallet_code included_address msg _174 + s4 s0 s3 XCHG3 // included_address msg owner_address _174 jetton_wallet_code + calculate_user_jetton_wallet_address INLINECALLDICT // included_address msg _175 + STSLICER // included_address msg + }>ELSE<{ // owner_address jetton_wallet_code included_address msg + 2 2 BLKDROP2 // included_address msg + 0 PUSHINT // included_address msg _177=0 + SWAP // included_address _177=0 msg + 2 STU // included_address msg + }> + STOPTREF // _180 + ENDC // _181 + 64 PUSHINT // _181 _182=64 + SENDRAWMSG + }> // msg_value fwd_fee sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code + s5 POP + s7 POP + s7 POP // admin_address content sender_address op jetton_wallet_code in_msg_body total_supply + s3 PUSH // admin_address content sender_address op jetton_wallet_code in_msg_body total_supply op + 3 EQINT // admin_address content sender_address op jetton_wallet_code in_msg_body total_supply _185 + IFJMP:<{ // admin_address content sender_address op jetton_wallet_code in_msg_body total_supply + s3 POP // admin_address content sender_address total_supply jetton_wallet_code in_msg_body + s3 s5 XCHG2 // in_msg_body content jetton_wallet_code total_supply sender_address admin_address + SDEQ // in_msg_body content jetton_wallet_code total_supply _187 + 73 THROWIFNOT + s0 s3 XCHG // total_supply content jetton_wallet_code in_msg_body + LDMSGADDR // total_supply content jetton_wallet_code _242 _241 + DROP // total_supply content jetton_wallet_code new_admin_address + -ROT // total_supply new_admin_address content jetton_wallet_code + save_data INLINECALLDICT + }> // admin_address content sender_address op jetton_wallet_code in_msg_body total_supply + s5 POP // admin_address total_supply sender_address op jetton_wallet_code in_msg_body + s0 s2 XCHG // admin_address total_supply sender_address in_msg_body jetton_wallet_code op + 4 EQINT // admin_address total_supply sender_address in_msg_body jetton_wallet_code _194 + IFJMP:<{ // admin_address total_supply sender_address in_msg_body jetton_wallet_code + s2 s4 XCPU // admin_address total_supply jetton_wallet_code in_msg_body sender_address admin_address + SDEQ // admin_address total_supply jetton_wallet_code in_msg_body _196 + 73 THROWIFNOT + LDREF // admin_address total_supply jetton_wallet_code _244 _243 + DROP // admin_address total_supply jetton_wallet_code _198 + s3 s0 s0 XCHG3 // total_supply admin_address _198 jetton_wallet_code + save_data INLINECALLDICT + }> // admin_address total_supply sender_address in_msg_body jetton_wallet_code + 5 BLKDROP // + 16 PUSHPOW2DEC // _201=65535 + THROWANY + }> + get_jetton_data PROC:<{ + // + load_data INLINECALLDICT // total_supply admin_address content jetton_wallet_code + -1 PUSHINT // total_supply admin_address content jetton_wallet_code _5=-1 + 3 -ROLL // total_supply _5=-1 admin_address content jetton_wallet_code + }> + get_wallet_address PROC:<{ + // owner_address + load_data INLINECALLDICT // owner_address _8 _9 _10 _11 + 3 1 BLKDROP2 // owner_address jetton_wallet_code + MYADDR // owner_address jetton_wallet_code _6 + SWAP // owner_address _6 jetton_wallet_code + calculate_user_jetton_wallet_address INLINECALLDICT // _7 + }> +}END>c diff --git a/contracts/imports/jetton-minter.fif b/contracts/imports/jetton-minter.fif new file mode 100644 index 0000000..577644d --- /dev/null +++ b/contracts/imports/jetton-minter.fif @@ -0,0 +1,252 @@ +"Asm.fif" include +// automatically generated from `imports/stdlib.fc` `params.fc` `op-codes.fc` `jetton-utils.fc` `jetton-minter.fc` +PROGRAM{ + DECLPROC force_chain + DECLPROC pack_jetton_wallet_data + DECLPROC calculate_jetton_wallet_state_init + DECLPROC calculate_jetton_wallet_address + DECLPROC calculate_user_jetton_wallet_address + DECLPROC load_data + DECLPROC save_data + DECLPROC mint_tokens + DECLPROC recv_internal + 106029 DECLMETHOD get_jetton_data + 103289 DECLMETHOD get_wallet_address + force_chain PROC:<{ + // addr + REWRITESTDADDR // _8 _9 + DROP // wc + 0 PUSHINT // wc _5 + EQUAL // _6 + 333 THROWIFNOT + }> + pack_jetton_wallet_data PROCINLINE:<{ + // balance owner_address jetton_master_address jetton_wallet_code + NEWC // balance owner_address jetton_master_address jetton_wallet_code _4 + s0 s4 XCHG2 // jetton_wallet_code owner_address jetton_master_address _4 balance + STVARUINT16 // jetton_wallet_code owner_address jetton_master_address _5 + ROT // jetton_wallet_code jetton_master_address _5 owner_address + STSLICER // jetton_wallet_code jetton_master_address _6 + SWAP // jetton_wallet_code _6 jetton_master_address + STSLICER // jetton_wallet_code _7 + STREF // _8 + ENDC // _9 + }> + calculate_jetton_wallet_state_init PROCINLINE:<{ + // owner_address jetton_master_address jetton_wallet_code + 0 PUSHINT // owner_address jetton_master_address jetton_wallet_code _3=0 + s0 s1 s2 XCPUXC + s4 s0 s3 XC2PU // _3=0 jetton_wallet_code _4=0 owner_address jetton_master_address jetton_wallet_code + pack_jetton_wallet_data INLINECALLDICT // _3=0 jetton_wallet_code _5 + s2 PUSH // _3=0 jetton_wallet_code _5 _6=0 + NEWC // _3=0 jetton_wallet_code _5 _6=0 _7 + 2 STU // _3=0 jetton_wallet_code _5 _9 + s1 s2 XCHG // _3=0 _5 jetton_wallet_code _9 + STDICT // _3=0 _5 _10 + STDICT // _3=0 _11 + 1 STU // _13 + ENDC // _14 + }> + calculate_jetton_wallet_address PROCINLINE:<{ + // state_init + HASHCU // _1 + 0 PUSHINT // _1 _2 + 4 PUSHINT // _1 _2 _3=4 + NEWC // _1 _2 _3=4 _4 + 3 STU // _1 _2 _6 + 8 STI // _1 _8 + 256 STU // _10 + ENDC // _11 + CTOS // _12 + }> + calculate_user_jetton_wallet_address PROCINLINE:<{ + // owner_address jetton_master_address jetton_wallet_code + calculate_jetton_wallet_state_init INLINECALLDICT // _3 + calculate_jetton_wallet_address INLINECALLDICT // _4 + }> + load_data PROCINLINE:<{ + // + c4 PUSH // _1 + CTOS // ds + LDVARUINT16 // _3 ds + LDMSGADDR // _3 _5 ds + LDREF // _3 _5 _7 ds + LDREF // _3 _5 _7 _18 _17 + DROP // _3 _5 _7 _9 + }> + save_data PROCINLINE:<{ + // total_supply admin_address content jetton_wallet_code + NEWC // total_supply admin_address content jetton_wallet_code _4 + s0 s4 XCHG2 // jetton_wallet_code admin_address content _4 total_supply + STVARUINT16 // jetton_wallet_code admin_address content _5 + ROT // jetton_wallet_code content _5 admin_address + STSLICER // jetton_wallet_code content _6 + STREF // jetton_wallet_code _7 + STREF // _8 + ENDC // _9 + c4 POP + }> + mint_tokens PROC:<{ + // to_address jetton_wallet_code amount master_msg + MYADDR // to_address jetton_wallet_code amount master_msg _5 + s4 s0 s3 XCHG3 // amount master_msg to_address _5 jetton_wallet_code + calculate_jetton_wallet_state_init INLINECALLDICT // amount master_msg state_init + DUP // amount master_msg state_init state_init + calculate_jetton_wallet_address INLINECALLDICT // amount master_msg state_init to_wallet_address + 7 PUSHINT // amount master_msg state_init to_wallet_address _14 + 24 PUSHINT // amount master_msg state_init to_wallet_address _14 _15=24 + NEWC // amount master_msg state_init to_wallet_address _14 _15=24 _16 + 6 STU // amount master_msg state_init to_wallet_address _14 _18 + ROT // amount master_msg state_init _14 _18 to_wallet_address + STSLICER // amount master_msg state_init _14 _19 + s0 s4 XCHG2 // _14 master_msg state_init _19 amount + STVARUINT16 // _14 master_msg state_init _20 + s1 s3 XCHG // state_init master_msg _14 _20 + 108 STU // state_init master_msg _36 + s1 s2 XCHG // master_msg state_init _36 + STREF // master_msg _37 + STREF // msg + ENDC // _39 + 1 PUSHINT // _39 _40=1 + SENDRAWMSG + }> + recv_internal PROC:<{ + // msg_value in_msg_full in_msg_body + s2 POP // in_msg_body in_msg_full + OVER // in_msg_body in_msg_full in_msg_body + SEMPTY // in_msg_body in_msg_full _3 + IFJMP:<{ // in_msg_body in_msg_full + 2DROP // + }> // in_msg_body in_msg_full + CTOS // in_msg_body cs + 4 LDU // in_msg_body flags cs + SWAP + 1 PUSHINT // in_msg_body cs flags _10=1 + AND // in_msg_body cs _11 + IFJMP:<{ // in_msg_body cs + 2DROP // + }> // in_msg_body cs + LDMSGADDR // in_msg_body _132 _131 + DROP // in_msg_body sender_address + SWAP // sender_address in_msg_body + 32 LDU // sender_address op in_msg_body + 64 LDU // sender_address op query_id in_msg_body + load_data INLINECALLDICT // sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code + 21 PUSHINT // sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code _28 + s7 s(-1) PUXC // sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code op _28 + EQUAL // sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code _29 + IFJMP:<{ // sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code + s5 POP + s5 POP // sender_address content jetton_wallet_code in_msg_body total_supply admin_address + s5 s5 XCPU // admin_address content jetton_wallet_code in_msg_body total_supply sender_address admin_address + SDEQ // admin_address content jetton_wallet_code in_msg_body total_supply _31 + 73 THROWIFNOT + SWAP // admin_address content jetton_wallet_code total_supply in_msg_body + LDMSGADDR // admin_address content jetton_wallet_code total_supply to_address in_msg_body + LDVARUINT16 // admin_address content jetton_wallet_code total_supply to_address amount in_msg_body + LDREF // admin_address content jetton_wallet_code total_supply to_address amount _146 _145 + DROP // admin_address content jetton_wallet_code total_supply to_address amount master_msg + DUP // admin_address content jetton_wallet_code total_supply to_address amount master_msg master_msg + CTOS // admin_address content jetton_wallet_code total_supply to_address amount master_msg master_msg_cs + 96 PUSHINT // admin_address content jetton_wallet_code total_supply to_address amount master_msg master_msg_cs _47 + SDSKIPFIRST // admin_address content jetton_wallet_code total_supply to_address amount master_msg master_msg_cs + LDVARUINT16 // admin_address content jetton_wallet_code total_supply to_address amount master_msg _148 _147 + DROP // admin_address content jetton_wallet_code total_supply to_address amount master_msg jetton_amount + s5 PUSH + s3 s4 XCHG + s4 s2 XCHG2 // admin_address content jetton_wallet_code total_supply jetton_amount to_address jetton_wallet_code amount master_msg + mint_tokens CALLDICT + ADD // admin_address content jetton_wallet_code _53 + 3 -ROLL // _53 admin_address content jetton_wallet_code + save_data INLINECALLDICT + }> // sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code + 0x7bdd97de PUSHINT // sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code _55 + s7 s(-1) PUXC // sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code op _55 + EQUAL // sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code _56 + IFJMP:<{ // sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code + s6 POP // sender_address jetton_wallet_code query_id in_msg_body total_supply admin_address content + s0 s3 XCHG // sender_address jetton_wallet_code query_id content total_supply admin_address in_msg_body + LDVARUINT16 // sender_address jetton_wallet_code query_id content total_supply admin_address jetton_amount in_msg_body + LDMSGADDR // sender_address jetton_wallet_code query_id content total_supply admin_address jetton_amount from_address in_msg_body + MYADDR // sender_address jetton_wallet_code query_id content total_supply admin_address jetton_amount from_address in_msg_body _64 + s2 s0 s8 XC2PU // sender_address jetton_wallet_code query_id content total_supply admin_address jetton_amount in_msg_body from_address _64 jetton_wallet_code + calculate_user_jetton_wallet_address INLINECALLDICT // sender_address jetton_wallet_code query_id content total_supply admin_address jetton_amount in_msg_body _65 + s0 s8 XCHG2 // in_msg_body jetton_wallet_code query_id content total_supply admin_address jetton_amount _65 sender_address + SDEQ // in_msg_body jetton_wallet_code query_id content total_supply admin_address jetton_amount _66 + 74 THROWIFNOT + s1 s2 XCHG // in_msg_body jetton_wallet_code query_id content admin_address total_supply jetton_amount + SUB // in_msg_body jetton_wallet_code query_id content admin_address _68 + s0 s3 XCHG + s2 s4 XCHG2 // in_msg_body query_id _68 admin_address content jetton_wallet_code + save_data INLINECALLDICT + SWAP // query_id in_msg_body + LDMSGADDR // query_id _154 _153 + DROP // query_id response_address + DUP // query_id response_address response_address + 2 PLDU // query_id response_address _74 + 0 NEQINT // query_id response_address _76 + IF:<{ // query_id response_address + 0xd53276db PUSHINT // query_id response_address _78 + 0 PUSHINT // query_id response_address _78 _79=0 + 16 PUSHINT // query_id response_address _78 _79=0 _80=16 + NEWC // query_id response_address _78 _79=0 _80=16 _81 + 6 STU // query_id response_address _78 _79=0 _83 + s0 s3 XCHG2 // query_id _79=0 _78 _83 response_address + STSLICER // query_id _79=0 _78 _84 + s2 PUSH // query_id _79=0 _78 _84 _85=0 + STVARUINT16 // query_id _79=0 _78 _86 + s1 s2 XCHG // query_id _78 _79=0 _86 + 107 STU // query_id _78 _100 + 32 STU // query_id _102 + 64 STU // msg + ENDC // _105 + 66 PUSHINT // _105 _108 + SENDRAWMSG + }>ELSE<{ + 2DROP // + }> + }> // sender_address op query_id in_msg_body total_supply admin_address content jetton_wallet_code + s5 POP // sender_address op jetton_wallet_code in_msg_body total_supply admin_address content + s5 PUSH // sender_address op jetton_wallet_code in_msg_body total_supply admin_address content op + 3 EQINT // sender_address op jetton_wallet_code in_msg_body total_supply admin_address content _111 + IFJMP:<{ // sender_address op jetton_wallet_code in_msg_body total_supply admin_address content + s5 POP // sender_address content jetton_wallet_code in_msg_body total_supply admin_address + s1 s5 XCHG // total_supply content jetton_wallet_code in_msg_body sender_address admin_address + SDEQ // total_supply content jetton_wallet_code in_msg_body _113 + 73 THROWIFNOT + LDMSGADDR // total_supply content jetton_wallet_code _156 _155 + DROP // total_supply content jetton_wallet_code new_admin_address + -ROT // total_supply new_admin_address content jetton_wallet_code + save_data INLINECALLDICT + }> // sender_address op jetton_wallet_code in_msg_body total_supply admin_address content + DROP // sender_address op jetton_wallet_code in_msg_body total_supply admin_address + s0 s4 XCHG // sender_address admin_address jetton_wallet_code in_msg_body total_supply op + 4 EQINT // sender_address admin_address jetton_wallet_code in_msg_body total_supply _120 + IFJMP:<{ // sender_address admin_address jetton_wallet_code in_msg_body total_supply + s4 s3 XCPU // total_supply admin_address jetton_wallet_code in_msg_body sender_address admin_address + SDEQ // total_supply admin_address jetton_wallet_code in_msg_body _122 + 73 THROWIFNOT + LDREF // total_supply admin_address jetton_wallet_code _158 _157 + DROP // total_supply admin_address jetton_wallet_code _124 + SWAP // total_supply admin_address _124 jetton_wallet_code + save_data INLINECALLDICT + }> // sender_address admin_address jetton_wallet_code in_msg_body total_supply + 5 BLKDROP // + 16 PUSHPOW2DEC // _127=65535 + THROWANY + }> + get_jetton_data PROC:<{ + // + load_data INLINECALLDICT // total_supply admin_address content jetton_wallet_code + -1 PUSHINT // total_supply admin_address content jetton_wallet_code _5=-1 + 3 -ROLL // total_supply _5=-1 admin_address content jetton_wallet_code + }> + get_wallet_address PROC:<{ + // owner_address + load_data INLINECALLDICT // owner_address _8 _9 _10 _11 + 3 1 BLKDROP2 // owner_address jetton_wallet_code + MYADDR // owner_address jetton_wallet_code _6 + SWAP // owner_address _6 jetton_wallet_code + calculate_user_jetton_wallet_address INLINECALLDICT // _7 + }> +}END>c diff --git a/contracts/imports/jetton-wallet.boc b/contracts/imports/jetton-wallet.boc new file mode 100644 index 0000000..50d2731 Binary files /dev/null and b/contracts/imports/jetton-wallet.boc differ diff --git a/contracts/imports/jetton-wallet.fif b/contracts/imports/jetton-wallet.fif new file mode 100644 index 0000000..0d04887 --- /dev/null +++ b/contracts/imports/jetton-wallet.fif @@ -0,0 +1,417 @@ +"Asm.fif" include +// automatically generated from `imports/stdlib.fc` `params.fc` `op-codes.fc` `jetton-utils.fc` `jetton-wallet.fc` +PROGRAM{ + DECLPROC force_chain + DECLPROC pack_jetton_wallet_data + DECLPROC calculate_jetton_wallet_state_init + DECLPROC calculate_jetton_wallet_address + DECLPROC calculate_user_jetton_wallet_address + DECLPROC load_data + DECLPROC save_data + DECLPROC send_tokens + DECLPROC receive_tokens + DECLPROC burn_tokens + DECLPROC on_bounce + DECLPROC recv_internal + 97026 DECLMETHOD get_wallet_data + force_chain PROC:<{ + // addr + REWRITESTDADDR // _8 _9 + DROP // wc + 0 PUSHINT // wc _5 + EQUAL // _6 + 333 THROWIFNOT + }> + pack_jetton_wallet_data PROCINLINE:<{ + // balance owner_address jetton_master_address jetton_wallet_code + NEWC // balance owner_address jetton_master_address jetton_wallet_code _4 + s0 s4 XCHG2 // jetton_wallet_code owner_address jetton_master_address _4 balance + STVARUINT16 // jetton_wallet_code owner_address jetton_master_address _5 + ROT // jetton_wallet_code jetton_master_address _5 owner_address + STSLICER // jetton_wallet_code jetton_master_address _6 + SWAP // jetton_wallet_code _6 jetton_master_address + STSLICER // jetton_wallet_code _7 + STREF // _8 + ENDC // _9 + }> + calculate_jetton_wallet_state_init PROCINLINE:<{ + // owner_address jetton_master_address jetton_wallet_code + 0 PUSHINT // owner_address jetton_master_address jetton_wallet_code _3=0 + s0 s1 s2 XCPUXC + s4 s0 s3 XC2PU // _3=0 jetton_wallet_code _4=0 owner_address jetton_master_address jetton_wallet_code + pack_jetton_wallet_data INLINECALLDICT // _3=0 jetton_wallet_code _5 + s2 PUSH // _3=0 jetton_wallet_code _5 _6=0 + NEWC // _3=0 jetton_wallet_code _5 _6=0 _7 + 2 STU // _3=0 jetton_wallet_code _5 _9 + s1 s2 XCHG // _3=0 _5 jetton_wallet_code _9 + STDICT // _3=0 _5 _10 + STDICT // _3=0 _11 + 1 STU // _13 + ENDC // _14 + }> + calculate_jetton_wallet_address PROCINLINE:<{ + // state_init + HASHCU // _1 + 0 PUSHINT // _1 _2 + 4 PUSHINT // _1 _2 _3=4 + NEWC // _1 _2 _3=4 _4 + 3 STU // _1 _2 _6 + 8 STI // _1 _8 + 256 STU // _10 + ENDC // _11 + CTOS // _12 + }> + calculate_user_jetton_wallet_address PROCINLINE:<{ + // owner_address jetton_master_address jetton_wallet_code + calculate_jetton_wallet_state_init INLINECALLDICT // _3 + calculate_jetton_wallet_address INLINECALLDICT // _4 + }> + load_data PROCINLINE:<{ + // + c4 PUSH // _1 + CTOS // ds + LDVARUINT16 // _3 ds + LDMSGADDR // _3 _5 ds + LDMSGADDR // _3 _5 _7 ds + LDREF // _3 _5 _7 _18 _17 + DROP // _3 _5 _7 _9 + }> + save_data PROCINLINE:<{ + // balance owner_address jetton_master_address jetton_wallet_code + pack_jetton_wallet_data INLINECALLDICT // _4 + c4 POP + }> + send_tokens PROC:<{ + // in_msg_body sender_address msg_value fwd_fee + s0 s3 XCHG // fwd_fee sender_address msg_value in_msg_body + 64 LDU // fwd_fee sender_address msg_value query_id in_msg_body + LDVARUINT16 // fwd_fee sender_address msg_value query_id jetton_amount in_msg_body + LDMSGADDR // fwd_fee sender_address msg_value query_id jetton_amount to_owner_address in_msg_body + OVER // fwd_fee sender_address msg_value query_id jetton_amount to_owner_address in_msg_body to_owner_address + force_chain CALLDICT + load_data INLINECALLDICT // fwd_fee sender_address msg_value query_id jetton_amount to_owner_address in_msg_body balance owner_address jetton_master_address jetton_wallet_code + s3 s6 XCPU // fwd_fee sender_address msg_value query_id jetton_amount to_owner_address in_msg_body jetton_wallet_code owner_address jetton_master_address balance jetton_amount + SUB // fwd_fee sender_address msg_value query_id jetton_amount to_owner_address in_msg_body jetton_wallet_code owner_address jetton_master_address balance + s2 s9 PUXC // fwd_fee balance msg_value query_id jetton_amount to_owner_address in_msg_body jetton_wallet_code owner_address jetton_master_address owner_address sender_address + SDEQ // fwd_fee balance msg_value query_id jetton_amount to_owner_address in_msg_body jetton_wallet_code owner_address jetton_master_address _22 + 705 THROWIFNOT + s8 PUSH // fwd_fee balance msg_value query_id jetton_amount to_owner_address in_msg_body jetton_wallet_code owner_address jetton_master_address balance + -1 GTINT // fwd_fee balance msg_value query_id jetton_amount to_owner_address in_msg_body jetton_wallet_code owner_address jetton_master_address _26 + 706 THROWIFNOT + s4 s4 s2 XCPU2 // fwd_fee balance msg_value query_id jetton_amount jetton_master_address in_msg_body jetton_wallet_code owner_address to_owner_address jetton_master_address jetton_wallet_code + calculate_jetton_wallet_state_init INLINECALLDICT // fwd_fee balance msg_value query_id jetton_amount jetton_master_address in_msg_body jetton_wallet_code owner_address state_init + DUP // fwd_fee balance msg_value query_id jetton_amount jetton_master_address in_msg_body jetton_wallet_code owner_address state_init state_init + calculate_jetton_wallet_address INLINECALLDICT // fwd_fee balance msg_value query_id jetton_amount jetton_master_address in_msg_body jetton_wallet_code owner_address state_init to_wallet_address + s0 s4 XCHG // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init in_msg_body + LDMSGADDR // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init response_address in_msg_body + LDDICT // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init response_address _123 _122 + NIP // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init response_address in_msg_body + LDVARUINT16 // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init response_address forward_ton_amount in_msg_body + DUP // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init response_address forward_ton_amount in_msg_body in_msg_body + SBITS // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init response_address forward_ton_amount in_msg_body _42 + 0 GTINT // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init response_address forward_ton_amount in_msg_body _44 + 708 THROWIFNOT // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init response_address forward_ton_amount either_forward_payload + 7 PUSHINT // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init response_address forward_ton_amount either_forward_payload _52 + 24 PUSHINT // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init response_address forward_ton_amount either_forward_payload _52 _53=24 + NEWC // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init response_address forward_ton_amount either_forward_payload _52 _53=24 _54 + 6 STU // fwd_fee balance msg_value query_id jetton_amount jetton_master_address to_wallet_address jetton_wallet_code owner_address state_init response_address forward_ton_amount either_forward_payload _52 _56 + s0 s8 XCHG2 // fwd_fee balance msg_value query_id jetton_amount jetton_master_address _52 jetton_wallet_code owner_address state_init response_address forward_ton_amount either_forward_payload _56 to_wallet_address + STSLICER // fwd_fee balance msg_value query_id jetton_amount jetton_master_address _52 jetton_wallet_code owner_address state_init response_address forward_ton_amount either_forward_payload _57 + 0 PUSHINT // fwd_fee balance msg_value query_id jetton_amount jetton_master_address _52 jetton_wallet_code owner_address state_init response_address forward_ton_amount either_forward_payload _57 _58=0 + STVARUINT16 // fwd_fee balance msg_value query_id jetton_amount jetton_master_address _52 jetton_wallet_code owner_address state_init response_address forward_ton_amount either_forward_payload _59 + s1 s7 XCHG // fwd_fee balance msg_value query_id jetton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address state_init response_address forward_ton_amount _52 _59 + 108 STU // fwd_fee balance msg_value query_id jetton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address state_init response_address forward_ton_amount _75 + s1 s3 XCHG // fwd_fee balance msg_value query_id jetton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address forward_ton_amount response_address state_init _75 + STREF // fwd_fee balance msg_value query_id jetton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address forward_ton_amount response_address msg + 0x178d4519 PUSHINT // fwd_fee balance msg_value query_id jetton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address forward_ton_amount response_address msg _78 + NEWC // fwd_fee balance msg_value query_id jetton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address forward_ton_amount response_address msg _78 _79 + 32 STU // fwd_fee balance msg_value query_id jetton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address forward_ton_amount response_address msg _81 + s1 s9 XCHG // fwd_fee balance msg_value msg jetton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address forward_ton_amount response_address query_id _81 + 64 STU // fwd_fee balance msg_value msg jetton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address forward_ton_amount response_address _83 + s0 s7 XCHG2 // fwd_fee balance msg_value msg response_address jetton_master_address either_forward_payload jetton_wallet_code owner_address forward_ton_amount _83 jetton_amount + STVARUINT16 // fwd_fee balance msg_value msg response_address jetton_master_address either_forward_payload jetton_wallet_code owner_address forward_ton_amount _84 + s2 PUSH // fwd_fee balance msg_value msg response_address jetton_master_address either_forward_payload jetton_wallet_code owner_address forward_ton_amount _84 owner_address + STSLICER // fwd_fee balance msg_value msg response_address jetton_master_address either_forward_payload jetton_wallet_code owner_address forward_ton_amount _85 + s0 s6 XCHG2 // fwd_fee balance msg_value msg forward_ton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address _85 response_address + STSLICER // fwd_fee balance msg_value msg forward_ton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address _86 + s5 PUSH // fwd_fee balance msg_value msg forward_ton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address _86 forward_ton_amount + STVARUINT16 // fwd_fee balance msg_value msg forward_ton_amount jetton_master_address either_forward_payload jetton_wallet_code owner_address _87 + s0 s3 XCHG2 // fwd_fee balance msg_value msg forward_ton_amount jetton_master_address owner_address jetton_wallet_code _87 either_forward_payload + STSLICER // fwd_fee balance msg_value msg forward_ton_amount jetton_master_address owner_address jetton_wallet_code _88 + ENDC // fwd_fee balance msg_value msg forward_ton_amount jetton_master_address owner_address jetton_wallet_code msg_body + s0 s5 XCHG2 // fwd_fee balance msg_value jetton_wallet_code forward_ton_amount jetton_master_address owner_address msg_body msg + STREF // fwd_fee balance msg_value jetton_wallet_code forward_ton_amount jetton_master_address owner_address msg + s3 PUSH // fwd_fee balance msg_value jetton_wallet_code forward_ton_amount jetton_master_address owner_address msg forward_ton_amount + IF:<{ // fwd_fee balance msg_value jetton_wallet_code forward_ton_amount jetton_master_address owner_address msg + 2 PUSHINT // fwd_fee balance msg_value jetton_wallet_code forward_ton_amount jetton_master_address owner_address msg _92=2 + }>ELSE<{ // fwd_fee balance msg_value jetton_wallet_code forward_ton_amount jetton_master_address owner_address msg + 1 PUSHINT // fwd_fee balance msg_value jetton_wallet_code forward_ton_amount jetton_master_address owner_address msg _92=1 + }> // fwd_fee balance msg_value jetton_wallet_code forward_ton_amount jetton_master_address owner_address msg fwd_count + s0 s8 XCHG2 // msg balance msg_value jetton_wallet_code forward_ton_amount jetton_master_address owner_address fwd_count fwd_fee + MUL // msg balance msg_value jetton_wallet_code forward_ton_amount jetton_master_address owner_address _96 + s1 s3 XCHG // msg balance msg_value jetton_wallet_code owner_address jetton_master_address forward_ton_amount _96 + ADD // msg balance msg_value jetton_wallet_code owner_address jetton_master_address _97 + 15000000 PUSHINT // msg balance msg_value jetton_wallet_code owner_address jetton_master_address _97 _99 + 1 LSHIFT# // msg balance msg_value jetton_wallet_code owner_address jetton_master_address _97 _100 + 10000000 PUSHINT // msg balance msg_value jetton_wallet_code owner_address jetton_master_address _97 _100 _101 + ADD // msg balance msg_value jetton_wallet_code owner_address jetton_master_address _97 _102 + ADD // msg balance msg_value jetton_wallet_code owner_address jetton_master_address _103 + s1 s4 XCHG // msg balance jetton_master_address jetton_wallet_code owner_address msg_value _103 + GREATER // msg balance jetton_master_address jetton_wallet_code owner_address _104 + 709 THROWIFNOT + s0 s4 XCHG // owner_address balance jetton_master_address jetton_wallet_code msg + ENDC // owner_address balance jetton_master_address jetton_wallet_code _106 + 64 PUSHINT // owner_address balance jetton_master_address jetton_wallet_code _106 _107=64 + SENDRAWMSG + s2 s3 XCHG // balance owner_address jetton_master_address jetton_wallet_code + save_data INLINECALLDICT + }> + receive_tokens PROC:<{ + // in_msg_body sender_address my_ton_balance fwd_fee msg_value + load_data INLINECALLDICT // in_msg_body sender_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address jetton_wallet_code + s0 s8 XCHG // jetton_wallet_code sender_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address in_msg_body + 64 LDU // jetton_wallet_code sender_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id in_msg_body + LDVARUINT16 // jetton_wallet_code sender_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount in_msg_body + s5 s1 XCPU // jetton_wallet_code sender_address my_ton_balance fwd_fee msg_value in_msg_body owner_address jetton_master_address query_id jetton_amount balance jetton_amount + ADD // jetton_wallet_code sender_address my_ton_balance fwd_fee msg_value in_msg_body owner_address jetton_master_address query_id jetton_amount balance + s0 s5 XCHG // jetton_wallet_code sender_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount in_msg_body + LDMSGADDR // jetton_wallet_code sender_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address in_msg_body + LDMSGADDR // jetton_wallet_code sender_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address response_address in_msg_body + s5 s11 PUSH2 // jetton_wallet_code sender_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address response_address in_msg_body jetton_master_address sender_address + SDEQ // jetton_wallet_code sender_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address response_address in_msg_body _25 + s3 s6 s13 PUSH3 // jetton_wallet_code sender_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address response_address in_msg_body _25 from_address jetton_master_address jetton_wallet_code + calculate_user_jetton_wallet_address INLINECALLDICT // jetton_wallet_code sender_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address response_address in_msg_body _25 _26 + s0 s13 XCHG2 // jetton_wallet_code _25 my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address response_address in_msg_body _26 sender_address + SDEQ // jetton_wallet_code _25 my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address response_address in_msg_body _27 + s1 s12 XCHG // jetton_wallet_code in_msg_body my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address response_address _25 _27 + OR // jetton_wallet_code in_msg_body my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address response_address _28 + 707 THROWIFNOT + s0 s10 XCHG // jetton_wallet_code response_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address in_msg_body + LDVARUINT16 // jetton_wallet_code response_address my_ton_balance fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address forward_ton_amount in_msg_body + s10 s8 XCPU // jetton_wallet_code response_address in_msg_body fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address forward_ton_amount my_ton_balance msg_value + SUB // jetton_wallet_code response_address in_msg_body fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address forward_ton_amount ton_balance_before_msg + 10000000 PUSHINT // jetton_wallet_code response_address in_msg_body fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address forward_ton_amount ton_balance_before_msg _36 + 10000000 PUSHINT // jetton_wallet_code response_address in_msg_body fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address forward_ton_amount ton_balance_before_msg _36 _37 + s1 s2 XCHG // jetton_wallet_code response_address in_msg_body fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address forward_ton_amount _36 ton_balance_before_msg _37 + MIN // jetton_wallet_code response_address in_msg_body fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address forward_ton_amount _36 _38 + SUB // jetton_wallet_code response_address in_msg_body fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address forward_ton_amount storage_fee + 15000000 PUSHINT // jetton_wallet_code response_address in_msg_body fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address forward_ton_amount storage_fee _40 + ADD // jetton_wallet_code response_address in_msg_body fwd_fee msg_value balance owner_address jetton_master_address query_id jetton_amount from_address forward_ton_amount _41 + s1 s8 XCHG // jetton_wallet_code response_address in_msg_body fwd_fee forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount from_address msg_value _41 + SUB // jetton_wallet_code response_address in_msg_body fwd_fee forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount from_address msg_value + s7 PUSH // jetton_wallet_code response_address in_msg_body fwd_fee forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount from_address msg_value forward_ton_amount + IF:<{ // jetton_wallet_code response_address in_msg_body fwd_fee forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount from_address msg_value + s7 s8 PUXC // jetton_wallet_code response_address in_msg_body msg_value forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount from_address forward_ton_amount fwd_fee + ADD // jetton_wallet_code response_address in_msg_body msg_value forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount from_address _43 + s1 s8 XCHG // jetton_wallet_code response_address in_msg_body from_address forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount msg_value _43 + SUB // jetton_wallet_code response_address either_forward_payload from_address forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount msg_value + 0x7362d09c PUSHINT // jetton_wallet_code response_address either_forward_payload from_address forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount msg_value _47 + NEWC // jetton_wallet_code response_address either_forward_payload from_address forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount msg_value _47 _48 + 32 STU // jetton_wallet_code response_address either_forward_payload from_address forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount msg_value _50 + s3 s(-1) PUXC // jetton_wallet_code response_address either_forward_payload from_address forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount msg_value query_id _50 + 64 STU // jetton_wallet_code response_address either_forward_payload from_address forward_ton_amount balance owner_address jetton_master_address query_id jetton_amount msg_value _52 + ROT // jetton_wallet_code response_address either_forward_payload from_address forward_ton_amount balance owner_address jetton_master_address query_id msg_value _52 jetton_amount + STVARUINT16 // jetton_wallet_code response_address either_forward_payload from_address forward_ton_amount balance owner_address jetton_master_address query_id msg_value _53 + s0 s7 XCHG2 // jetton_wallet_code response_address either_forward_payload msg_value forward_ton_amount balance owner_address jetton_master_address query_id _53 from_address + STSLICER // jetton_wallet_code response_address either_forward_payload msg_value forward_ton_amount balance owner_address jetton_master_address query_id _54 + s0 s7 XCHG2 // jetton_wallet_code response_address query_id msg_value forward_ton_amount balance owner_address jetton_master_address _54 either_forward_payload + STSLICER // jetton_wallet_code response_address query_id msg_value forward_ton_amount balance owner_address jetton_master_address _55 + ENDC // jetton_wallet_code response_address query_id msg_value forward_ton_amount balance owner_address jetton_master_address msg_body + 1 PUSHINT // jetton_wallet_code response_address query_id msg_value forward_ton_amount balance owner_address jetton_master_address msg_body _58=1 + 16 PUSHINT // jetton_wallet_code response_address query_id msg_value forward_ton_amount balance owner_address jetton_master_address msg_body _58=1 _59=16 + NEWC // jetton_wallet_code response_address query_id msg_value forward_ton_amount balance owner_address jetton_master_address msg_body _58=1 _59=16 _60 + 6 STU // jetton_wallet_code response_address query_id msg_value forward_ton_amount balance owner_address jetton_master_address msg_body _58=1 _62 + s4 PUSH // jetton_wallet_code response_address query_id msg_value forward_ton_amount balance owner_address jetton_master_address msg_body _58=1 _62 owner_address + STSLICER // jetton_wallet_code response_address query_id msg_value forward_ton_amount balance owner_address jetton_master_address msg_body _58=1 _63 + s0 s6 XCHG2 // jetton_wallet_code response_address query_id msg_value _58=1 balance owner_address jetton_master_address msg_body _63 forward_ton_amount + STVARUINT16 // jetton_wallet_code response_address query_id msg_value _58=1 balance owner_address jetton_master_address msg_body _64 + s1 s5 XCHG // jetton_wallet_code response_address query_id msg_value msg_body balance owner_address jetton_master_address _58=1 _64 + 107 STU // jetton_wallet_code response_address query_id msg_value msg_body balance owner_address jetton_master_address _78 + s1 s4 XCHG // jetton_wallet_code response_address query_id msg_value jetton_master_address balance owner_address msg_body _78 + STREF // jetton_wallet_code response_address query_id msg_value jetton_master_address balance owner_address msg + ENDC // jetton_wallet_code response_address query_id msg_value jetton_master_address balance owner_address _80 + 1 PUSHINT // jetton_wallet_code response_address query_id msg_value jetton_master_address balance owner_address _80 _81=1 + SENDRAWMSG + s2 s4 XCHG + s2 s3 XCHG // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address + }>ELSE<{ + s4 s9 XCHG + s3 s8 XCHG + s7 POP + 4 BLKDROP // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address + }> + s5 PUSH // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address response_address + 2 PLDU // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address _84 + 0 NEQINT // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address _86 + s3 PUSH // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address _86 msg_value + 0 GTINT // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address _86 _88 + AND // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address _89 + IF:<{ // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address + 0xd53276db PUSHINT // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address _91 + 0 PUSHINT // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address _91 _92=0 + 16 PUSHINT // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address _91 _92=0 _93=16 + NEWC // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address _91 _92=0 _93=16 _94 + 6 STU // jetton_wallet_code response_address jetton_master_address query_id msg_value balance owner_address _91 _92=0 _96 + s0 s8 XCHG2 // jetton_wallet_code _92=0 jetton_master_address query_id msg_value balance owner_address _91 _96 response_address + STSLICER // jetton_wallet_code _92=0 jetton_master_address query_id msg_value balance owner_address _91 _97 + s0 s4 XCHG2 // jetton_wallet_code _92=0 jetton_master_address query_id _91 balance owner_address _97 msg_value + STVARUINT16 // jetton_wallet_code _92=0 jetton_master_address query_id _91 balance owner_address _98 + s1 s6 XCHG // jetton_wallet_code owner_address jetton_master_address query_id _91 balance _92=0 _98 + 107 STU // jetton_wallet_code owner_address jetton_master_address query_id _91 balance _112 + s1 s2 XCHG // jetton_wallet_code owner_address jetton_master_address query_id balance _91 _112 + 32 STU // jetton_wallet_code owner_address jetton_master_address query_id balance _114 + s1 s2 XCHG // jetton_wallet_code owner_address jetton_master_address balance query_id _114 + 64 STU // jetton_wallet_code owner_address jetton_master_address balance msg + ENDC // jetton_wallet_code owner_address jetton_master_address balance _117 + 2 PUSHINT // jetton_wallet_code owner_address jetton_master_address balance _117 _118=2 + SENDRAWMSG + }>ELSE<{ + s5 POP + 2 1 BLKDROP2 // jetton_wallet_code owner_address jetton_master_address balance + }> + s0 s3 XCHG // balance owner_address jetton_master_address jetton_wallet_code + save_data INLINECALLDICT + }> + burn_tokens PROC:<{ + // in_msg_body sender_address msg_value fwd_fee + load_data INLINECALLDICT // in_msg_body sender_address msg_value fwd_fee balance owner_address jetton_master_address jetton_wallet_code + s0 s7 XCHG // jetton_wallet_code sender_address msg_value fwd_fee balance owner_address jetton_master_address in_msg_body + 64 LDU // jetton_wallet_code sender_address msg_value fwd_fee balance owner_address jetton_master_address query_id in_msg_body + LDVARUINT16 // jetton_wallet_code sender_address msg_value fwd_fee balance owner_address jetton_master_address query_id jetton_amount in_msg_body + LDMSGADDR // jetton_wallet_code sender_address msg_value fwd_fee balance owner_address jetton_master_address query_id jetton_amount _82 _81 + DROP // jetton_wallet_code sender_address msg_value fwd_fee balance owner_address jetton_master_address query_id jetton_amount response_address + s5 s1 XCPU // jetton_wallet_code sender_address msg_value fwd_fee response_address owner_address jetton_master_address query_id jetton_amount balance jetton_amount + SUB // jetton_wallet_code sender_address msg_value fwd_fee response_address owner_address jetton_master_address query_id jetton_amount balance + s4 s8 PUXC // jetton_wallet_code balance msg_value fwd_fee response_address owner_address jetton_master_address query_id jetton_amount owner_address sender_address + SDEQ // jetton_wallet_code balance msg_value fwd_fee response_address owner_address jetton_master_address query_id jetton_amount _21 + 705 THROWIFNOT + s7 PUSH // jetton_wallet_code balance msg_value fwd_fee response_address owner_address jetton_master_address query_id jetton_amount balance + -1 GTINT // jetton_wallet_code balance msg_value fwd_fee response_address owner_address jetton_master_address query_id jetton_amount _25 + 706 THROWIFNOT + 15000000 PUSHINT // jetton_wallet_code balance msg_value fwd_fee response_address owner_address jetton_master_address query_id jetton_amount _29 + 1 LSHIFT# // jetton_wallet_code balance msg_value fwd_fee response_address owner_address jetton_master_address query_id jetton_amount _30 + s1 s6 XCHG // jetton_wallet_code balance msg_value jetton_amount response_address owner_address jetton_master_address query_id fwd_fee _30 + ADD // jetton_wallet_code balance msg_value jetton_amount response_address owner_address jetton_master_address query_id _31 + s1 s6 XCHG // jetton_wallet_code balance query_id jetton_amount response_address owner_address jetton_master_address msg_value _31 + GREATER // jetton_wallet_code balance query_id jetton_amount response_address owner_address jetton_master_address _32 + 707 THROWIFNOT + 0x7bdd97de PUSHINT // jetton_wallet_code balance query_id jetton_amount response_address owner_address jetton_master_address _35 + NEWC // jetton_wallet_code balance query_id jetton_amount response_address owner_address jetton_master_address _35 _36 + 32 STU // jetton_wallet_code balance query_id jetton_amount response_address owner_address jetton_master_address _38 + s1 s5 XCHG // jetton_wallet_code balance jetton_master_address jetton_amount response_address owner_address query_id _38 + 64 STU // jetton_wallet_code balance jetton_master_address jetton_amount response_address owner_address _40 + s0 s3 XCHG2 // jetton_wallet_code balance jetton_master_address owner_address response_address _40 jetton_amount + STVARUINT16 // jetton_wallet_code balance jetton_master_address owner_address response_address _41 + s2 PUSH // jetton_wallet_code balance jetton_master_address owner_address response_address _41 owner_address + STSLICER // jetton_wallet_code balance jetton_master_address owner_address response_address _42 + SWAP // jetton_wallet_code balance jetton_master_address owner_address _42 response_address + STSLICER // jetton_wallet_code balance jetton_master_address owner_address _43 + ENDC // jetton_wallet_code balance jetton_master_address owner_address msg_body + 1 PUSHINT // jetton_wallet_code balance jetton_master_address owner_address msg_body _46=1 + 24 PUSHINT // jetton_wallet_code balance jetton_master_address owner_address msg_body _46=1 _47=24 + NEWC // jetton_wallet_code balance jetton_master_address owner_address msg_body _46=1 _47=24 _48 + 6 STU // jetton_wallet_code balance jetton_master_address owner_address msg_body _46=1 _50 + s4 PUSH // jetton_wallet_code balance jetton_master_address owner_address msg_body _46=1 _50 jetton_master_address + STSLICER // jetton_wallet_code balance jetton_master_address owner_address msg_body _46=1 _51 + 0 PUSHINT // jetton_wallet_code balance jetton_master_address owner_address msg_body _46=1 _51 _52=0 + STVARUINT16 // jetton_wallet_code balance jetton_master_address owner_address msg_body _46=1 _53 + 107 STU // jetton_wallet_code balance jetton_master_address owner_address msg_body _67 + STREF // jetton_wallet_code balance jetton_master_address owner_address msg + ENDC // jetton_wallet_code balance jetton_master_address owner_address _69 + 64 PUSHINT // jetton_wallet_code balance jetton_master_address owner_address _69 _70=64 + SENDRAWMSG + s0 s1 s3 XCHG3 // balance owner_address jetton_master_address jetton_wallet_code + save_data INLINECALLDICT + }> + on_bounce PROC:<{ + // in_msg_body + 32 PUSHINT // in_msg_body _2=32 + SDSKIPFIRST // in_msg_body + load_data INLINECALLDICT // in_msg_body balance owner_address jetton_master_address jetton_wallet_code + s0 s4 XCHG // jetton_wallet_code balance owner_address jetton_master_address in_msg_body + 32 LDU // jetton_wallet_code balance owner_address jetton_master_address op in_msg_body + 0x178d4519 PUSHINT // jetton_wallet_code balance owner_address jetton_master_address op in_msg_body _14 + s2 s(-1) PUXC // jetton_wallet_code balance owner_address jetton_master_address op in_msg_body op _14 + EQUAL // jetton_wallet_code balance owner_address jetton_master_address op in_msg_body _15 + 0x7bdd97de PUSHINT // jetton_wallet_code balance owner_address jetton_master_address op in_msg_body _15 _16 + s1 s3 XCHG // jetton_wallet_code balance owner_address jetton_master_address _15 in_msg_body op _16 + EQUAL // jetton_wallet_code balance owner_address jetton_master_address _15 in_msg_body _17 + s1 s2 XCHG // jetton_wallet_code balance owner_address jetton_master_address in_msg_body _15 _17 + OR // jetton_wallet_code balance owner_address jetton_master_address in_msg_body _18 + 709 THROWIFNOT + 64 LDU // jetton_wallet_code balance owner_address jetton_master_address _36 _35 + NIP // jetton_wallet_code balance owner_address jetton_master_address in_msg_body + LDVARUINT16 // jetton_wallet_code balance owner_address jetton_master_address _38 _37 + DROP // jetton_wallet_code balance owner_address jetton_master_address jetton_amount + s1 s3 XCHG // jetton_wallet_code jetton_master_address owner_address balance jetton_amount + ADD // jetton_wallet_code jetton_master_address owner_address balance + s2 s3 XCHG2 // balance owner_address jetton_master_address jetton_wallet_code + save_data INLINECALLDICT + }> + recv_internal PROC:<{ + // my_balance msg_value in_msg_full in_msg_body + DUP // my_balance msg_value in_msg_full in_msg_body in_msg_body + SEMPTY // my_balance msg_value in_msg_full in_msg_body _4 + IFJMP:<{ // my_balance msg_value in_msg_full in_msg_body + 4 BLKDROP // + }> // my_balance msg_value in_msg_full in_msg_body + SWAP // my_balance msg_value in_msg_body in_msg_full + CTOS // my_balance msg_value in_msg_body cs + 4 LDU // my_balance msg_value in_msg_body flags cs + SWAP + 1 PUSHINT // my_balance msg_value in_msg_body cs flags _11=1 + AND // my_balance msg_value in_msg_body cs _12 + IFJMP:<{ // my_balance msg_value in_msg_body cs + s1 s3 XCHG + 3 BLKDROP // in_msg_body + on_bounce CALLDICT + }> // my_balance msg_value in_msg_body cs + LDMSGADDR // my_balance msg_value in_msg_body sender_address cs + LDMSGADDR // my_balance msg_value in_msg_body sender_address _52 _51 + NIP // my_balance msg_value in_msg_body sender_address cs + LDVARUINT16 // my_balance msg_value in_msg_body sender_address _54 _53 + NIP // my_balance msg_value in_msg_body sender_address cs + 1 PUSHINT // my_balance msg_value in_msg_body sender_address cs _22=1 + SDSKIPFIRST // my_balance msg_value in_msg_body sender_address cs + LDVARUINT16 // my_balance msg_value in_msg_body sender_address _56 _55 + NIP // my_balance msg_value in_msg_body sender_address cs + LDVARUINT16 // my_balance msg_value in_msg_body sender_address _58 _57 + DROP // my_balance msg_value in_msg_body sender_address _27 + 3 PUSHINT // my_balance msg_value in_msg_body sender_address _27 _29=3 + 1 MULRSHIFT# // my_balance msg_value in_msg_body sender_address fwd_fee + s0 s2 XCHG // my_balance msg_value fwd_fee sender_address in_msg_body + 32 LDU // my_balance msg_value fwd_fee sender_address op in_msg_body + 0xf8a7ea5 PUSHINT // my_balance msg_value fwd_fee sender_address op in_msg_body _36 + s2 s(-1) PUXC // my_balance msg_value fwd_fee sender_address op in_msg_body op _36 + EQUAL // my_balance msg_value fwd_fee sender_address op in_msg_body _37 + IFJMP:<{ // my_balance msg_value fwd_fee sender_address op in_msg_body + NIP + s4 POP // in_msg_body msg_value fwd_fee sender_address + -ROT // in_msg_body sender_address msg_value fwd_fee + send_tokens CALLDICT + }> // my_balance msg_value fwd_fee sender_address op in_msg_body + 0x178d4519 PUSHINT // my_balance msg_value fwd_fee sender_address op in_msg_body _39 + s2 s(-1) PUXC // my_balance msg_value fwd_fee sender_address op in_msg_body op _39 + EQUAL // my_balance msg_value fwd_fee sender_address op in_msg_body _40 + IFJMP:<{ // my_balance msg_value fwd_fee sender_address op in_msg_body + NIP // my_balance msg_value fwd_fee sender_address in_msg_body + s4 s4 s4 XCHG3 + s0 s3 XCHG // in_msg_body sender_address my_balance fwd_fee msg_value + receive_tokens CALLDICT + }> // my_balance msg_value fwd_fee sender_address op in_msg_body + s5 POP // in_msg_body msg_value fwd_fee sender_address op + 0x595f07bc PUSHINT // in_msg_body msg_value fwd_fee sender_address op _42 + EQUAL // in_msg_body msg_value fwd_fee sender_address _43 + IFJMP:<{ // in_msg_body msg_value fwd_fee sender_address + -ROT // in_msg_body sender_address msg_value fwd_fee + burn_tokens CALLDICT + }> // in_msg_body msg_value fwd_fee sender_address + 4 BLKDROP // + 16 PUSHPOW2DEC // _45=65535 + THROWANY + }> + get_wallet_data PROC:<{ + // + load_data INLINECALLDICT // _1 _2 _3 _4 + }> +}END>c diff --git a/contracts/imports/new-wton.fif b/contracts/imports/new-wton.fif new file mode 100644 index 0000000..7e93395 --- /dev/null +++ b/contracts/imports/new-wton.fif @@ -0,0 +1,36 @@ +#!/usr/bin/fift -s +"TonUtil.fif" include +"Asm.fif" include + + +"jetton-wallet.boc" file>B B>boc =: ft_code + +<{ + SETCP0 ACCEPT + now PUSHINT + "jetton-minter.fif" include PUSHREF SETCODE +}>s =: contract_code + + =: contract_storage + +0 =: wc + + ref, contract_storage ref, b> +dup =: state_init +dup hashu wc swap 2constant contract_addr + +."Contract address = " contract_addr .addr cr + +contract_addr "wton.addr" save-address-verbose + +."Non-bounceable address (for init): " contract_addr 7 .Addr cr +."Bounceable address (for later access): " contract_addr 6 .Addr cr + + + =: init_message + + + +2 boc+>B +"wton-query.boc" tuck B>file +."(Saved collection contract creating query to file " type .")" cr diff --git a/contracts/imports/print-hex.fif b/contracts/imports/print-hex.fif new file mode 100644 index 0000000..61e8cc0 --- /dev/null +++ b/contracts/imports/print-hex.fif @@ -0,0 +1,31 @@ +#!/usr/bin/fift -s +"TonUtil.fif" include +"Asm.fif" include + +."jetton-minter:" cr + +"jetton-minter.fif" include +2 boc+>B dup Bx. cr + +."jetton-wallet:" cr + +"jetton-wallet.fif" include +2 boc+>B dup Bx. cr + + +."jetton-minter-ICO:" cr + +"jetton-minter-ICO.fif" include +2 boc+>B dup Bx. cr + + +."jetton-minter-discoverable:" cr + +"jetton-minter-discoverable.fif" include +2 boc+>B dup Bx. cr + + +."jetton-discovery:" cr + +"jetton-discovery.fif" include +2 boc+>B dup Bx. cr diff --git a/contracts/imports/send-token.fif b/contracts/imports/send-token.fif new file mode 100644 index 0000000..ce9439d --- /dev/null +++ b/contracts/imports/send-token.fif @@ -0,0 +1,10 @@ +"Asm.fif" include +"TonUtil.fif" include +smca 2drop Addr, +"EQDkZIvi6fkgNVxLOgw5hzquGhxhUvhvJ4B836p-NQ-iLKCv" $>smca 2drop Addr, +0 1 u, +1 Gram, +0 1 u, +b> + diff --git a/contracts/imports/wton.addr b/contracts/imports/wton.addr new file mode 100644 index 0000000..9e4d0e4 Binary files /dev/null and b/contracts/imports/wton.addr differ diff --git a/contracts/jetton-discovery.fc b/contracts/jetton-discovery.fc new file mode 100644 index 0000000..d07050a --- /dev/null +++ b/contracts/jetton-discovery.fc @@ -0,0 +1,70 @@ +;; Jettons discovery smart contract for the non-discoverable Jettons + +;; 6098(computational_gas_price) * 1000(cur_gas_price) = 6098000 +;; ceil(6098000) = 10000000 ~= 0.01 TON +int provide_address_gas_consumption() asm "10000000 PUSHINT"; + +;; storage scheme +;; storage#_ jetton_minter_address:MsgAddress jetton_wallet_code:^Cell = Storage; + +(slice, cell) load_data() inline { + slice ds = get_data().begin_parse(); + return ( + ds~load_msg_addr(), ;; jetton_minter_address + ds~load_ref() ;; jetton_wallet_code + ); +} + +() recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure { + if (in_msg_body.slice_empty?()) { ;; ignore empty messages + return (); + } + + slice cs = in_msg_full.begin_parse(); + int flags = cs~load_uint(4); + + if (flags & 1) { ;; ignore all bounced messages + return (); + } + + slice sender_address = cs~load_msg_addr(); + cs~load_msg_addr(); ;; skip dst + cs~load_coins(); ;; skip value + cs~skip_bits(1); ;; skip extracurrency collection + cs~load_coins(); ;; skip ihr_fee + int fwd_fee = muldiv(cs~load_coins(), 3, 2); ;; we use message fwd_fee for estimation of forward_payload costs + + int op = in_msg_body~load_uint(32); + int query_id = in_msg_body~load_uint(64); + + if (op == op::provide_wallet_address()) { + throw_unless(75, msg_value > fwd_fee + provide_address_gas_consumption()); + + (slice jetton_minter_address, cell jetton_wallet_code) = load_data(); + + slice owner_address = in_msg_body~load_msg_addr(); + int include_address? = in_msg_body~load_uint(1); + + cell included_address = include_address? + ? begin_cell().store_slice(owner_address).end_cell() + : null(); + + var msg = begin_cell() + .store_uint(0x18, 6) + .store_slice(sender_address) + .store_coins(0) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(op::take_wallet_address(), 32) + .store_uint(query_id, 64); + + if (is_resolvable?(owner_address)) { + msg = msg.store_slice(calculate_user_jetton_wallet_address(owner_address, jetton_minter_address, jetton_wallet_code)); + } else { + msg = msg.store_uint(0, 2); ;; addr_none + } + send_raw_message(msg.store_maybe_ref(included_address).end_cell(), 64); + return (); + } + + throw(0xffff); +} \ No newline at end of file diff --git a/contracts/jetton-minter-ICO.fc b/contracts/jetton-minter-ICO.fc new file mode 100644 index 0000000..7eac70d --- /dev/null +++ b/contracts/jetton-minter-ICO.fc @@ -0,0 +1,121 @@ +;; Jettons minter smart contract + +;; storage scheme +;; storage#_ total_supply:Coins admin_address:MsgAddress content:^Cell jetton_wallet_code:^Cell = Storage; + +(int, slice, cell, cell) load_data() inline { + slice ds = get_data().begin_parse(); + return ( + ds~load_coins(), ;; total_supply + ds~load_msg_addr(), ;; admin_address + ds~load_ref(), ;; content + ds~load_ref() ;; jetton_wallet_code + ); +} + +() save_data(int total_supply, slice admin_address, cell content, cell jetton_wallet_code) impure inline { + set_data(begin_cell() + .store_coins(total_supply) + .store_slice(admin_address) + .store_ref(content) + .store_ref(jetton_wallet_code) + .end_cell() + ); +} + +() mint_tokens(slice to_address, cell jetton_wallet_code, int amount, cell master_msg) impure { + cell state_init = calculate_jetton_wallet_state_init(to_address, my_address(), jetton_wallet_code); + slice to_wallet_address = calculate_jetton_wallet_address(state_init); + var msg = begin_cell() + .store_uint(0x18, 6) + .store_slice(to_wallet_address) + .store_coins(amount) + .store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1) + .store_ref(state_init) + .store_ref(master_msg); + send_raw_message(msg.end_cell(), 1); ;; pay transfer fees separately, revert on errors +} + +() recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure { + slice cs = in_msg_full.begin_parse(); + int flags = cs~load_uint(4); + + if (flags & 1) { ;; ignore all bounced messages + return (); + } + slice sender_address = cs~load_msg_addr(); + + (int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data(); + + if (in_msg_body.slice_empty?()) { ;; buy jettons for Toncoin + + int amount = 10000000; ;; for mint message + int buy_amount = msg_value - amount; + throw_unless(76, buy_amount > 0); + + int jetton_amount = buy_amount; ;; rate 1 jetton = 1 toncoin; multiply to price here + + var master_msg = begin_cell() + .store_uint(op::internal_transfer(), 32) + .store_uint(0, 64) ;; quert_id + .store_coins(jetton_amount) + .store_slice(my_address()) ;; from_address + .store_slice(sender_address) ;; response_address + .store_coins(0) ;; no forward_amount + .store_uint(0, 1) ;; forward_payload in this slice, not separate cell + .end_cell(); + + mint_tokens(sender_address, jetton_wallet_code, amount, master_msg); + save_data(total_supply + jetton_amount, admin_address, content, jetton_wallet_code); + return (); + } + + int op = in_msg_body~load_uint(32); + int query_id = in_msg_body~load_uint(64); + + if (op == op::mint()) { + throw_unless(73, equal_slices(sender_address, admin_address)); + slice to_address = in_msg_body~load_msg_addr(); + int amount = in_msg_body~load_coins(); + cell master_msg = in_msg_body~load_ref(); + slice master_msg_cs = master_msg.begin_parse(); + master_msg_cs~skip_bits(32 + 64); ;; op + query_id + int jetton_amount = master_msg_cs~load_coins(); + mint_tokens(to_address, jetton_wallet_code, amount, master_msg); + save_data(total_supply + jetton_amount, admin_address, content, jetton_wallet_code); + return (); + } + + if (op == op::burn_notification()) { + int jetton_amount = in_msg_body~load_coins(); + slice from_address = in_msg_body~load_msg_addr(); + throw_unless(74, + equal_slices(calculate_user_jetton_wallet_address(from_address, my_address(), jetton_wallet_code), sender_address) + ); + save_data(total_supply - jetton_amount, admin_address, content, jetton_wallet_code); + slice response_address = in_msg_body~load_msg_addr(); + if (response_address.preload_uint(2) != 0) { + var msg = begin_cell() + .store_uint(0x10, 6) ;; nobounce - int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool src:MsgAddress -> 011000 + .store_slice(response_address) + .store_coins(0) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(op::excesses(), 32) + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 2 + 64); + } + return (); + } + + throw(0xffff); +} + +(int, int, slice, cell, cell) get_jetton_data() method_id { + (int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data(); + return (total_supply, -1, admin_address, content, jetton_wallet_code); +} + +slice get_wallet_address(slice owner_address) method_id { + (int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data(); + return calculate_user_jetton_wallet_address(owner_address, my_address(), jetton_wallet_code); +} diff --git a/contracts/jetton-minter-discoverable.fc b/contracts/jetton-minter-discoverable.fc new file mode 100644 index 0000000..422d7ad --- /dev/null +++ b/contracts/jetton-minter-discoverable.fc @@ -0,0 +1,150 @@ +;; Jettons discoverable smart contract + +;; 6905(computational_gas_price) * 1000(cur_gas_price) = 6905000 +;; ceil(6905000) = 10000000 ~= 0.01 TON +int provide_address_gas_consumption() asm "10000000 PUSHINT"; + +;; storage scheme +;; storage#_ total_supply:Coins admin_address:MsgAddress content:^Cell jetton_wallet_code:^Cell = Storage; + +(int, slice, cell, cell) load_data() inline { + slice ds = get_data().begin_parse(); + return ( + ds~load_coins(), ;; total_supply + ds~load_msg_addr(), ;; admin_address + ds~load_ref(), ;; content + ds~load_ref() ;; jetton_wallet_code + ); +} + +() save_data(int total_supply, slice admin_address, cell content, cell jetton_wallet_code) impure inline { + set_data(begin_cell() + .store_coins(total_supply) + .store_slice(admin_address) + .store_ref(content) + .store_ref(jetton_wallet_code) + .end_cell() + ); +} + +() mint_tokens(slice to_address, cell jetton_wallet_code, int amount, cell master_msg) impure { + cell state_init = calculate_jetton_wallet_state_init(to_address, my_address(), jetton_wallet_code); + slice to_wallet_address = calculate_jetton_wallet_address(state_init); + var msg = begin_cell() + .store_uint(0x18, 6) + .store_slice(to_wallet_address) + .store_coins(amount) + .store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1) + .store_ref(state_init) + .store_ref(master_msg); + send_raw_message(msg.end_cell(), 1); ;; pay transfer fees separately, revert on errors +} + +() recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure { + if (in_msg_body.slice_empty?()) { ;; ignore empty messages + return (); + } + slice cs = in_msg_full.begin_parse(); + int flags = cs~load_uint(4); + + if (flags & 1) { ;; ignore all bounced messages + return (); + } + slice sender_address = cs~load_msg_addr(); + cs~load_msg_addr(); ;; skip dst + cs~load_coins(); ;; skip value + cs~skip_bits(1); ;; skip extracurrency collection + cs~load_coins(); ;; skip ihr_fee + int fwd_fee = muldiv(cs~load_coins(), 3, 2); ;; we use message fwd_fee for estimation of forward_payload costs + + int op = in_msg_body~load_uint(32); + int query_id = in_msg_body~load_uint(64); + + (int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data(); + + if (op == op::mint()) { + throw_unless(73, equal_slices(sender_address, admin_address)); + slice to_address = in_msg_body~load_msg_addr(); + int amount = in_msg_body~load_coins(); + cell master_msg = in_msg_body~load_ref(); + slice master_msg_cs = master_msg.begin_parse(); + master_msg_cs~skip_bits(32 + 64); ;; op + query_id + int jetton_amount = master_msg_cs~load_coins(); + mint_tokens(to_address, jetton_wallet_code, amount, master_msg); + save_data(total_supply + jetton_amount, admin_address, content, jetton_wallet_code); + return (); + } + + if (op == op::burn_notification()) { + int jetton_amount = in_msg_body~load_coins(); + slice from_address = in_msg_body~load_msg_addr(); + throw_unless(74, + equal_slices(calculate_user_jetton_wallet_address(from_address, my_address(), jetton_wallet_code), sender_address) + ); + save_data(total_supply - jetton_amount, admin_address, content, jetton_wallet_code); + slice response_address = in_msg_body~load_msg_addr(); + if (response_address.preload_uint(2) != 0) { + var msg = begin_cell() + .store_uint(0x10, 6) ;; nobounce - int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool src:MsgAddress -> 011000 + .store_slice(response_address) + .store_coins(0) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(op::excesses(), 32) + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 2 + 64); + } + return (); + } + + if (op == op::provide_wallet_address()) { + throw_unless(75, msg_value > fwd_fee + provide_address_gas_consumption()); + + slice owner_address = in_msg_body~load_msg_addr(); + int include_address? = in_msg_body~load_uint(1); + + cell included_address = include_address? + ? begin_cell().store_slice(owner_address).end_cell() + : null(); + + var msg = begin_cell() + .store_uint(0x18, 6) + .store_slice(sender_address) + .store_coins(0) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(op::take_wallet_address(), 32) + .store_uint(query_id, 64); + + if (is_resolvable?(owner_address)) { + msg = msg.store_slice(calculate_user_jetton_wallet_address(owner_address, my_address(), jetton_wallet_code)); + } else { + msg = msg.store_uint(0, 2); ;; addr_none + } + send_raw_message(msg.store_maybe_ref(included_address).end_cell(), 64); + return (); + } + + if (op == 3) { ;; change admin + throw_unless(73, equal_slices(sender_address, admin_address)); + slice new_admin_address = in_msg_body~load_msg_addr(); + save_data(total_supply, new_admin_address, content, jetton_wallet_code); + return (); + } + + if (op == 4) { ;; change content, delete this for immutable tokens + throw_unless(73, equal_slices(sender_address, admin_address)); + save_data(total_supply, admin_address, in_msg_body~load_ref(), jetton_wallet_code); + return (); + } + + throw(0xffff); +} + +(int, int, slice, cell, cell) get_jetton_data() method_id { + (int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data(); + return (total_supply, -1, admin_address, content, jetton_wallet_code); +} + +slice get_wallet_address(slice owner_address) method_id { + (int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data(); + return calculate_user_jetton_wallet_address(owner_address, my_address(), jetton_wallet_code); +} diff --git a/contracts/jetton-minter.fc b/contracts/jetton-minter.fc new file mode 100644 index 0000000..97796da --- /dev/null +++ b/contracts/jetton-minter.fc @@ -0,0 +1,117 @@ +;; It is recommended to use https://github.com/ton-blockchain/token-contract/blob/main/ft/jetton-minter-discoverable.fc +;; instead of this contract, see https://github.com/ton-blockchain/TEPs/blob/master/text/0089-jetton-wallet-discovery.md + +;; Jettons minter smart contract + +;; storage scheme +;; storage#_ total_supply:Coins admin_address:MsgAddress content:^Cell jetton_wallet_code:^Cell = Storage; + +(int, slice, cell, cell) load_data() inline { + slice ds = get_data().begin_parse(); + return ( + ds~load_coins(), ;; total_supply + ds~load_msg_addr(), ;; admin_address + ds~load_ref(), ;; content + ds~load_ref() ;; jetton_wallet_code + ); +} + +() save_data(int total_supply, slice admin_address, cell content, cell jetton_wallet_code) impure inline { + set_data(begin_cell() + .store_coins(total_supply) + .store_slice(admin_address) + .store_ref(content) + .store_ref(jetton_wallet_code) + .end_cell() + ); +} + +() mint_tokens(slice to_address, cell jetton_wallet_code, int amount, cell master_msg) impure { + cell state_init = calculate_jetton_wallet_state_init(to_address, my_address(), jetton_wallet_code); + slice to_wallet_address = calculate_jetton_wallet_address(state_init); + var msg = begin_cell() + .store_uint(0x18, 6) + .store_slice(to_wallet_address) + .store_coins(amount) + .store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1) + .store_ref(state_init) + .store_ref(master_msg); + send_raw_message(msg.end_cell(), 1); ;; pay transfer fees separately, revert on errors +} + +() recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure { + if (in_msg_body.slice_empty?()) { ;; ignore empty messages + return (); + } + slice cs = in_msg_full.begin_parse(); + int flags = cs~load_uint(4); + + if (flags & 1) { ;; ignore all bounced messages + return (); + } + slice sender_address = cs~load_msg_addr(); + + int op = in_msg_body~load_uint(32); + int query_id = in_msg_body~load_uint(64); + + (int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data(); + + if (op == op::mint()) { + throw_unless(73, equal_slices(sender_address, admin_address)); + slice to_address = in_msg_body~load_msg_addr(); + int amount = in_msg_body~load_coins(); + cell master_msg = in_msg_body~load_ref(); + slice master_msg_cs = master_msg.begin_parse(); + master_msg_cs~skip_bits(32 + 64); ;; op + query_id + int jetton_amount = master_msg_cs~load_coins(); + mint_tokens(to_address, jetton_wallet_code, amount, master_msg); + save_data(total_supply + jetton_amount, admin_address, content, jetton_wallet_code); + return (); + } + + if (op == op::burn_notification()) { + int jetton_amount = in_msg_body~load_coins(); + slice from_address = in_msg_body~load_msg_addr(); + throw_unless(74, + equal_slices(calculate_user_jetton_wallet_address(from_address, my_address(), jetton_wallet_code), sender_address) + ); + save_data(total_supply - jetton_amount, admin_address, content, jetton_wallet_code); + slice response_address = in_msg_body~load_msg_addr(); + if (response_address.preload_uint(2) != 0) { + var msg = begin_cell() + .store_uint(0x10, 6) ;; nobounce - int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool src:MsgAddress -> 011000 + .store_slice(response_address) + .store_coins(0) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(op::excesses(), 32) + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 2 + 64); + } + return (); + } + + if (op == 3) { ;; change admin + throw_unless(73, equal_slices(sender_address, admin_address)); + slice new_admin_address = in_msg_body~load_msg_addr(); + save_data(total_supply, new_admin_address, content, jetton_wallet_code); + return (); + } + + if (op == 4) { ;; change content, delete this for immutable tokens + throw_unless(73, equal_slices(sender_address, admin_address)); + save_data(total_supply, admin_address, in_msg_body~load_ref(), jetton_wallet_code); + return (); + } + + throw(0xffff); +} + +(int, int, slice, cell, cell) get_jetton_data() method_id { + (int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data(); + return (total_supply, -1, admin_address, content, jetton_wallet_code); +} + +slice get_wallet_address(slice owner_address) method_id { + (int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data(); + return calculate_user_jetton_wallet_address(owner_address, my_address(), jetton_wallet_code); +} diff --git a/contracts/jetton-utils.fc b/contracts/jetton-utils.fc new file mode 100644 index 0000000..296816a --- /dev/null +++ b/contracts/jetton-utils.fc @@ -0,0 +1,30 @@ +cell pack_jetton_wallet_data(int balance, slice owner_address, slice jetton_master_address, cell jetton_wallet_code) inline { + return begin_cell() + .store_coins(balance) + .store_slice(owner_address) + .store_slice(jetton_master_address) + .store_ref(jetton_wallet_code) + .end_cell(); +} + +cell calculate_jetton_wallet_state_init(slice owner_address, slice jetton_master_address, cell jetton_wallet_code) inline { + return begin_cell() + .store_uint(0, 2) + .store_dict(jetton_wallet_code) + .store_dict(pack_jetton_wallet_data(0, owner_address, jetton_master_address, jetton_wallet_code)) + .store_uint(0, 1) + .end_cell(); +} + +slice calculate_jetton_wallet_address(cell state_init) inline { + return begin_cell().store_uint(4, 3) + .store_int(workchain(), 8) + .store_uint(cell_hash(state_init), 256) + .end_cell() + .begin_parse(); +} + +slice calculate_user_jetton_wallet_address(slice owner_address, slice jetton_master_address, cell jetton_wallet_code) inline { + return calculate_jetton_wallet_address(calculate_jetton_wallet_state_init(owner_address, jetton_master_address, jetton_wallet_code)); +} + diff --git a/contracts/jetton-wallet.fc b/contracts/jetton-wallet.fc new file mode 100644 index 0000000..49554fa --- /dev/null +++ b/contracts/jetton-wallet.fc @@ -0,0 +1,248 @@ +;; Jetton Wallet Smart Contract + +{- + +NOTE that this tokens can be transferred within the same workchain. + +This is suitable for most tokens, if you need tokens transferable between workchains there are two solutions: + +1) use more expensive but universal function to calculate message forward fee for arbitrary destination (see `misc/forward-fee-calc.cs`) + +2) use token holder proxies in target workchain (that way even 'non-universal' token can be used from any workchain) + +-} + +int min_tons_for_storage() asm "10000000 PUSHINT"; ;; 0.01 TON +;; Note that 2 * gas_consumptions is expected to be able to cover fees on both wallets (sender and receiver) +;; and also constant fees on inter-wallet interaction, in particular fwd fee on state_init transfer +;; that means that you need to reconsider this fee when: +;; a) jetton logic become more gas-heavy +;; b) jetton-wallet code (sent with inter-wallet message) become larger or smaller +;; c) global fee changes / different workchain +int gas_consumption() asm "15000000 PUSHINT"; ;; 0.015 TON + +{- + Storage + storage#_ balance:Coins owner_address:MsgAddressInt jetton_master_address:MsgAddressInt jetton_wallet_code:^Cell = Storage; +-} + +(int, slice, slice, cell) load_data() inline { + slice ds = get_data().begin_parse(); + return (ds~load_coins(), ds~load_msg_addr(), ds~load_msg_addr(), ds~load_ref()); +} + +() save_data (int balance, slice owner_address, slice jetton_master_address, cell jetton_wallet_code) impure inline { + set_data(pack_jetton_wallet_data(balance, owner_address, jetton_master_address, jetton_wallet_code)); +} + +{- + transfer query_id:uint64 amount:(VarUInteger 16) destination:MsgAddress + response_destination:MsgAddress custom_payload:(Maybe ^Cell) + forward_ton_amount:(VarUInteger 16) forward_payload:(Either Cell ^Cell) + = InternalMsgBody; + internal_transfer query_id:uint64 amount:(VarUInteger 16) from:MsgAddress + response_address:MsgAddress + forward_ton_amount:(VarUInteger 16) + forward_payload:(Either Cell ^Cell) + = InternalMsgBody; +-} + +() send_tokens (slice in_msg_body, slice sender_address, int msg_value, int fwd_fee) impure { + int query_id = in_msg_body~load_uint(64); + int jetton_amount = in_msg_body~load_coins(); + slice to_owner_address = in_msg_body~load_msg_addr(); + force_chain(to_owner_address); + (int balance, slice owner_address, slice jetton_master_address, cell jetton_wallet_code) = load_data(); + balance -= jetton_amount; + + throw_unless(705, equal_slices(owner_address, sender_address)); + throw_unless(706, balance >= 0); + + cell state_init = calculate_jetton_wallet_state_init(to_owner_address, jetton_master_address, jetton_wallet_code); + slice to_wallet_address = calculate_jetton_wallet_address(state_init); + slice response_address = in_msg_body~load_msg_addr(); + cell custom_payload = in_msg_body~load_dict(); + int forward_ton_amount = in_msg_body~load_coins(); + throw_unless(708, slice_bits(in_msg_body) >= 1); + slice either_forward_payload = in_msg_body; + var msg = begin_cell() + .store_uint(0x18, 6) + .store_slice(to_wallet_address) + .store_coins(0) + .store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1) + .store_ref(state_init); + var msg_body = begin_cell() + .store_uint(op::internal_transfer(), 32) + .store_uint(query_id, 64) + .store_coins(jetton_amount) + .store_slice(owner_address) + .store_slice(response_address) + .store_coins(forward_ton_amount) + .store_slice(either_forward_payload) + .end_cell(); + + msg = msg.store_ref(msg_body); + int fwd_count = forward_ton_amount ? 2 : 1; + throw_unless(709, msg_value > + forward_ton_amount + + ;; 3 messages: wal1->wal2, wal2->owner, wal2->response + ;; but last one is optional (it is ok if it fails) + fwd_count * fwd_fee + + (2 * gas_consumption() + min_tons_for_storage())); + ;; universal message send fee calculation may be activated here + ;; by using this instead of fwd_fee + ;; msg_fwd_fee(to_wallet, msg_body, state_init, 15) + + send_raw_message(msg.end_cell(), 64); ;; revert on errors + save_data(balance, owner_address, jetton_master_address, jetton_wallet_code); +} + +{- + internal_transfer query_id:uint64 amount:(VarUInteger 16) from:MsgAddress + response_address:MsgAddress + forward_ton_amount:(VarUInteger 16) + forward_payload:(Either Cell ^Cell) + = InternalMsgBody; +-} + +() receive_tokens (slice in_msg_body, slice sender_address, int my_ton_balance, int fwd_fee, int msg_value) impure { + ;; NOTE we can not allow fails in action phase since in that case there will be + ;; no bounce. Thus check and throw in computation phase. + (int balance, slice owner_address, slice jetton_master_address, cell jetton_wallet_code) = load_data(); + int query_id = in_msg_body~load_uint(64); + int jetton_amount = in_msg_body~load_coins(); + balance += jetton_amount; + slice from_address = in_msg_body~load_msg_addr(); + slice response_address = in_msg_body~load_msg_addr(); + throw_unless(707, + equal_slices(jetton_master_address, sender_address) + | + equal_slices(calculate_user_jetton_wallet_address(from_address, jetton_master_address, jetton_wallet_code), sender_address) + ); + int forward_ton_amount = in_msg_body~load_coins(); + + int ton_balance_before_msg = my_ton_balance - msg_value; + int storage_fee = min_tons_for_storage() - min(ton_balance_before_msg, min_tons_for_storage()); + msg_value -= (storage_fee + gas_consumption()); + if(forward_ton_amount) { + msg_value -= (forward_ton_amount + fwd_fee); + slice either_forward_payload = in_msg_body; + + var msg_body = begin_cell() + .store_uint(op::transfer_notification(), 32) + .store_uint(query_id, 64) + .store_coins(jetton_amount) + .store_slice(from_address) + .store_slice(either_forward_payload) + .end_cell(); + + var msg = begin_cell() + .store_uint(0x10, 6) ;; we should not bounce here cause receiver can have uninitialized contract + .store_slice(owner_address) + .store_coins(forward_ton_amount) + .store_uint(1, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_ref(msg_body); + + send_raw_message(msg.end_cell(), 1); + } + + if ((response_address.preload_uint(2) != 0) & (msg_value > 0)) { + var msg = begin_cell() + .store_uint(0x10, 6) ;; nobounce - int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool src:MsgAddress -> 010000 + .store_slice(response_address) + .store_coins(msg_value) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(op::excesses(), 32) + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 2); + } + + save_data(balance, owner_address, jetton_master_address, jetton_wallet_code); +} + +() burn_tokens (slice in_msg_body, slice sender_address, int msg_value, int fwd_fee) impure { + ;; NOTE we can not allow fails in action phase since in that case there will be + ;; no bounce. Thus check and throw in computation phase. + (int balance, slice owner_address, slice jetton_master_address, cell jetton_wallet_code) = load_data(); + int query_id = in_msg_body~load_uint(64); + int jetton_amount = in_msg_body~load_coins(); + slice response_address = in_msg_body~load_msg_addr(); + ;; ignore custom payload + ;; slice custom_payload = in_msg_body~load_dict(); + balance -= jetton_amount; + throw_unless(705, equal_slices(owner_address, sender_address)); + throw_unless(706, balance >= 0); + throw_unless(707, msg_value > fwd_fee + 2 * gas_consumption()); + + var msg_body = begin_cell() + .store_uint(op::burn_notification(), 32) + .store_uint(query_id, 64) + .store_coins(jetton_amount) + .store_slice(owner_address) + .store_slice(response_address) + .end_cell(); + + var msg = begin_cell() + .store_uint(0x18, 6) + .store_slice(jetton_master_address) + .store_coins(0) + .store_uint(1, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_ref(msg_body); + + send_raw_message(msg.end_cell(), 64); + + save_data(balance, owner_address, jetton_master_address, jetton_wallet_code); +} + +() on_bounce (slice in_msg_body) impure { + in_msg_body~skip_bits(32); ;; 0xFFFFFFFF + (int balance, slice owner_address, slice jetton_master_address, cell jetton_wallet_code) = load_data(); + int op = in_msg_body~load_uint(32); + throw_unless(709, (op == op::internal_transfer()) | (op == op::burn_notification())); + int query_id = in_msg_body~load_uint(64); + int jetton_amount = in_msg_body~load_coins(); + balance += jetton_amount; + save_data(balance, owner_address, jetton_master_address, jetton_wallet_code); +} + +() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure { + if (in_msg_body.slice_empty?()) { ;; ignore empty messages + return (); + } + + slice cs = in_msg_full.begin_parse(); + int flags = cs~load_uint(4); + if (flags & 1) { + on_bounce(in_msg_body); + return (); + } + slice sender_address = cs~load_msg_addr(); + cs~load_msg_addr(); ;; skip dst + cs~load_coins(); ;; skip value + cs~skip_bits(1); ;; skip extracurrency collection + cs~load_coins(); ;; skip ihr_fee + int fwd_fee = muldiv(cs~load_coins(), 3, 2); ;; we use message fwd_fee for estimation of forward_payload costs + + int op = in_msg_body~load_uint(32); + + if (op == op::transfer()) { ;; outgoing transfer + send_tokens(in_msg_body, sender_address, msg_value, fwd_fee); + return (); + } + + if (op == op::internal_transfer()) { ;; incoming transfer + receive_tokens(in_msg_body, sender_address, my_balance, fwd_fee, msg_value); + return (); + } + + if (op == op::burn()) { ;; burn + burn_tokens(in_msg_body, sender_address, msg_value, fwd_fee); + return (); + } + + throw(0xffff); +} + +(int, slice, slice, cell) get_wallet_data() method_id { + return load_data(); +} diff --git a/contracts/op-codes.fc b/contracts/op-codes.fc new file mode 100644 index 0000000..3b0df04 --- /dev/null +++ b/contracts/op-codes.fc @@ -0,0 +1,9 @@ +int op::transfer() asm "0xf8a7ea5 PUSHINT"; +int op::transfer_notification() asm "0x7362d09c PUSHINT"; +int op::internal_transfer() asm "0x178d4519 PUSHINT"; +int op::excesses() asm "0xd53276db PUSHINT"; +int op::burn() asm "0x595f07bc PUSHINT"; +int op::burn_notification() asm "0x7bdd97de PUSHINT"; + +;; Minter +int op::mint() asm "21 PUSHINT"; diff --git a/contracts/params.fc b/contracts/params.fc new file mode 100644 index 0000000..e28eac4 --- /dev/null +++ b/contracts/params.fc @@ -0,0 +1,6 @@ +int workchain() asm "0 PUSHINT"; + +() force_chain(slice addr) impure { + (int wc, _) = parse_std_addr(addr); + throw_unless(333, wc == workchain()); +} \ No newline at end of file diff --git a/tests/Fibonacci.spec.ts b/tests/Fibonacci.spec.ts index 1a0291b..63445a8 100644 --- a/tests/Fibonacci.spec.ts +++ b/tests/Fibonacci.spec.ts @@ -20,12 +20,12 @@ describe('[Fibonacci]', () => { deployer = await blockchain.treasury('deployer'); }); - it('[Fibonacci] deploy', async () => { + it('[Fibonacci] deploys', async () => { const deployResult = await contract.sendDeploy(deployer.getSender(), toNano('0.05')); expect(typeof deployResult.transactions[0].now).toBe('number'); }); - it('[Fibonacci] trigger fibonacci sequence', async () => { + it('[Fibonacci] triggers fibonacci sequence', async () => { for (const vals of [ [1, 0], [1, 1], diff --git a/tests/OneThousandTokenTransfers.spec.ts b/tests/OneThousandTokenTransfers.spec.ts new file mode 100644 index 0000000..a88238d --- /dev/null +++ b/tests/OneThousandTokenTransfers.spec.ts @@ -0,0 +1,165 @@ +import { Blockchain, SandboxContract, TreasuryContract, internal } from '@ton/sandbox'; +import { Cell, toNano, beginCell, Address } from '@ton/core'; +import { JettonWallet } from '../wrappers/JettonWallet'; +import { JettonMinter, jettonContentToCell } from '../wrappers/JettonMinter'; +import '@ton/test-utils'; +import { compile } from '@ton/blueprint'; + +/* + These tests check compliance with the TEP-74 and TEP-89, + but also checks some implementation details. + If you want to keep only TEP-74 and TEP-89 compliance tests, + you need to remove/modify the following tests: + mint tests (since minting is not covered by standard) + exit_codes + prove pathway +*/ + +//jetton params + +const fwd_fee = 1804014n, + gas_consumption = 15000000n, + min_tons_for_storage = 10000000n; +//let fwd_fee = 1804014n, gas_consumption = 14000000n, min_tons_for_storage = 10000000n; + +describe('[One thousand token transfers]', () => { + let jwallet_code = new Cell(); + let minter_code = new Cell(); + let blockchain: Blockchain; + let user1: SandboxContract; + let user2: SandboxContract; + let user3: SandboxContract; + let jettonMinter: SandboxContract; + let userWallet: any; + let defaultContent: Cell; + const transfers: { + sender: SandboxContract; + receiver: SandboxContract; + value: bigint; + }[] = []; + + beforeAll(async () => { + jwallet_code = await compile('JettonWallet'); + minter_code = await compile('JettonMinter'); + blockchain = await Blockchain.create(); + user1 = await blockchain.treasury('user1'); + user2 = await blockchain.treasury('user2'); + user3 = await blockchain.treasury('user3'); + defaultContent = jettonContentToCell({ type: 1, uri: 'https://testjetton.org/content.json' }); + jettonMinter = blockchain.openContract( + JettonMinter.createFromConfig( + { + admin: user1.address, + content: defaultContent, + wallet_code: jwallet_code, + }, + minter_code, + ), + ); + userWallet = async (address: Address) => + blockchain.openContract(JettonWallet.createFromAddress(await jettonMinter.getWalletAddress(address))); + + for (let i = 0; i < 1000; i += 1) { + if (Math.random() < 0.33) { + transfers.push({ + sender: user1 as unknown as SandboxContract, + receiver: user2 as unknown as SandboxContract, + value: BigInt(Math.round(Math.random() * 100)), + }); + } else if (Math.random() < 0.66) { + transfers.push({ + sender: user2 as unknown as SandboxContract, + receiver: user3 as unknown as SandboxContract, + value: BigInt(Math.round(Math.random() * 100)), + }); + } else { + transfers.push({ + sender: user3 as unknown as SandboxContract, + receiver: user1 as unknown as SandboxContract, + value: BigInt(Math.round(Math.random() * 100)), + }); + } + } + }); + + // implementation detail + it('[One thousand token transfers] deploys', async () => { + const deployResult = await jettonMinter.sendDeploy(user1.getSender(), toNano('100')); + + expect(deployResult.transactions).toHaveTransaction({ + from: user1.address, + to: jettonMinter.address, + deploy: true, + }); + }); + + it('[One thousand token transfers] mints initial 100B supply', async () => { + const initialTotalSupply = await jettonMinter.getTotalSupply(); + expect(initialTotalSupply).toBe(BigInt('0')); + const user1JettonWallet = await userWallet(user1.address); + const mintResult = await jettonMinter.sendMint( + user1.getSender(), + user1.address, + BigInt('100000000000'), + toNano('0.05'), + toNano('1'), + ); + expect(await jettonMinter.getTotalSupply()).toBe(BigInt('100000000000')); + }); + + it('[One thousand token transfers] user1 (deployer+minter) sends a portion to user2 and user3', async () => { + const user1JettonWallet = await userWallet(user1.address); + const user2JettonWallet = await userWallet(user2.address); + const user3JettonWallet = await userWallet(user3.address); + await user1JettonWallet.sendTransfer( + user1.getSender(), + toNano('0.1'), + BigInt('33000000000'), + user2.address, + user1.address, + null, + toNano('0.05'), + null, + ); + await user1JettonWallet.sendTransfer( + user1.getSender(), + toNano('0.1'), + BigInt('33000000000'), + user3.address, + user1.address, + null, + toNano('0.05'), + null, + ); + expect(await user2JettonWallet.getJettonBalance()).toEqual(BigInt('33000000000')); + expect(await user3JettonWallet.getJettonBalance()).toEqual(BigInt('33000000000')); + }); + + it('[One thousand token transfers] do the 10.000 transfers', async () => { + let i = 1; + for (const transfer of transfers) { + const senderJettonWallet = await userWallet(transfer.sender.address); + const receiverJettonWallet = await userWallet(transfer.receiver.address); + + const balanceReceiverBefore = await receiverJettonWallet.getJettonBalance(); + + await senderJettonWallet.sendTransfer( + transfer.sender.getSender(), + toNano('0.1'), + transfer.value, + transfer.receiver.address, + transfer.sender.address, + null, + toNano('0.05'), + null, + ); + expect(await await receiverJettonWallet.getJettonBalance()).toBe(balanceReceiverBefore + transfer.value); + i += 1; + if (i % 100 === 0 && process.argv.includes('--logs')) { + console.log( + `[One thousand token transfers] ok transfer no${i} ${transfer.sender.address} -> ${transfer.receiver.address} (${transfer.value})`, + ); + } + } + }); +}); diff --git a/tests/TenThousandsTransfers.spec.ts b/tests/TenThousandsTransfers.spec.ts index 0901ea4..7789189 100644 --- a/tests/TenThousandsTransfers.spec.ts +++ b/tests/TenThousandsTransfers.spec.ts @@ -50,9 +50,9 @@ describe('[Ten thousands transfers]', () => { const balanceReceiverAfter = await transfer.receiver.getBalance(); expect(expectedBalances.includes(balanceReceiverAfter)).toBe(true); i += 1; - if (i === 100 || i === 1000 || i % 1000 === 0) { + if (process.argv.includes('--logs') && (i === 100 || i === 1000 || i % 1000 === 0)) { console.log( - `ok transfer no${i} ${transfer.sender.address} -> ${transfer.receiver.address} (${transfer.value})`, + `[Ten thousands transfers] ok transfer no${i} ${transfer.sender.address} -> ${transfer.receiver.address} (${transfer.value})`, ); } } diff --git a/tests/utils.ts b/tests/utils.ts new file mode 100644 index 0000000..9ff20dd --- /dev/null +++ b/tests/utils.ts @@ -0,0 +1,142 @@ +import { Address, toNano, Cell } from '@ton/core'; + +export const randomAddress = (wc: number = 0) => { + const buf = Buffer.alloc(32); + for (let i = 0; i < buf.length; i++) { + buf[i] = Math.floor(Math.random() * 256); + } + return new Address(wc, buf); +}; + +export const differentAddress = (old: Address) => { + let newAddr: Address; + do { + newAddr = randomAddress(old.workChain); + } while (newAddr.equals(old)); + + return newAddr; +}; + +const getRandom = (min: number, max: number) => { + return Math.random() * (max - min) + min; +}; + +export const getRandomInt = (min: number, max: number) => { + return Math.round(getRandom(min, max)); +}; + +export const getRandomTon = (min: number, max: number): bigint => { + return toNano(getRandom(min, max).toFixed(9)); +}; + +export type InternalTransfer = { + from: Address | null; + response: Address | null; + amount: bigint; + forwardAmount: bigint; + payload: Cell | null; +}; +export type JettonTransfer = { + to: Address; + response_address: Address | null; + amount: bigint; + custom_payload: Cell | null; + forward_amount: bigint; + forward_payload: Cell | null; +}; + +export const parseTransfer = (body: Cell) => { + const ts = body.beginParse().skip(64 + 32); + return { + amount: ts.loadCoins(), + to: ts.loadAddress(), + response_address: ts.loadAddressAny(), + custom_payload: ts.loadMaybeRef(), + forward_amount: ts.loadCoins(), + forward_payload: ts.loadMaybeRef(), + }; +}; +export const parseInternalTransfer = (body: Cell) => { + const ts = body.beginParse().skip(64 + 32); + + return { + amount: ts.loadCoins(), + from: ts.loadAddressAny(), + response: ts.loadAddressAny(), + forwardAmount: ts.loadCoins(), + payload: ts.loadMaybeRef(), + }; +}; +type JettonTransferNotification = { + amount: bigint; + from: Address | null; + payload: Cell | null; +}; +export const parseTransferNotification = (body: Cell) => { + const bs = body.beginParse().skip(64 + 32); + return { + amount: bs.loadCoins(), + from: bs.loadAddressAny(), + payload: bs.loadMaybeRef(), + }; +}; + +type JettonBurnNotification = { + amount: bigint; + from: Address; + response_address: Address | null; +}; +export const parseBurnNotification = (body: Cell) => { + const ds = body.beginParse().skip(64 + 32); + const res = { + amount: ds.loadCoins(), + from: ds.loadAddress(), + response_address: ds.loadAddressAny(), + }; + + return res; +}; + +const testPartial = (cmp: any, match: any) => { + for (let key in match) { + if (!(key in cmp)) { + throw Error(`Unknown key ${key} in ${cmp}`); + } + + if (match[key] instanceof Address) { + if (!(cmp[key] instanceof Address)) { + return false; + } + if (!(match[key] as Address).equals(cmp[key])) { + return false; + } + } else if (match[key] instanceof Cell) { + if (!(cmp[key] instanceof Cell)) { + return false; + } + if (!(match[key] as Cell).equals(cmp[key])) { + return false; + } + } else if (match[key] !== cmp[key]) { + return false; + } + } + return true; +}; +export const testJettonBurnNotification = (body: Cell, match: Partial) => { + const res = parseBurnNotification(body); + return testPartial(res, match); +}; + +export const testJettonTransfer = (body: Cell, match: Partial) => { + const res = parseTransfer(body); + return testPartial(res, match); +}; +export const testJettonInternalTransfer = (body: Cell, match: Partial) => { + const res = parseInternalTransfer(body); + return testPartial(res, match); +}; +export const testJettonNotification = (body: Cell, match: Partial) => { + const res = parseTransferNotification(body); + return testPartial(res, match); +}; diff --git a/wrappers/JettonConstants.ts b/wrappers/JettonConstants.ts new file mode 100644 index 0000000..5e20e55 --- /dev/null +++ b/wrappers/JettonConstants.ts @@ -0,0 +1,28 @@ +export abstract class Op { + static transfer = 0xf8a7ea5; + static transfer_notification = 0x7362d09c; + static internal_transfer = 0x178d4519; + static excesses = 0xd53276db; + static burn = 0x595f07bc; + static burn_notification = 0x7bdd97de; + + static provide_wallet_address = 0x2c76b973; + static take_wallet_address = 0xd1735400; + static mint = 21; + static change_admin = 3; + static change_content = 4; +} + +export abstract class Errors { + static invalid_op = 709; + static not_admin = 73; + static unouthorized_burn = 74; + static discovery_fee_not_matched = 75; + static wrong_op = 0xffff; + static not_owner = 705; + static not_enough_ton = 709; + static not_enough_gas = 707; + static not_valid_wallet = 707; + static wrong_workchain = 333; + static balance_error = 706; +} diff --git a/wrappers/JettonMinter.compile.ts b/wrappers/JettonMinter.compile.ts new file mode 100644 index 0000000..0d85d80 --- /dev/null +++ b/wrappers/JettonMinter.compile.ts @@ -0,0 +1,12 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + targets: [ + 'contracts/imports/stdlib.fc', + 'contracts/params.fc', + 'contracts/op-codes.fc', + 'contracts/discovery-params.fc', + 'contracts/jetton-utils.fc', + 'contracts/jetton-minter-discoverable.fc', + ], +}; diff --git a/wrappers/JettonMinter.ts b/wrappers/JettonMinter.ts new file mode 100644 index 0000000..ccfde11 --- /dev/null +++ b/wrappers/JettonMinter.ts @@ -0,0 +1,215 @@ +import { + Address, + beginCell, + Cell, + Contract, + contractAddress, + ContractProvider, + Sender, + SendMode, + toNano, + internal as internal_relaxed, + storeMessageRelaxed, +} from '@ton/core'; + +import { Op } from './JettonConstants'; + +export type JettonMinterContent = { + type: 0 | 1; + uri: string; +}; + +export type JettonMinterConfig = { admin: Address; content: Cell; wallet_code: Cell }; + +export function jettonMinterConfigToCell(config: JettonMinterConfig): Cell { + return beginCell() + .storeCoins(0) + .storeAddress(config.admin) + .storeRef(config.content) + .storeRef(config.wallet_code) + .endCell(); +} + +export function jettonContentToCell(content: JettonMinterContent) { + return beginCell() + .storeUint(content.type, 8) + .storeStringTail(content.uri) //Snake logic under the hood + .endCell(); +} + +export class JettonMinter implements Contract { + constructor( + readonly address: Address, + readonly init?: { code: Cell; data: Cell }, + ) {} + + static createFromAddress(address: Address) { + return new JettonMinter(address); + } + + static createFromConfig(config: JettonMinterConfig, code: Cell, workchain = 0) { + const data = jettonMinterConfigToCell(config); + const init = { code, data }; + return new JettonMinter(contractAddress(workchain, init), init); + } + + async sendDeploy(provider: ContractProvider, via: Sender, value: bigint) { + await provider.internal(via, { + value, + sendMode: SendMode.PAY_GAS_SEPARATELY, + body: beginCell().endCell(), + }); + } + + protected static jettonInternalTransfer( + jetton_amount: bigint, + forward_ton_amount: bigint, + response_addr?: Address, + query_id: number | bigint = 0, + ) { + return beginCell() + .storeUint(Op.internal_transfer, 32) + .storeUint(query_id, 64) + .storeCoins(jetton_amount) + .storeAddress(null) + .storeAddress(response_addr) + .storeCoins(forward_ton_amount) + .storeBit(false) + .endCell(); + } + static mintMessage( + from: Address, + to: Address, + jetton_amount: bigint, + forward_ton_amount: bigint, + total_ton_amount: bigint, + query_id: number | bigint = 0, + ) { + const mintMsg = beginCell() + .storeUint(Op.internal_transfer, 32) + .storeUint(0, 64) + .storeCoins(jetton_amount) + .storeAddress(null) + .storeAddress(from) // Response addr + .storeCoins(forward_ton_amount) + .storeMaybeRef(null) + .endCell(); + + return beginCell() + .storeUint(Op.mint, 32) + .storeUint(query_id, 64) // op, queryId + .storeAddress(to) + .storeCoins(total_ton_amount) + .storeCoins(jetton_amount) + .storeRef(mintMsg) + .endCell(); + } + async sendMint( + provider: ContractProvider, + via: Sender, + to: Address, + jetton_amount: bigint, + forward_ton_amount: bigint, + total_ton_amount: bigint, + ) { + if (total_ton_amount <= forward_ton_amount) { + throw new Error('Total ton amount should be > forward amount'); + } + await provider.internal(via, { + sendMode: SendMode.PAY_GAS_SEPARATELY, + body: JettonMinter.mintMessage(this.address, to, jetton_amount, forward_ton_amount, total_ton_amount), + value: total_ton_amount + toNano('0.015'), + }); + } + + /* provide_wallet_address#2c76b973 query_id:uint64 owner_address:MsgAddress include_address:Bool = InternalMsgBody; + */ + static discoveryMessage(owner: Address, include_address: boolean) { + return beginCell() + .storeUint(0x2c76b973, 32) + .storeUint(0, 64) // op, queryId + .storeAddress(owner) + .storeBit(include_address) + .endCell(); + } + + async sendDiscovery( + provider: ContractProvider, + via: Sender, + owner: Address, + include_address: boolean, + value: bigint = toNano('0.1'), + ) { + await provider.internal(via, { + sendMode: SendMode.PAY_GAS_SEPARATELY, + body: JettonMinter.discoveryMessage(owner, include_address), + value: value, + }); + } + + static changeAdminMessage(newOwner: Address) { + return beginCell() + .storeUint(Op.change_admin, 32) + .storeUint(0, 64) // op, queryId + .storeAddress(newOwner) + .endCell(); + } + + async sendChangeAdmin(provider: ContractProvider, via: Sender, newOwner: Address) { + await provider.internal(via, { + sendMode: SendMode.PAY_GAS_SEPARATELY, + body: JettonMinter.changeAdminMessage(newOwner), + value: toNano('0.05'), + }); + } + static changeContentMessage(content: Cell) { + return beginCell() + .storeUint(Op.change_content, 32) + .storeUint(0, 64) // op, queryId + .storeRef(content) + .endCell(); + } + + async sendChangeContent(provider: ContractProvider, via: Sender, content: Cell) { + await provider.internal(via, { + sendMode: SendMode.PAY_GAS_SEPARATELY, + body: JettonMinter.changeContentMessage(content), + value: toNano('0.05'), + }); + } + async getWalletAddress(provider: ContractProvider, owner: Address): Promise
{ + const res = await provider.get('get_wallet_address', [ + { type: 'slice', cell: beginCell().storeAddress(owner).endCell() }, + ]); + return res.stack.readAddress(); + } + + async getJettonData(provider: ContractProvider) { + const res = await provider.get('get_jetton_data', []); + const totalSupply = res.stack.readBigNumber(); + const mintable = res.stack.readBoolean(); + const adminAddress = res.stack.readAddress(); + const content = res.stack.readCell(); + const walletCode = res.stack.readCell(); + return { + totalSupply, + mintable, + adminAddress, + content, + walletCode, + }; + } + + async getTotalSupply(provider: ContractProvider) { + const res = await this.getJettonData(provider); + return res.totalSupply; + } + async getAdminAddress(provider: ContractProvider) { + const res = await this.getJettonData(provider); + return res.adminAddress; + } + async getContent(provider: ContractProvider) { + const res = await this.getJettonData(provider); + return res.content; + } +} diff --git a/wrappers/JettonWallet.compile.ts b/wrappers/JettonWallet.compile.ts new file mode 100644 index 0000000..61ae295 --- /dev/null +++ b/wrappers/JettonWallet.compile.ts @@ -0,0 +1,11 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + targets: [ + 'contracts/imports/stdlib.fc', + 'contracts/params.fc', + 'contracts/op-codes.fc', + 'contracts/jetton-utils.fc', + 'contracts/jetton-wallet.fc', + ], +}; diff --git a/wrappers/JettonWallet.ts b/wrappers/JettonWallet.ts new file mode 100644 index 0000000..bd1f3a8 --- /dev/null +++ b/wrappers/JettonWallet.ts @@ -0,0 +1,160 @@ +import { + Address, + beginCell, + Cell, + Contract, + contractAddress, + ContractProvider, + Sender, + SendMode, + toNano, +} from '@ton/core'; + +export type JettonWalletConfig = {}; + +export function jettonWalletConfigToCell(config: JettonWalletConfig): Cell { + return beginCell().endCell(); +} + +export class JettonWallet implements Contract { + constructor( + readonly address: Address, + readonly init?: { code: Cell; data: Cell }, + ) {} + + static createFromAddress(address: Address) { + return new JettonWallet(address); + } + + static createFromConfig(config: JettonWalletConfig, code: Cell, workchain = 0) { + const data = jettonWalletConfigToCell(config); + const init = { code, data }; + return new JettonWallet(contractAddress(workchain, init), init); + } + + async sendDeploy(provider: ContractProvider, via: Sender, value: bigint) { + await provider.internal(via, { + value, + sendMode: SendMode.PAY_GAS_SEPARATELY, + body: beginCell().endCell(), + }); + } + + async getJettonBalance(provider: ContractProvider) { + const state = await provider.getState(); + if (state.state.type !== 'active') { + return 0n; + } + const res = await provider.get('get_wallet_data', []); + return res.stack.readBigNumber(); + } + static transferMessage( + jetton_amount: bigint, + to: Address, + responseAddress: Address, + customPayload: Cell | null, + forward_ton_amount: bigint, + forwardPayload: Cell | null, + ) { + return beginCell() + .storeUint(0xf8a7ea5, 32) + .storeUint(0, 64) // op, queryId + .storeCoins(jetton_amount) + .storeAddress(to) + .storeAddress(responseAddress) + .storeMaybeRef(customPayload) + .storeCoins(forward_ton_amount) + .storeMaybeRef(forwardPayload) + .endCell(); + } + async sendTransfer( + provider: ContractProvider, + via: Sender, + value: bigint, + jetton_amount: bigint, + to: Address, + responseAddress: Address, + customPayload: Cell, + forward_ton_amount: bigint, + forwardPayload: Cell, + ) { + await provider.internal(via, { + sendMode: SendMode.PAY_GAS_SEPARATELY, + body: JettonWallet.transferMessage( + jetton_amount, + to, + responseAddress, + customPayload, + forward_ton_amount, + forwardPayload, + ), + value: value, + }); + } + /* + burn#595f07bc query_id:uint64 amount:(VarUInteger 16) + response_destination:MsgAddress custom_payload:(Maybe ^Cell) + = InternalMsgBody; + */ + static burnMessage(jetton_amount: bigint, responseAddress: Address, customPayload: Cell | null) { + return beginCell() + .storeUint(0x595f07bc, 32) + .storeUint(0, 64) // op, queryId + .storeCoins(jetton_amount) + .storeAddress(responseAddress) + .storeMaybeRef(customPayload) + .endCell(); + } + + async sendBurn( + provider: ContractProvider, + via: Sender, + value: bigint, + jetton_amount: bigint, + responseAddress: Address, + customPayload: Cell, + ) { + await provider.internal(via, { + sendMode: SendMode.PAY_GAS_SEPARATELY, + body: JettonWallet.burnMessage(jetton_amount, responseAddress, customPayload), + value: value, + }); + } + /* + withdraw_tons#107c49ef query_id:uint64 = InternalMsgBody; + */ + static withdrawTonsMessage() { + return beginCell() + .storeUint(0x6d8e5e3c, 32) + .storeUint(0, 64) // op, queryId + .endCell(); + } + + async sendWithdrawTons(provider: ContractProvider, via: Sender) { + await provider.internal(via, { + sendMode: SendMode.PAY_GAS_SEPARATELY, + body: JettonWallet.withdrawTonsMessage(), + value: toNano('0.1'), + }); + } + /* + withdraw_jettons#10 query_id:uint64 wallet:MsgAddressInt amount:Coins = InternalMsgBody; + */ + static withdrawJettonsMessage(from: Address, amount: bigint) { + return beginCell() + .storeUint(0x768a50b2, 32) + .storeUint(0, 64) // op, queryId + .storeAddress(from) + .storeCoins(amount) + .storeMaybeRef(null) + .endCell(); + } + + async sendWithdrawJettons(provider: ContractProvider, via: Sender, from: Address, amount: bigint) { + await provider.internal(via, { + sendMode: SendMode.PAY_GAS_SEPARATELY, + body: JettonWallet.withdrawJettonsMessage(from, amount), + value: toNano('0.1'), + }); + } +}