Skip to content

Commit

Permalink
Add pool code
Browse files Browse the repository at this point in the history
  • Loading branch information
EmelyanenkoK committed May 18, 2023
1 parent 887e992 commit 11c0388
Show file tree
Hide file tree
Showing 12 changed files with 987 additions and 78 deletions.
78 changes: 78 additions & 0 deletions contracts/address_calculations.func
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "metadata_utils.func";

global cell controller_code;
global cell awaited_jetton_wallet_code;
global cell pool_jetton_wallet_code;
global cell payout_minter_code;

slice addr_none() asm "b{00} PUSHSLICE";
builder store_zeros(builder b, int n) asm "STZEROES";

cell controller_init_data (builder static_data) {
;; TODO optimize with store_zeros
return begin_cell()
.store_uint(0, 8) ;; state
.store_int(0, 1) ;; approved
.store_coins(0) ;; stake_amount_sent
.store_timestamp(0) ;; stake_at
.store_uint(0, 256) ;; saved_validator_set_hash
.store_uint(0, 8) ;; validator_set_changes_count
.store_timestamp(0) ;; validator_set_change_time
.store_timestamp(0) ;; stake_held_for
.store_coins(0) ;; borrowed_amount
.store_timestamp(0) ;; borrowing_time
.store_slice(sudoer) ;; sudoer
.store_timestamp(0) ;; sudoer_set_at
.store_builder(static_data)
.end_cell();
}

cell controller_init_state (builder static_data) {
return begin_cell()
.store_uint(0, 1 + 1) ;; split_depth (Maybe = 0) and special (Maybe = 0)
.store_maybe_ref(controller_code)
.store_maybe_ref(controller_init_data(static_data))
.store_uint(0,1) ;; libraries - empty cell
.end_cell();
}


slice calc_address(int workchain, cell state_init) inline {
return begin_cell().store_uint(4, 3) ;; 0x100 : $10 + anycast (Maybe = 0)
.store_int(workchain, 8)
.store_uint(
cell_hash(state_init), 256)
.end_cell()
.begin_parse();
}

global slice consigliere;

cell calculate_payout_state_init(slice pool_address, int round_id, int distributing_jettons?) {
cell content_dict = new_dict();
;; TODO optimize
slice name = concat(distributing_jettons? ? "Jetton " : "TON ", concat("Payout#", encode_number_to_text(round_id, 10)));
content_dict~udict_set_ref(256, "name"H, pack_metadata_value(name));
content_dict~udict_set_ref(256, "description"H, pack_metadata_value("Utility jetton: do not use directly"));
slice symbol = distributing_jettons? ? "⏲️J" : "⏲️💎";
content_dict~udict_set_ref(256, "symbol"H, pack_metadata_value(symbol));
content_dict~udict_set_ref(256, "uri"H, pack_metadata_value("my-custom-stake-address.ton"));
content_dict~udict_set_ref(256, "image"H, pack_metadata_value("my-custom-stake-address.ton/icon.img"));
cell onchain_content = begin_cell().store_uint(0, 8).store_dict(content_dict).end_cell();


cell data = begin_cell()
.store_coins(0) ;; total_supply
.store_slice(my_address()) ;; admin_address
.store_slice(consigliere) ;; stake_amount_sent
.store_maybe_ref(null()) ;; Distribution
.store_ref(onchain_content) ;; Content
.store_ref(awaited_jetton_wallet_code)
.end_cell();
return begin_cell()
.store_uint(0, 1 + 1) ;; split_depth (Maybe = 0) and special (Maybe = 0)
.store_maybe_ref(payout_minter_code)
.store_maybe_ref(data)
.store_uint(0,1) ;; libraries - empty cell
.end_cell();
}
79 changes: 8 additions & 71 deletions contracts/controller.func
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
#include "op-codes.func";
#include "messages.func";
#include "asserts.func";
#include "utils.func";
#include "network_config_utils.func";
#include "sudoer_requests.func";
#include "governor_requests.func";
#include "halter_requests.func";


const int ADDR_SIZE = 256; ;; bits
const int ONE_TON = 1000000000;
const int ELECTOR_OPERATION_VALUE = 103 * ONE_TON / 100 ;
const int MIN_TONS_FOR_STORAGE = 10 * ONE_TON; ;; 10 TON
Expand Down Expand Up @@ -74,16 +75,13 @@ const int state::HALTED = 0xff;

slice elector_address();
int is_elector_address(slice address);
int max_recommended_punishment_for_validator_misbehaviour(int stake);
(int, int, int) get_validator_config();
int get_stake_held_for();
int get_elections_start_before();
(int, int, cell) get_current_validator_set();
;;int max_recommended_punishment_for_validator_misbehaviour(int stake);
;;(int, int, int) get_validator_config();
;;int get_stake_held_for();
;;int get_elections_start_before();
;;(int, int, cell) get_current_validator_set();
int check_new_stake_msg(slice cs);

(slice, (int)) ~load_timestamp(slice s) inline { return s.load_uint(48); }
builder store_timestamp(builder b, int timestamp) inline { return b.store_uint(timestamp, 48); }

() recv_internal(int balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {

slice cs = in_msg_full.begin_parse();
Expand Down Expand Up @@ -431,68 +429,6 @@ int is_elector_address(slice address) inline_ref {
return equal_slice_bits(address, elector_address());
}

;; https://github.com/ton-blockchain/ton/blob/ae5c0720143e231c32c3d2034cfe4e533a16d969/crypto/block/block.tlb#L721
int max_recommended_punishment_for_validator_misbehaviour(int stake) inline_ref {
cell cp = config_param(40);
if (cell_null?(cp)) {
return 101 * ONE_TON; ;; 101 TON - https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/lite-client/lite-client.cpp#L3678
}

slice cs = cp.begin_parse();

(int prefix,
int default_flat_fine, int default_proportional_fine,
int severity_flat_mult, int severity_proportional_mult,
int unpunishable_interval,
int long_interval, int long_flat_mult, int long_proportional_mult) =
(cs~load_uint(8),
cs~load_coins(), cs~load_uint(32),
cs~load_uint(16), cs~load_uint(16),
cs~load_uint(16),
cs~load_uint(16), cs~load_uint(16), cs~load_uint(16)
);

;; https://github.com/ton-blockchain/ton/blob/master/lite-client/lite-client.cpp#L3721
int fine = default_flat_fine;
int fine_part = default_proportional_fine;

fine *= severity_flat_mult; fine >>= 8;
fine_part *= severity_proportional_mult; fine_part >>= 8;

fine *= long_flat_mult; fine >>= 8;
fine_part *= long_proportional_mult; fine_part >>= 8;

return min(stake, fine + muldiv(stake, fine_part, 1 << 32)); ;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/smartcont/elector-code.fc#L529
}

;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/block/block.tlb#L632
;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/smartcont/elector-code.fc#L118
(int, int, int) get_validator_config() inline {
slice cs = config_param(15).begin_parse();
(int validators_elected_for, int elections_start_before, int elections_end_before, int _stake_held_for) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32), cs.preload_uint(32));
return (elections_start_before, _stake_held_for, elections_end_before);
}

int get_stake_held_for() inline_ref {
(int elections_start_before, int _stake_held_for, _) = get_validator_config();
return _stake_held_for;
}
int get_elections_start_before() inline_ref {
(int elections_start_before, int _stake_held_for, _) = get_validator_config();
return elections_start_before;
}

;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/block/block.tlb#L712
(int, int, cell) get_current_validator_set() inline_ref {
cell vset = config_param(34); ;; current validator set
slice cs = vset.begin_parse();
;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/block/block.tlb#L579
;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/smartcont/config-code.fc#L49
throw_unless(9, cs~load_uint(8) == 0x12); ;; validators_ext#12 only
int utime_since = cs~load_uint(32); ;; actual start unixtime of current validation round
int utime_until = cs~load_uint(32); ;; supposed end unixtime of current validation round (utime_until = utime_since + validators_elected_for); unfreeze_at = utime_until + stake_held_for
return (utime_since, utime_until, vset);
}

;; check the validity of the new_stake message
;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/smartcont/elector-code.fc#L208
Expand Down Expand Up @@ -528,3 +464,4 @@ _ get_validator_controller_data() method_id {
int get_max_punishment(int stake) method_id {
return max_recommended_punishment_for_validator_misbehaviour(stake);
}

29 changes: 29 additions & 0 deletions contracts/dao_jetton_utils.func
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
cell pack_jetton_wallet_data (int balance, slice owner,
slice jetton_master, cell token_wallet_code,
int locked, int locked_expiration,
cell vote_controller_code) inline {
return begin_cell()
.store_coins(balance)
.store_slice(owner)
.store_slice(jetton_master)
.store_ref(token_wallet_code)
.store_coins(locked)
.store_uint(locked_expiration, 48)
.store_ref(vote_controller_code)
.end_cell();
}
{-
_ split_depth:(Maybe (## 5)) special:(Maybe TickTock)
code:(Maybe ^Cell) data:(Maybe ^Cell)
library:(HashmapE 256 SimpleLib) = StateInit;
-}
cell calculate_jetton_wallet_state_init (slice owner, slice jetton_master, cell code, cell vote_controller_code) inline {
return begin_cell()
.store_uint(0,1 + 1) ;; split_depth (Maybe = 0) and special (Maybe = 0)
.store_maybe_ref(code)
.store_maybe_ref(pack_jetton_wallet_data(0, owner, jetton_master, code, 0, 0, vote_controller_code))
.store_uint(0,1) ;; libraries - empty cell
.end_cell();
}


2 changes: 2 additions & 0 deletions contracts/errors.func
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const int error::unauthorized_burn_request = 0x92283;

60 changes: 53 additions & 7 deletions contracts/messages.func
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,19 @@ builder store_msg_flags(builder b, int msg_flag) inline { return b.store_uint(ms

-}

builder store_msgbody_prefix_stateinit(builder b) inline {
return b.store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1);
builder store_msgbody_prefix_stateinit(builder b, cell state_init, cell ref) inline {
return b.store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1).store_ref(state_init).store_ref(ref);
}
builder store_msgbody_prefix_slice(builder b) inline {
return b.store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1);

builder store_msgbody_prefix_stateinit_slice(builder b, cell state_init) inline {
return b.store_uint(4 + 2 + 0, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1).store_ref(state_init);
}

builder store_msgbody_prefix_slice(builder b) inline {
return b.store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1);
}
builder store_msgbody_prefix_ref(builder b) inline {
return b.store_uint(1, 1 + 4 + 4 + 64 + 32 + 1 + 1);
builder store_msgbody_prefix_ref(builder b, cell ref) inline {
return b.store_uint(1, 1 + 4 + 4 + 64 + 32 + 1 + 1).store_ref(ref);
}

{-
Expand All @@ -51,9 +56,27 @@ builder store_masterchain_address(builder b, int address_hash) inline {
.store_coins(amount);

if (has_payload) {
msg = msg.store_msgbody_prefix_ref().store_ref(payload);
msg = msg.store_msgbody_prefix_ref(payload);
} else {
msg = msg.store_msgbody_prefix_slice();
}

send_raw_message(msg.end_cell(), send_mode);
}

() send_msg_builder(slice to_address, int amount, builder payload, int flags, int send_mode) impure inline_ref {
int payload_length = payload.null?() ? 0 : payload.builder_bits();

builder msg = begin_cell()
.store_msg_flags(flags)
.store_slice(to_address)
.store_coins(amount);

if (payload_length + msg.builder_bits() > 1023 - (1 + 4 + 4 + 64 + 32 + 1 + 1)) {
msg = msg.store_msgbody_prefix_ref(begin_cell().store_builder(payload).end_cell());
} else {
msg = msg.store_msgbody_prefix_slice();
msg.store_builder(payload);
}

send_raw_message(msg.end_cell(), send_mode);
Expand All @@ -67,3 +90,26 @@ builder store_masterchain_address(builder b, int address_hash) inline {
msgflag::NON_BOUNCEABLE,
sendmode::CARRY_ALL_REMAINING_MESSAGE_VALUE | sendmode::IGNORE_ERRORS); ;; non-bouneable, remaining inbound message amount, fee deducted from amount, ignore errors
}



() emit_log (int topic, builder data) impure inline {
;; 1023 - (4+2+9+256+64+32+2) = 654 bit free

var msg = begin_cell()
.store_uint (12, 4) ;; ext_out_msg_info$11 src:MsgAddressInt ()
.store_uint (1, 2) ;; addr_extern$01
.store_uint (256, 9) ;; len:(## 9)
.store_uint(topic, 256); ;; external_address:(bits len)

if (data.builder_bits() > 1023 - (4 + 2 + 9 + 256 + 64 + 32 + 2) ) {
msg = msg.store_uint(1, 64 + 32 + 2) ;; created_lt, created_at, init:Maybe, body:Either
.store_ref(begin_cell().store_builder(data).end_cell());
} else {
msg = msg.store_uint(0, 64 + 32 + 2) ;; created_lt, created_at, init:Maybe, body:Either
.store_builder(data);
}

send_raw_message(msg.end_cell(), sendmode::REGULAR);
}

27 changes: 27 additions & 0 deletions contracts/metadata_utils.func
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
cell pack_metadata_value(slice a) inline {
return begin_cell().store_uint(0, 8).store_slice(a).end_cell();
}

slice encode_number_to_text(int decimals, int radix) {
builder str = begin_cell();
int ctr = 0;
tuple chars = empty_tuple();

do {
(decimals, int rem) = decimals /% radix;

chars~tpush( rem >= 10 ? 87 + rem : 48 + rem);
ctr += 1;
} until (decimals == 0);

repeat( ctr ) {
str = str.store_uint(chars.at(ctr - 1), 8);
ctr -= 1;
}

return str.end_cell().begin_parse();
}

slice concat(slice a, slice b) inline {
return begin_cell().store_slice(a).store_slice(b).end_cell().begin_parse();
}
64 changes: 64 additions & 0 deletions contracts/network_config_utils.func
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const int ONE_TON = 1000000000;

;; https://github.com/ton-blockchain/ton/blob/ae5c0720143e231c32c3d2034cfe4e533a16d969/crypto/block/block.tlb#L721
int max_recommended_punishment_for_validator_misbehaviour(int stake) inline_ref {
cell cp = config_param(40);
if (cell_null?(cp)) {
return 101 * ONE_TON; ;; 101 TON - https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/lite-client/lite-client.cpp#L3678
}

slice cs = cp.begin_parse();

(int prefix,
int default_flat_fine, int default_proportional_fine,
int severity_flat_mult, int severity_proportional_mult,
int unpunishable_interval,
int long_interval, int long_flat_mult, int long_proportional_mult) =
(cs~load_uint(8),
cs~load_coins(), cs~load_uint(32),
cs~load_uint(16), cs~load_uint(16),
cs~load_uint(16),
cs~load_uint(16), cs~load_uint(16), cs~load_uint(16)
);

;; https://github.com/ton-blockchain/ton/blob/master/lite-client/lite-client.cpp#L3721
int fine = default_flat_fine;
int fine_part = default_proportional_fine;

fine *= severity_flat_mult; fine >>= 8;
fine_part *= severity_proportional_mult; fine_part >>= 8;

fine *= long_flat_mult; fine >>= 8;
fine_part *= long_proportional_mult; fine_part >>= 8;

return min(stake, fine + muldiv(stake, fine_part, 1 << 32)); ;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/smartcont/elector-code.fc#L529
}

;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/block/block.tlb#L632
;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/smartcont/elector-code.fc#L118
(int, int, int) get_validator_config() inline {
slice cs = config_param(15).begin_parse();
(int validators_elected_for, int elections_start_before, int elections_end_before, int _stake_held_for) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32), cs.preload_uint(32));
return (elections_start_before, _stake_held_for, elections_end_before);
}

int get_stake_held_for() inline_ref {
(int elections_start_before, int _stake_held_for, _) = get_validator_config();
return _stake_held_for;
}
int get_elections_start_before() inline_ref {
(int elections_start_before, int _stake_held_for, _) = get_validator_config();
return elections_start_before;
}

;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/block/block.tlb#L712
(int, int, cell) get_current_validator_set() inline_ref {
cell vset = config_param(34); ;; current validator set
slice cs = vset.begin_parse();
;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/block/block.tlb#L579
;; https://github.com/ton-blockchain/ton/blob/b38d227a469666d83ac535ad2eea80cb49d911b8/crypto/smartcont/config-code.fc#L49
throw_unless(9, cs~load_uint(8) == 0x12); ;; validators_ext#12 only
int utime_since = cs~load_uint(32); ;; actual start unixtime of current validation round
int utime_until = cs~load_uint(32); ;; supposed end unixtime of current validation round (utime_until = utime_since + validators_elected_for); unfreeze_at = utime_until + stake_held_for
return (utime_since, utime_until, vset);
}
Loading

0 comments on commit 11c0388

Please sign in to comment.