forked from ton-blockchain/token-contract
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjetton-discovery.fc
70 lines (55 loc) · 2.38 KB
/
jetton-discovery.fc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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);
}