ston-fi / dex-core

Core contracts for STON.fi DEX.

Home Page:https://app.ston.fi

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

https://github.com/ston-fi/dex-core/blob/v1.0.0/contracts%2Flp_wallet.func

derockchannels opened this issue · comments

#pragma version >=0.2.0;

#include "common/stdlib.func";
#include "lp_wallet/op.func";
#include "lp_wallet/params.func";
#include "lp_wallet/errors.func";
#include "lp_wallet/jetton-utils.func";
#include "lp_wallet/storage.func";

() send_tokens (slice in_msg_body, slice sender_address, int msg_value, int fwd_fee) impure {
int query_id = in_msg_bodyload_uint(64);
int jetton_amount = in_msg_body
load_coins();
slice to_owner_address = in_msg_body~load_msg_addr();
force_chain(WORKCHAIN, to_owner_address, WRONG_WORKCHAIN);

(int balance, slice owner_address, slice jetton_master_address, cell jetton_wallet_code) = load_storage();
balance -= jetton_amount;

throw_unless(705, equal_slices(owner_address, sender_address));
throw_unless(706, balance >= 0);

cell state_init = calculate_jetton_lp_wallet_state_init(to_owner_address, jetton_master_address, jetton_wallet_code);
slice to_wallet_address = calculate_jetton_lp_wallet_address(state_init);
slice response_address = in_msg_bodyload_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(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 + fwd_count * fwd_fee + (2 * REQUIRED_GAS + REQUIRED_TON_STORAGE));
send_raw_message(msg.end_cell(), 64);
save_storage(balance, owner_address, jetton_master_address, jetton_wallet_code);
}

() receive_tokens (slice in_msg_body, slice sender_address, int my_ton_balance, int fwd_fee, int msg_value) impure {
(int balance, slice owner_address, slice jetton_master_address, cell jetton_wallet_code) = load_storage();
int query_id = in_msg_bodyload_uint(64);
int jetton_amount = in_msg_body
load_coins();
balance += jetton_amount;
slice from_address = in_msg_bodyload_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_lp_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 = REQUIRED_TON_STORAGE - min(ton_balance_before_msg, REQUIRED_TON_STORAGE);
msg_value -= (storage_fee + REQUIRED_GAS);
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(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(0x18, 6)
.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)
.store_slice(response_address)
.store_coins(msg_value)
.store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)
.store_uint(excesses, 32)
.store_uint(query_id, 64);
send_raw_message(msg.end_cell(), 2);
}

save_storage(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 {
(int balance, slice owner_address, slice jetton_master_address, cell jetton_wallet_code) = load_storage();
int query_id = in_msg_bodyload_uint(64);
int jetton_amount = in_msg_body
load_coins();
slice response_address = in_msg_bodyload_msg_addr();
;; 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 * REQUIRED_GAS);

var msg_body = begin_cell()
.store_uint(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_storage(balance, owner_address, jetton_master_address, jetton_wallet_code);
}

() on_bounce (slice in_msg_body) impure {
in_msg_bodyskip_bits(32);
(int balance, slice owner_address, slice jetton_master_address, cell jetton_wallet_code) = load_storage();
int op = in_msg_body
load_uint(32);
throw_unless(709, (op == internal_transfer) | (op == burn_notification));
int query_id = in_msg_bodyload_uint(64);
int jetton_amount = in_msg_body
load_coins();
balance += jetton_amount;
save_storage(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?()) {
return ();
}

slice cs = in_msg_full.begin_parse();
int flags = csload_uint(4);
if (flags & 1) {
on_bounce(in_msg_body);
return ();
}
slice sender_address = cs
load_msg_addr();
csload_msg_addr();
cs
load_coins();
csskip_bits(1);
cs
load_coins();
int fwd_fee = cs~load_coins();

int op = in_msg_body~load_uint(32);

if (op == transfer) {
send_tokens(in_msg_body, sender_address, msg_value, fwd_fee);
return ();
}

if (op == internal_transfer) {
receive_tokens(in_msg_body, sender_address, my_balance, fwd_fee, msg_value);
return ();
}

if (op == burn) {
burn_tokens(in_msg_body, sender_address, msg_value, fwd_fee);
return ();
}

throw(WRONG_OP);
}

(int, slice, slice, cell) get_wallet_data() method_id {
return load_storage();
}