Advertisement
AmirVagapov

nftsale

Apr 16th, 2024
585
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.77 KB | None | 0 0
  1. #include "imports/stdlib.fc";
  2. #include "imports/op-codes.fc";
  3.  
  4. ;; NFT sale smart contract
  5.  
  6. int min_gas_amount() asm "1000000000 PUSHINT"; ;; 1 TON
  7.  
  8. (slice, slice, slice, int, cell, int) load_data() inline {
  9.   var ds = get_data().begin_parse();
  10.   return
  11.     (ds~load_msg_addr(),   ;; marketplace_address
  12.       ds~load_msg_addr(),  ;; nft_address
  13.       ds~load_msg_addr(),  ;; nft_owner_address
  14.       ds~load_coins(),     ;; full_price
  15.       ds~load_ref(),       ;; fees_cell
  16.       ds~load_uint(32)     ;; sale_count
  17.      );
  18. }
  19.  
  20. (int, slice, int) load_fees(cell fees_cell) inline {
  21.   var ds = fees_cell.begin_parse();
  22.   return
  23.     (ds~load_coins(),     ;; marketplace_fee,
  24.       ds~load_msg_addr(), ;; royalty_address
  25.       ds~load_coins()     ;; royalty_amount
  26.      );
  27. }
  28.  
  29.  
  30. () save_data(slice marketplace_address, slice nft_address, slice nft_owner_address, int full_price, cell fees_cell, int sale_count) impure inline {
  31.   set_data(begin_cell()
  32.     .store_slice(marketplace_address)
  33.     .store_slice(nft_address)
  34.     .store_slice(nft_owner_address)
  35.     .store_coins(full_price)
  36.     .store_ref(fees_cell)
  37.     .store_uint(sale_count, 32)
  38.     .end_cell());
  39. }
  40.  
  41. () buy(int my_balance, slice marketplace_address, slice nft_address, slice nft_owner_address, int full_price, cell fees_cell, int msg_value, slice sender_address, int query_id, int sale_count) impure {
  42.   throw_unless(450, msg_value >= full_price + min_gas_amount());
  43.  
  44.   var (marketplace_fee, royalty_address, royalty_amount) = load_fees(fees_cell);
  45.  
  46.   var owner_msg = begin_cell()
  47.            .store_uint(0x10, 6) ;; nobounce
  48.            .store_slice(nft_owner_address)
  49.            .store_coins(full_price - marketplace_fee - royalty_amount + (my_balance - msg_value))
  50.            .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1);
  51.  
  52.   send_raw_message(owner_msg.end_cell(), 1);
  53.  
  54.  
  55.   var royalty_msg = begin_cell()
  56.            .store_uint(0x10, 6) ;; nobounce
  57.            .store_slice(royalty_address)
  58.            .store_coins(royalty_amount)
  59.            .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1);
  60.  
  61.   send_raw_message(royalty_msg.end_cell(), 1);
  62.  
  63.  
  64.   var marketplace_msg = begin_cell()
  65.            .store_uint(0x10, 6) ;; nobounce
  66.            .store_slice(marketplace_address)
  67.            .store_coins(marketplace_fee)
  68.            .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1);
  69.  
  70.   send_raw_message(marketplace_msg.end_cell(), 1);
  71.  
  72.   var nft_msg = begin_cell()
  73.            .store_uint(0x18, 6)
  74.            .store_slice(nft_address)
  75.            .store_coins(0)
  76.            .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)
  77.            .store_uint(op::transfer(), 32)
  78.            .store_uint(query_id, 64)
  79.            .store_slice(sender_address) ;; new_owner_address
  80.            .store_slice(sender_address) ;; response_address
  81.            .store_int(0, 1) ;; empty custom_payload
  82.            .store_coins(0) ;; forward amount to new_owner_address
  83.            .store_int(0, 1); ;; empty forward_payload
  84.  
  85.  
  86.   send_raw_message(nft_msg.end_cell(), 128 + 32);
  87.  
  88.   sale_count = sale_count + 1;
  89.  
  90.   save_data(marketplace_address,nft_address,nft_owner_address,full_price,fees_cell,sale_count);
  91. }
  92.  
  93. () recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
  94.     slice cs = in_msg_full.begin_parse();
  95.     int flags = cs~load_uint(4);
  96.  
  97.     if (flags & 1) {  ;; ignore all bounced messages
  98.         return ();
  99.     }
  100.  
  101.     slice sender_address = cs~load_msg_addr();
  102.  
  103.     var (marketplace_address, nft_address, nft_owner_address, full_price, fees_cell, sale_count) = load_data();
  104.  
  105.     var is_initialized = nft_owner_address.slice_bits() > 2; ;; not initialized if null address
  106.  
  107.     if (~ is_initialized) { ;; initialization
  108.  
  109.       if (equal_slices(sender_address, marketplace_address)) {
  110.          return (); ;; just accept coins on deploy
  111.       }
  112.  
  113.       throw_unless(500, equal_slices(sender_address, nft_address));
  114.       int op = in_msg_body~load_uint(32);
  115.       throw_unless(501, op == op::ownership_assigned());
  116.       int query_id = in_msg_body~load_uint(64);
  117.       slice prev_owner_address = in_msg_body~load_msg_addr();
  118.  
  119.       save_data(marketplace_address, nft_address, prev_owner_address, full_price, fees_cell, sale_count);
  120.  
  121.       return ();
  122.  
  123.     }
  124.  
  125.     if (in_msg_body.slice_empty?()) {
  126.         buy(my_balance, marketplace_address, nft_address, nft_owner_address, full_price, fees_cell, msg_value, sender_address, 0, 0);
  127.         return ();
  128.     }
  129.  
  130.     int op = in_msg_body~load_uint(32);
  131.     int query_id = in_msg_body~load_uint(64);
  132.  
  133.     if (op == 1) { ;; just accept coins
  134.         return ();
  135.     }
  136.  
  137.     if (op == 2) { ;; buy by admin
  138.       throw_unless(458, equal_slices(sender_address, marketplace_address));
  139.  
  140.       buy(my_balance, marketplace_address, nft_address, nft_owner_address, full_price, fees_cell, msg_value, sender_address, query_id, sale_count);
  141.  
  142.       return ();
  143.  
  144.     }
  145.  
  146.     if (op == 3) { ;; cancel sale (remove)
  147.          throw_unless(457, msg_value >= min_gas_amount());
  148.          throw_unless(458, equal_slices(sender_address, marketplace_address));
  149.  
  150.          var msg = begin_cell()
  151.            .store_uint(0x10, 6) ;; nobounce
  152.            .store_slice(nft_address)
  153.            .store_coins(0)
  154.            .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)
  155.            .store_uint(op::transfer(), 32)
  156.            .store_uint(query_id, 64)
  157.            .store_slice(nft_owner_address) ;; new_owner_address
  158.            .store_slice(nft_owner_address) ;; response_address;
  159.            .store_int(0, 1) ;; empty custom_payload
  160.            .store_coins(0) ;; forward amount to new_owner_address
  161.            .store_int(0, 1); ;; empty forward_payload
  162.  
  163.         send_raw_message(msg.end_cell(), 128 + 32);
  164.  
  165.         return ();
  166.     }
  167.  
  168.     if (op == 4) { ;; update price
  169.         throw_unless(457, msg_value >= min_gas_amount());
  170.         throw_unless(458, equal_slices(sender_address, marketplace_address));
  171.         int new_price = in_msg_body~load_coins();
  172.         full_price = new_price;
  173.         save_data(marketplace_address,nft_address,nft_owner_address,full_price,fees_cell,sale_count);
  174.  
  175.         return ();
  176.     }
  177.  
  178.     throw(0xffff);
  179.  
  180. }
  181.  
  182. () recv_external(slice in_msg) impure {
  183. }
  184.  
  185. (slice, slice, slice, int, int, slice, int) get_sale_data() method_id {
  186.   var (marketplace_address, nft_address, nft_owner_address, full_price, fees_cell, sale_count) = load_data();
  187.   var (marketplace_fee, royalty_address, royalty_amount) = load_fees(fees_cell);
  188.   return (marketplace_address, nft_address, nft_owner_address, full_price, marketplace_fee, royalty_address, royalty_amount);
  189. }
  190.  
  191. (slice) get_admin() method_id {
  192.   (slice marketplace_address,_,_,_,_,_) = load_data();
  193.   return marketplace_address;
  194. }
  195.  
  196. (int) get_sale_count() method_id {
  197.     (_,_,_,_,_, int sale_count) = load_data();
  198.     return sale_count;
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement