Browse Source

Foundation, tests

master
Lev 2 years ago
parent
commit
e7c3861dab
  1. 141
      sources/foundation.tact
  2. 6
      sources/jetton.tact
  3. 6
      sources/messages.tact
  4. 2
      sources/output/jetton_Linker.abi
  5. 2
      sources/output/jetton_Linker.code.fc
  6. 2
      sources/output/jetton_Linker.code.fif
  7. 20
      sources/output/jetton_Linker.md
  8. 2
      sources/output/jetton_Linker.pkg
  9. 211
      sources/output/jetton_Linker.ts
  10. 2
      sources/output/jetton_PseudoStaking.abi
  11. 2
      sources/output/jetton_PseudoStaking.code.fc
  12. 2
      sources/output/jetton_PseudoStaking.code.fif
  13. 20
      sources/output/jetton_PseudoStaking.md
  14. 2
      sources/output/jetton_PseudoStaking.pkg
  15. 211
      sources/output/jetton_PseudoStaking.ts
  16. 2
      sources/output/jetton_TONB.abi
  17. BIN
      sources/output/jetton_TONB.code.boc
  18. 25
      sources/output/jetton_TONB.code.fc
  19. 43
      sources/output/jetton_TONB.code.fif
  20. 242
      sources/output/jetton_TONB.code.rev.fif
  21. 22
      sources/output/jetton_TONB.md
  22. 2
      sources/output/jetton_TONB.pkg
  23. 220
      sources/output/jetton_TONB.ts
  24. 2
      sources/output/jetton_TONBWallet.abi
  25. 2
      sources/output/jetton_TONBWallet.code.fc
  26. 2
      sources/output/jetton_TONBWallet.code.fif
  27. 20
      sources/output/jetton_TONBWallet.md
  28. 2
      sources/output/jetton_TONBWallet.pkg
  29. 211
      sources/output/jetton_TONBWallet.ts
  30. 34
      sources/tests/__snapshots__/jetton.spec.ts.snap
  31. 23
      sources/tests/foundation.spec.ts
  32. 19
      sources/tests/voting.spec.ts
  33. 28
      sources/utils/interactions.ts

141
sources/foundation.tact

@ -4,7 +4,8 @@ import "./messages";
struct Proposal { struct Proposal {
type: Int; // 0 - Blacklist, 1 - Full liquidation, 2 - Change percents type: Int; // 0 - Blacklist, 1 - Full liquidation, 2 - Change percents
data: Cell; // Address for blacklist, Distribution for percents blacklistAddress: Address?;
distribution: Distribution?;
} }
struct Vote { struct Vote {
@ -17,16 +18,6 @@ struct Vote {
result: Bool?; // None - no result, True - passed, False - failed result: Bool?; // None - no result, True - passed, False - failed
} }
fun vote_res(prop: Proposal): Cell? {
if (prop.type == 0) {
return BlacklistWallet {
wallet: prop.data.readAddress()
}.asCell();
}
if (prop.type == 1) {
// todo
}
}
contract Foundation { contract Foundation {
founders: AddressList; // aka superadmins founders: AddressList; // aka superadmins
@ -34,7 +25,7 @@ contract Foundation {
tonb: Address; tonb: Address;
votes: map[Int]Vote; votes: map[Int]Vote;
profits: map[Address]Int; profits: map[Address]Int;
n_votes: Int; n_votes: Int = 0;
init(admins: Distribution, founders: AddressList, tonb: Address) { init(admins: Distribution, founders: AddressList, tonb: Address) {
self.admins = admins; self.admins = admins;
@ -43,8 +34,8 @@ contract Foundation {
} }
receive(msg: FinishVote) { receive(msg: FinishVote) {
require(msg.vote_id < self.n_votes, "Invalid vote id"); require(msg.voteId < self.n_votes, "Invalid vote id");
let vote: Vote = self.votes.get(msg.vote_id)!!; let vote: Vote = self.votes.get(msg.voteId)!!;
require(vote.ended == false, "Vote already ended"); require(vote.ended == false, "Vote already ended");
require(vote.vote_end < now(), "Vote is not finished yet"); require(vote.vote_end < now(), "Vote is not finished yet");
let n_yes: Int = 0; let n_yes: Int = 0;
@ -52,7 +43,7 @@ contract Foundation {
let n_abstain: Int = 0; let n_abstain: Int = 0;
let i: Int = 0; let i: Int = 0;
while (i < self.admins.addresses.length) { while (i < self.admins.addresses.length) {
let vote_: Int = vote.votes.get(i)!!; let vote_i: Int = vote.votes.get(i)!!;
if (vote_i == 1) { if (vote_i == 1) {
n_yes = n_yes + 1; n_yes = n_yes + 1;
} else if (vote_i == 2) { } else if (vote_i == 2) {
@ -72,79 +63,61 @@ contract Foundation {
vote.result = false; vote.result = false;
} }
vote.ended = true; vote.ended = true;
self.votes.set(msg.vote_id, vote); self.votes.set(msg.voteId, vote);
if (vote.result == true) { if (vote.result == true) {
let vres: Cell? = vote_res(vote.proposal); let prop: Proposal = vote.proposal;
if (vres != null) { if (prop.type == 0) {
send(SendParameters{ send(SendParameters{
to: self.tonb, to: self.tonb,
value: 0, value: 0,
mode: SendRemainingValue, mode: SendRemainingValue,
body: vres!! body: BlacklistWallet {
}); wallet: prop.blacklistAddress!!
}.toCell()
});
} }
if(vote.proposal.type == 2) { if (prop.type == 1) {
// self.admins = Distribution { // todo
// addresses: vote.proposal.data.readAddressList(), }
// percents: vote.proposal.data.readPercents() if (prop.type == 2) {
// }; self.admins = prop.distribution!!;
} }
} }
} }
receive(msg: Vote) { receive(msg: VoteMsg) {
require(msg.adminIndex < self.admins.addresses.length, "Invalid admin index") require(msg.adminIndex < self.admins.addresses.length, "Invalid admin index");
let ctx: Context = context(); let ctx: Context = context();
require(ctx.sender == self.admins.addresses.addresses.get(msg.adminIndex), "Only an admin can vote"); require(ctx.sender == self.admins.addresses.addresses.get(msg.adminIndex), "Only an admin can vote");
require(msg.vote_id < self.n_votes, "Invalid vote id"); require(msg.voteId < self.n_votes, "Invalid vote id");
let vote: Vote = self.votes.get(msg.vote_id)!!; let vote: Vote = self.votes.get(msg.voteId)!!;
require(vote.ended == false, "Vote already ended"); require(vote.ended == false, "Vote already ended");
require(vote.vote_end > now(), "Vote is finished"); require(vote.vote_end > now(), "Vote is finished");
require(msg.vote >= 0 && msg.vote <= 2, "Invalid vote"); require(msg.vote >= 0 && msg.vote <= 2, "Invalid vote");
vote.votes.set(msg.adminIndex, msg.vote); vote.votes.set(msg.adminIndex, msg.vote);
self.votes.set(msg.vote_id, vote); self.votes.set(msg.voteId, vote);
} }
receive(msg: InitiateBlacklistVote) { receive(msg: InitiateBlacklistVote) {
let ctx: Context = context(); let ctx: Context = context();
require(ctx.sender == self.admins.addresses.addresses.get(msg.adminIndex), "Only an admin can initiate a vote"); require(ctx.sender == self.admins.addresses.addresses.get(msg.adminIndex), "Only an admin can initiate a vote");
require(ctx.value >= ton("1.0"), "Voting requires at least 1 ton for the fees") require(ctx.value >= ton("1.0"), "Voting requires at least 1 ton for the fees");
require(msg.quorum_percent > 20 && msg.quorum_percent <= 100, "Invalid quorum percent"); require(msg.quorum_percent > 20 && msg.quorum_percent <= 100, "Invalid quorum percent");
require(msg.vote_time > 0 && msg.vote_time < 3 * 24 * 3600, "Invalid vote time"); require(msg.vote_time > 0 && msg.vote_time < 3 * 24 * 3600, "Invalid vote time");
let vote = Vote { let proposal: Proposal = Proposal {
id: self.n_votes, type: 0,
vote_end: now() + msg.vote_time, blacklistAddress: msg.wallet,
proposal: Proposal { distribution: null
type: 0,
data: msg.address
},
quorum_percent: msg.quorum_percent
}; };
let i: Int = 0; let vote: Vote = Vote {
while (i < self.admins.addresses.length) {
vote.votes.set(i, -1);
i = i + 1;
}
self.votes.set(self.n_votes, vote);
self.n_votes = self.n_votes + 1;
}
receive(msg: InitiateDistributionVote) {
let ctx: Context = context();
require(ctx.sender == self.admins.addresses.addresses.get(msg.adminIndex), "Only an admin can initiate a vote");
require(ctx.value >= ton("1.0"), "Voting requires at least 1 ton for the fees")
require(msg.quorum_percent > 20 && msg.quorum_percent <= 100, "Invalid quorum percent");
require(msg.vote_time > 0 && msg.vote_time < 3 * 24 * 3600, "Invalid vote time");
let vote = Vote {
id: self.n_votes, id: self.n_votes,
vote_end: now() + msg.vote_time, vote_end: now() + msg.vote_time,
proposal: Proposal { proposal: proposal,
type: 2, quorum_percent: msg.quorum_percent,
data: msg.distribution votes: emptyMap(),
}, result: null
quorum_percent: msg.quorum_percent
}; };
let i: Int = 0; let i: Int = 0;
while (i < self.admins.addresses.length) { while (i < self.admins.addresses.length) {
@ -155,20 +128,52 @@ contract Foundation {
self.n_votes = self.n_votes + 1; self.n_votes = self.n_votes + 1;
} }
receive(msg: InitiateFullLiquidationVote) { // receive(msg: InitiateDistributionVote) {
// let ctx: Context = context();
// require(ctx.sender == self.admins.addresses.addresses.get(msg.adminIndex), "Only an admin can initiate a vote");
// require(ctx.value >= ton("1.0"), "Voting requires at least 1 ton for the fees");
// require(msg.quorum_percent > 20 && msg.quorum_percent <= 100, "Invalid quorum percent");
// require(msg.vote_time > 0 && msg.vote_time < 3 * 24 * 3600, "Invalid vote time");
// let proposal: Proposal = Proposal {
// type: 2,
// blacklistAddress: null,
// distribution: msg.distribution
// };
// let vote: Vote = Vote {
// id: self.n_votes,
// vote_end: now() + msg.vote_time,
// proposal: proposal,
// quorum_percent: msg.quorum_percent,
// votes: emptyMap(),
// result: null
// };
// let i: Int = 0;
// while (i < self.admins.addresses.length) {
// vote.votes.set(i, -1);
// i = i + 1;
// }
// self.votes.set(self.n_votes, vote);
// self.n_votes = self.n_votes + 1;
// }
receive(msg: InitiateLiquidationVote) {
let ctx: Context = context(); let ctx: Context = context();
require(ctx.sender == self.admins.addresses.addresses.get(msg.adminIndex), "Only an admin can initiate a vote"); require(ctx.sender == self.admins.addresses.addresses.get(msg.adminIndex), "Only an admin can initiate a vote");
require(ctx.value >= ton("1.0"), "Voting requires at least 1 ton for the fees") require(ctx.value >= ton("1.0"), "Voting requires at least 1 ton for the fees");
require(msg.quorum_percent > 85 && msg.quorum_percent <= 100, "Invalid quorum percent"); require(msg.quorum_percent > 85 && msg.quorum_percent <= 100, "Invalid quorum percent");
require(msg.vote_time > 0 && msg.vote_time < 3 * 24 * 3600, "Invalid vote time"); require(msg.vote_time > 0 && msg.vote_time < 3 * 24 * 3600, "Invalid vote time");
let vote = Vote { let vote: Vote = Vote {
id: self.n_votes, id: self.n_votes,
vote_end: now() + msg.vote_time, vote_end: now() + msg.vote_time,
proposal: Proposal { proposal: Proposal {
type: 1, type: 1,
data: beginCell().endCell() blacklistAddress: null,
distribution: null
}, },
quorum_percent: msg.quorum_percent quorum_percent: msg.quorum_percent,
votes: emptyMap(),
result: null
}; };
let i: Int = 0; let i: Int = 0;
while (i < self.admins.addresses.length) { while (i < self.admins.addresses.length) {
@ -187,7 +192,7 @@ contract Foundation {
let i: Int = 0; let i: Int = 0;
while (i < self.admins.addresses.length) { while (i < self.admins.addresses.length) {
let addr: Address = self.admins.addresses.addresses.get(i)!!; let addr: Address = self.admins.addresses.addresses.get(i)!!;
let percent: Int = self.admins.percents.percents.get(i)!!; let percent: Int = self.admins.percents.get(addr)!!;
let amount: Int = value * percent / 100; let amount: Int = value * percent / 100;
// todo: record the profit // todo: record the profit
let current_profit: Int = 0; let current_profit: Int = 0;
@ -204,10 +209,10 @@ contract Foundation {
receive(msg: RequestUnstake) { receive(msg: RequestUnstake) {
// If this is sent by one of the founders, it means that the user wants to unstake // If this is sent by one of the founders, it means that the user wants to unstake
let ctx: Context = context(); let ctx: Context = context();
require(self.founders.get(msg.founderIndex) == ctx.sender, "Only a founder can request unstake"); require(self.founders.addresses.get(msg.founderIndex) == ctx.sender, "Only a founder can request unstake");
send(SendParameters{ send(SendParameters{
to: self.tonb, to: self.tonb,
value: msg.amount, value: 0,
mode: SendRemainingValue, mode: SendRemainingValue,
body: Unstake { amount: 0 }.toCell() body: Unstake { amount: 0 }.toCell()
}); });

6
sources/jetton.tact

@ -6,6 +6,7 @@ import "./jetton_trait";
import "./staking"; import "./staking";
import "./constants"; import "./constants";
import "./pseudostaking"; import "./pseudostaking";
import "./foundation";
message Deposit { message Deposit {
amount: Int as coins; amount: Int as coins;
@ -60,4 +61,9 @@ contract TONB with TONBTrait {
receive(msg: SetStakingPool) { receive(msg: SetStakingPool) {
self.staking_pool = msg.staking_pool; self.staking_pool = msg.staking_pool;
} }
receive(msg: SetOwner) {
require(self.owner == context().sender, "only the owner can set a new owner");
self.owner = msg.owner;
}
} }

6
sources/messages.tact

@ -105,7 +105,7 @@ message FinishVote {
voteId: Int; voteId: Int;
} }
message Vote { message VoteMsg {
voteId: Int; voteId: Int;
adminIndex: Int; adminIndex: Int;
vote: Int; // 0 - abstain, 1 - yes, 2 - no vote: Int; // 0 - abstain, 1 - yes, 2 - no
@ -145,4 +145,8 @@ message RequestUnstake {
message CollectProfit { message CollectProfit {
adminIndex: Int; adminIndex: Int;
}
message SetOwner {
owner: Address;
} }

2
sources/output/jetton_Linker.abi

File diff suppressed because one or more lines are too long

2
sources/output/jetton_Linker.code.fc

@ -229,5 +229,5 @@ _ supported_interfaces() method_id {
} }
_ get_abi_ipfs() { _ get_abi_ipfs() {
return "ipfs://QmeGA7QUi3FCDzQtd9VhqDi1VpHx2sbycwoWaDsMsQNDS3"; return "ipfs://QmPdxwain9Y3xSr42K9ApJ5UsTURQZGtDmdhUSMQqrzYux";
} }

2
sources/output/jetton_Linker.code.fif

@ -354,6 +354,6 @@ PROGRAM{
209801025412363888721030803524359905849 PUSHINT 209801025412363888721030803524359905849 PUSHINT
}> }>
get_abi_ipfs PROC:<{ get_abi_ipfs PROC:<{
x{697066733a2f2f516d65474137515569334643447a51746439566871446931567048783273627963776f576144734d73514e445333} PUSHSLICE x{697066733a2f2f516d5064787761696e39593378537234324b3941704a355573545552515a4774446d646855534d5171727a597578} PUSHSLICE
}> }>
}END>c }END>c

20
sources/output/jetton_Linker.md

@ -3,7 +3,7 @@ Contract: Linker
BOC Size: 645 bytes BOC Size: 645 bytes
# Types # Types
Total Types: 33 Total Types: 36
## StateInit ## StateInit
TLB: `_ code:^cell data:^cell = StateInit` TLB: `_ code:^cell data:^cell = StateInit`
@ -85,9 +85,9 @@ Signature: `InitiateLiquidationVote{adminIndex:int257,quorum_percent:int257,vote
TLB: `finish_vote#2a574443 voteId:int257 = FinishVote` TLB: `finish_vote#2a574443 voteId:int257 = FinishVote`
Signature: `FinishVote{voteId:int257}` Signature: `FinishVote{voteId:int257}`
## Vote ## VoteMsg
TLB: `vote#b670f4ce voteId:int257 adminIndex:int257 vote:int257 = Vote` TLB: `vote_msg#58fde8ab voteId:int257 adminIndex:int257 vote:int257 = VoteMsg`
Signature: `Vote{voteId:int257,adminIndex:int257,vote:int257}` Signature: `VoteMsg{voteId:int257,adminIndex:int257,vote:int257}`
## AddressList ## AddressList
TLB: `_ addresses:dict<int, address> length:int257 = AddressList` TLB: `_ addresses:dict<int, address> length:int257 = AddressList`
@ -121,10 +121,22 @@ Signature: `RequestUnstake{founderIndex:int257}`
TLB: `collect_profit#51912735 adminIndex:int257 = CollectProfit` TLB: `collect_profit#51912735 adminIndex:int257 = CollectProfit`
Signature: `CollectProfit{adminIndex:int257}` Signature: `CollectProfit{adminIndex:int257}`
## SetOwner
TLB: `set_owner#b71c6df6 owner:address = SetOwner`
Signature: `SetOwner{owner:address}`
## WithdrawalRequests ## WithdrawalRequests
TLB: `_ addresses:dict<int, address> amounts:dict<int, int> n_requests:int257 = WithdrawalRequests` TLB: `_ addresses:dict<int, address> amounts:dict<int, int> n_requests:int257 = WithdrawalRequests`
Signature: `WithdrawalRequests{addresses:dict<int, address>,amounts:dict<int, int>,n_requests:int257}` Signature: `WithdrawalRequests{addresses:dict<int, address>,amounts:dict<int, int>,n_requests:int257}`
## Proposal
TLB: `_ type:int257 blacklistAddress:Maybe address distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>} = Proposal`
Signature: `Proposal{type:int257,blacklistAddress:Maybe address,distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>}}`
## Vote
TLB: `_ id:int257 votes:dict<int, int> vote_end:int257 proposal:Proposal{type:int257,blacklistAddress:Maybe address,distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>}} quorum_percent:int257 ended:bool result:Maybe bool = Vote`
Signature: `Vote{id:int257,votes:dict<int, int>,vote_end:int257,proposal:Proposal{type:int257,blacklistAddress:Maybe address,distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>}},quorum_percent:int257,ended:bool,result:Maybe bool}`
## ChangeOwner ## ChangeOwner
TLB: `change_owner#0f474d03 newOwner:address = ChangeOwner` TLB: `change_owner#0f474d03 newOwner:address = ChangeOwner`
Signature: `ChangeOwner{newOwner:address}` Signature: `ChangeOwner{newOwner:address}`

2
sources/output/jetton_Linker.pkg

File diff suppressed because one or more lines are too long

211
sources/output/jetton_Linker.ts

@ -1065,40 +1065,40 @@ function dictValueParserFinishVote(): DictionaryValue<FinishVote> {
} }
} }
} }
export type Vote = { export type VoteMsg = {
$$type: 'Vote'; $$type: 'VoteMsg';
voteId: bigint; voteId: bigint;
adminIndex: bigint; adminIndex: bigint;
vote: bigint; vote: bigint;
} }
export function storeVote(src: Vote) { export function storeVoteMsg(src: VoteMsg) {
return (builder: Builder) => { return (builder: Builder) => {
let b_0 = builder; let b_0 = builder;
b_0.storeUint(3060856014, 32); b_0.storeUint(1493035179, 32);
b_0.storeInt(src.voteId, 257); b_0.storeInt(src.voteId, 257);
b_0.storeInt(src.adminIndex, 257); b_0.storeInt(src.adminIndex, 257);
b_0.storeInt(src.vote, 257); b_0.storeInt(src.vote, 257);
}; };
} }
export function loadVote(slice: Slice) { export function loadVoteMsg(slice: Slice) {
let sc_0 = slice; let sc_0 = slice;
if (sc_0.loadUint(32) !== 3060856014) { throw Error('Invalid prefix'); } if (sc_0.loadUint(32) !== 1493035179) { throw Error('Invalid prefix'); }
let _voteId = sc_0.loadIntBig(257); let _voteId = sc_0.loadIntBig(257);
let _adminIndex = sc_0.loadIntBig(257); let _adminIndex = sc_0.loadIntBig(257);
let _vote = sc_0.loadIntBig(257); let _vote = sc_0.loadIntBig(257);
return { $$type: 'Vote' as const, voteId: _voteId, adminIndex: _adminIndex, vote: _vote }; return { $$type: 'VoteMsg' as const, voteId: _voteId, adminIndex: _adminIndex, vote: _vote };
} }
function loadTupleVote(source: TupleReader) { function loadTupleVoteMsg(source: TupleReader) {
let _voteId = source.readBigNumber(); let _voteId = source.readBigNumber();
let _adminIndex = source.readBigNumber(); let _adminIndex = source.readBigNumber();
let _vote = source.readBigNumber(); let _vote = source.readBigNumber();
return { $$type: 'Vote' as const, voteId: _voteId, adminIndex: _adminIndex, vote: _vote }; return { $$type: 'VoteMsg' as const, voteId: _voteId, adminIndex: _adminIndex, vote: _vote };
} }
function storeTupleVote(source: Vote) { function storeTupleVoteMsg(source: VoteMsg) {
let builder = new TupleBuilder(); let builder = new TupleBuilder();
builder.writeNumber(source.voteId); builder.writeNumber(source.voteId);
builder.writeNumber(source.adminIndex); builder.writeNumber(source.adminIndex);
@ -1106,13 +1106,13 @@ function storeTupleVote(source: Vote) {
return builder.build(); return builder.build();
} }
function dictValueParserVote(): DictionaryValue<Vote> { function dictValueParserVoteMsg(): DictionaryValue<VoteMsg> {
return { return {
serialize: (src, buidler) => { serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeVote(src)).endCell()); buidler.storeRef(beginCell().store(storeVoteMsg(src)).endCell());
}, },
parse: (src) => { parse: (src) => {
return loadVote(src.loadRef().beginParse()); return loadVoteMsg(src.loadRef().beginParse());
} }
} }
} }
@ -1468,6 +1468,47 @@ function dictValueParserCollectProfit(): DictionaryValue<CollectProfit> {
} }
} }
} }
export type SetOwner = {
$$type: 'SetOwner';
owner: Address;
}
export function storeSetOwner(src: SetOwner) {
return (builder: Builder) => {
let b_0 = builder;
b_0.storeUint(3072093686, 32);
b_0.storeAddress(src.owner);
};
}
export function loadSetOwner(slice: Slice) {
let sc_0 = slice;
if (sc_0.loadUint(32) !== 3072093686) { throw Error('Invalid prefix'); }
let _owner = sc_0.loadAddress();
return { $$type: 'SetOwner' as const, owner: _owner };
}
function loadTupleSetOwner(source: TupleReader) {
let _owner = source.readAddress();
return { $$type: 'SetOwner' as const, owner: _owner };
}
function storeTupleSetOwner(source: SetOwner) {
let builder = new TupleBuilder();
builder.writeAddress(source.owner);
return builder.build();
}
function dictValueParserSetOwner(): DictionaryValue<SetOwner> {
return {
serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeSetOwner(src)).endCell());
},
parse: (src) => {
return loadSetOwner(src.loadRef().beginParse());
}
}
}
export type WithdrawalRequests = { export type WithdrawalRequests = {
$$type: 'WithdrawalRequests'; $$type: 'WithdrawalRequests';
addresses: Dictionary<bigint, Address>; addresses: Dictionary<bigint, Address>;
@ -1517,6 +1558,135 @@ function dictValueParserWithdrawalRequests(): DictionaryValue<WithdrawalRequests
} }
} }
} }
export type Proposal = {
$$type: 'Proposal';
type: bigint;
blacklistAddress: Address | null;
distribution: Distribution | null;
}
export function storeProposal(src: Proposal) {
return (builder: Builder) => {
let b_0 = builder;
b_0.storeInt(src.type, 257);
b_0.storeAddress(src.blacklistAddress);
if (src.distribution !== null && src.distribution !== undefined) { b_0.storeBit(true); b_0.store(storeDistribution(src.distribution)); } else { b_0.storeBit(false); }
};
}
export function loadProposal(slice: Slice) {
let sc_0 = slice;
let _type = sc_0.loadIntBig(257);
let _blacklistAddress = sc_0.loadMaybeAddress();
let _distribution = sc_0.loadBit() ? loadDistribution(sc_0) : null;
return { $$type: 'Proposal' as const, type: _type, blacklistAddress: _blacklistAddress, distribution: _distribution };
}
function loadTupleProposal(source: TupleReader) {
let _type = source.readBigNumber();
let _blacklistAddress = source.readAddressOpt();
const _distribution_p = source.readTupleOpt();
const _distribution = _distribution_p ? loadTupleDistribution(_distribution_p) : null;
return { $$type: 'Proposal' as const, type: _type, blacklistAddress: _blacklistAddress, distribution: _distribution };
}
function storeTupleProposal(source: Proposal) {
let builder = new TupleBuilder();
builder.writeNumber(source.type);
builder.writeAddress(source.blacklistAddress);
if (source.distribution !== null && source.distribution !== undefined) {
builder.writeTuple(storeTupleDistribution(source.distribution));
} else {
builder.writeTuple(null);
}
return builder.build();
}
function dictValueParserProposal(): DictionaryValue<Proposal> {
return {
serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeProposal(src)).endCell());
},
parse: (src) => {
return loadProposal(src.loadRef().beginParse());
}
}
}
export type Vote = {
$$type: 'Vote';
id: bigint;
votes: Dictionary<bigint, bigint>;
vote_end: bigint;
proposal: Proposal;
quorum_percent: bigint;
ended: boolean;
result: boolean | null;
}
export function storeVote(src: Vote) {
return (builder: Builder) => {
let b_0 = builder;
b_0.storeInt(src.id, 257);
b_0.storeDict(src.votes, Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257));
b_0.storeInt(src.vote_end, 257);
let b_1 = new Builder();
b_1.store(storeProposal(src.proposal));
let b_2 = new Builder();
b_2.storeInt(src.quorum_percent, 257);
b_2.storeBit(src.ended);
if (src.result !== null && src.result !== undefined) { b_2.storeBit(true).storeBit(src.result); } else { b_2.storeBit(false); }
b_1.storeRef(b_2.endCell());
b_0.storeRef(b_1.endCell());
};
}
export function loadVote(slice: Slice) {
let sc_0 = slice;
let _id = sc_0.loadIntBig(257);
let _votes = Dictionary.load(Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257), sc_0);
let _vote_end = sc_0.loadIntBig(257);
let sc_1 = sc_0.loadRef().beginParse();
let _proposal = loadProposal(sc_1);
let sc_2 = sc_1.loadRef().beginParse();
let _quorum_percent = sc_2.loadIntBig(257);
let _ended = sc_2.loadBit();
let _result = sc_2.loadBit() ? sc_2.loadBit() : null;
return { $$type: 'Vote' as const, id: _id, votes: _votes, vote_end: _vote_end, proposal: _proposal, quorum_percent: _quorum_percent, ended: _ended, result: _result };
}
function loadTupleVote(source: TupleReader) {
let _id = source.readBigNumber();
let _votes = Dictionary.loadDirect(Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257), source.readCellOpt());
let _vote_end = source.readBigNumber();
const _proposal = loadTupleProposal(source.readTuple());
let _quorum_percent = source.readBigNumber();
let _ended = source.readBoolean();
let _result = source.readBooleanOpt();
return { $$type: 'Vote' as const, id: _id, votes: _votes, vote_end: _vote_end, proposal: _proposal, quorum_percent: _quorum_percent, ended: _ended, result: _result };
}
function storeTupleVote(source: Vote) {
let builder = new TupleBuilder();
builder.writeNumber(source.id);
builder.writeCell(source.votes.size > 0 ? beginCell().storeDictDirect(source.votes, Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257)).endCell() : null);
builder.writeNumber(source.vote_end);
builder.writeTuple(storeTupleProposal(source.proposal));
builder.writeNumber(source.quorum_percent);
builder.writeBoolean(source.ended);
builder.writeBoolean(source.result);
return builder.build();
}
function dictValueParserVote(): DictionaryValue<Vote> {
return {
serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeVote(src)).endCell());
},
parse: (src) => {
return loadVote(src.loadRef().beginParse());
}
}
}
export type ChangeOwner = { export type ChangeOwner = {
$$type: 'ChangeOwner'; $$type: 'ChangeOwner';
newOwner: Address; newOwner: Address;
@ -1695,11 +1865,26 @@ const Linker_errors: { [key: number]: { message: string } } = {
136: { message: `Invalid address` }, 136: { message: `Invalid address` },
4429: { message: `Invalid sender` }, 4429: { message: `Invalid sender` },
6384: { message: `not enough money for withdraw` }, 6384: { message: `not enough money for withdraw` },
6873: { message: `Only an admin can initiate a vote` },
13650: { message: `Invalid bounced message` }, 13650: { message: `Invalid bounced message` },
16059: { message: `Invalid value` }, 16059: { message: `Invalid value` },
16994: { message: `Vote is finished` },
18474: { message: `only the owner can set a new owner` },
19362: { message: `Invalid quorum percent` },
29720: { message: `Invalid vote` },
29821: { message: `Voting requires at least 1 ton for the fees` },
30386: { message: `Vote already ended` },
32366: { message: `not enough money for deposit` }, 32366: { message: `not enough money for deposit` },
34326: { message: `Vote is not finished yet` },
37444: { message: `Only a founder can request unstake` },
41207: { message: `invalid sender` }, 41207: { message: `invalid sender` },
42983: { message: `No profit to collect` },
44816: { message: `Wallet is blacklisted` }, 44816: { message: `Wallet is blacklisted` },
46931: { message: `Invalid vote id` },
49606: { message: `Invalid admin index` },
53981: { message: `Only an admin can collect profit` },
56549: { message: `Only an admin can vote` },
61070: { message: `Invalid vote time` },
61265: { message: `Only the owner can trigger un-staking` }, 61265: { message: `Only the owner can trigger un-staking` },
62972: { message: `Invalid balance` }, 62972: { message: `Invalid balance` },
} }

2
sources/output/jetton_PseudoStaking.abi

File diff suppressed because one or more lines are too long

2
sources/output/jetton_PseudoStaking.code.fc

@ -284,5 +284,5 @@ _ supported_interfaces() method_id {
} }
_ get_abi_ipfs() { _ get_abi_ipfs() {
return "ipfs://QmTpVYvpJy7wvLrPak1F6KJSC44yccvcdix7pmrnjZmAHa"; return "ipfs://QmauXGiekdCW4GNrULhiN8JhMuRfKgUTpLsD9DTSjKjW2f";
} }

2
sources/output/jetton_PseudoStaking.code.fif

@ -490,6 +490,6 @@ PROGRAM{
209801025412363888721030803524359905849 PUSHINT 209801025412363888721030803524359905849 PUSHINT
}> }>
get_abi_ipfs PROC:<{ get_abi_ipfs PROC:<{
x{697066733a2f2f516d5470565976704a793777764c7250616b3146364b4a53433434796363766364697837706d726e6a5a6d414861} PUSHSLICE x{697066733a2f2f516d6175584769656b64435734474e72554c68694e384a684d7552664b675554704c7344394454536a4b6a573266} PUSHSLICE
}> }>
}END>c }END>c

20
sources/output/jetton_PseudoStaking.md

@ -3,7 +3,7 @@ Contract: PseudoStaking
BOC Size: 876 bytes BOC Size: 876 bytes
# Types # Types
Total Types: 33 Total Types: 36
## StateInit ## StateInit
TLB: `_ code:^cell data:^cell = StateInit` TLB: `_ code:^cell data:^cell = StateInit`
@ -85,9 +85,9 @@ Signature: `InitiateLiquidationVote{adminIndex:int257,quorum_percent:int257,vote
TLB: `finish_vote#2a574443 voteId:int257 = FinishVote` TLB: `finish_vote#2a574443 voteId:int257 = FinishVote`
Signature: `FinishVote{voteId:int257}` Signature: `FinishVote{voteId:int257}`
## Vote ## VoteMsg
TLB: `vote#b670f4ce voteId:int257 adminIndex:int257 vote:int257 = Vote` TLB: `vote_msg#58fde8ab voteId:int257 adminIndex:int257 vote:int257 = VoteMsg`
Signature: `Vote{voteId:int257,adminIndex:int257,vote:int257}` Signature: `VoteMsg{voteId:int257,adminIndex:int257,vote:int257}`
## AddressList ## AddressList
TLB: `_ addresses:dict<int, address> length:int257 = AddressList` TLB: `_ addresses:dict<int, address> length:int257 = AddressList`
@ -121,10 +121,22 @@ Signature: `RequestUnstake{founderIndex:int257}`
TLB: `collect_profit#51912735 adminIndex:int257 = CollectProfit` TLB: `collect_profit#51912735 adminIndex:int257 = CollectProfit`
Signature: `CollectProfit{adminIndex:int257}` Signature: `CollectProfit{adminIndex:int257}`
## SetOwner
TLB: `set_owner#b71c6df6 owner:address = SetOwner`
Signature: `SetOwner{owner:address}`
## WithdrawalRequests ## WithdrawalRequests
TLB: `_ addresses:dict<int, address> amounts:dict<int, int> n_requests:int257 = WithdrawalRequests` TLB: `_ addresses:dict<int, address> amounts:dict<int, int> n_requests:int257 = WithdrawalRequests`
Signature: `WithdrawalRequests{addresses:dict<int, address>,amounts:dict<int, int>,n_requests:int257}` Signature: `WithdrawalRequests{addresses:dict<int, address>,amounts:dict<int, int>,n_requests:int257}`
## Proposal
TLB: `_ type:int257 blacklistAddress:Maybe address distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>} = Proposal`
Signature: `Proposal{type:int257,blacklistAddress:Maybe address,distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>}}`
## Vote
TLB: `_ id:int257 votes:dict<int, int> vote_end:int257 proposal:Proposal{type:int257,blacklistAddress:Maybe address,distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>}} quorum_percent:int257 ended:bool result:Maybe bool = Vote`
Signature: `Vote{id:int257,votes:dict<int, int>,vote_end:int257,proposal:Proposal{type:int257,blacklistAddress:Maybe address,distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>}},quorum_percent:int257,ended:bool,result:Maybe bool}`
## ChangeOwner ## ChangeOwner
TLB: `change_owner#0f474d03 newOwner:address = ChangeOwner` TLB: `change_owner#0f474d03 newOwner:address = ChangeOwner`
Signature: `ChangeOwner{newOwner:address}` Signature: `ChangeOwner{newOwner:address}`

2
sources/output/jetton_PseudoStaking.pkg

File diff suppressed because one or more lines are too long

211
sources/output/jetton_PseudoStaking.ts

@ -1065,40 +1065,40 @@ function dictValueParserFinishVote(): DictionaryValue<FinishVote> {
} }
} }
} }
export type Vote = { export type VoteMsg = {
$$type: 'Vote'; $$type: 'VoteMsg';
voteId: bigint; voteId: bigint;
adminIndex: bigint; adminIndex: bigint;
vote: bigint; vote: bigint;
} }
export function storeVote(src: Vote) { export function storeVoteMsg(src: VoteMsg) {
return (builder: Builder) => { return (builder: Builder) => {
let b_0 = builder; let b_0 = builder;
b_0.storeUint(3060856014, 32); b_0.storeUint(1493035179, 32);
b_0.storeInt(src.voteId, 257); b_0.storeInt(src.voteId, 257);
b_0.storeInt(src.adminIndex, 257); b_0.storeInt(src.adminIndex, 257);
b_0.storeInt(src.vote, 257); b_0.storeInt(src.vote, 257);
}; };
} }
export function loadVote(slice: Slice) { export function loadVoteMsg(slice: Slice) {
let sc_0 = slice; let sc_0 = slice;
if (sc_0.loadUint(32) !== 3060856014) { throw Error('Invalid prefix'); } if (sc_0.loadUint(32) !== 1493035179) { throw Error('Invalid prefix'); }
let _voteId = sc_0.loadIntBig(257); let _voteId = sc_0.loadIntBig(257);
let _adminIndex = sc_0.loadIntBig(257); let _adminIndex = sc_0.loadIntBig(257);
let _vote = sc_0.loadIntBig(257); let _vote = sc_0.loadIntBig(257);
return { $$type: 'Vote' as const, voteId: _voteId, adminIndex: _adminIndex, vote: _vote }; return { $$type: 'VoteMsg' as const, voteId: _voteId, adminIndex: _adminIndex, vote: _vote };
} }
function loadTupleVote(source: TupleReader) { function loadTupleVoteMsg(source: TupleReader) {
let _voteId = source.readBigNumber(); let _voteId = source.readBigNumber();
let _adminIndex = source.readBigNumber(); let _adminIndex = source.readBigNumber();
let _vote = source.readBigNumber(); let _vote = source.readBigNumber();
return { $$type: 'Vote' as const, voteId: _voteId, adminIndex: _adminIndex, vote: _vote }; return { $$type: 'VoteMsg' as const, voteId: _voteId, adminIndex: _adminIndex, vote: _vote };
} }
function storeTupleVote(source: Vote) { function storeTupleVoteMsg(source: VoteMsg) {
let builder = new TupleBuilder(); let builder = new TupleBuilder();
builder.writeNumber(source.voteId); builder.writeNumber(source.voteId);
builder.writeNumber(source.adminIndex); builder.writeNumber(source.adminIndex);
@ -1106,13 +1106,13 @@ function storeTupleVote(source: Vote) {
return builder.build(); return builder.build();
} }
function dictValueParserVote(): DictionaryValue<Vote> { function dictValueParserVoteMsg(): DictionaryValue<VoteMsg> {
return { return {
serialize: (src, buidler) => { serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeVote(src)).endCell()); buidler.storeRef(beginCell().store(storeVoteMsg(src)).endCell());
}, },
parse: (src) => { parse: (src) => {
return loadVote(src.loadRef().beginParse()); return loadVoteMsg(src.loadRef().beginParse());
} }
} }
} }
@ -1468,6 +1468,47 @@ function dictValueParserCollectProfit(): DictionaryValue<CollectProfit> {
} }
} }
} }
export type SetOwner = {
$$type: 'SetOwner';
owner: Address;
}
export function storeSetOwner(src: SetOwner) {
return (builder: Builder) => {
let b_0 = builder;
b_0.storeUint(3072093686, 32);
b_0.storeAddress(src.owner);
};
}
export function loadSetOwner(slice: Slice) {
let sc_0 = slice;
if (sc_0.loadUint(32) !== 3072093686) { throw Error('Invalid prefix'); }
let _owner = sc_0.loadAddress();
return { $$type: 'SetOwner' as const, owner: _owner };
}
function loadTupleSetOwner(source: TupleReader) {
let _owner = source.readAddress();
return { $$type: 'SetOwner' as const, owner: _owner };
}
function storeTupleSetOwner(source: SetOwner) {
let builder = new TupleBuilder();
builder.writeAddress(source.owner);
return builder.build();
}
function dictValueParserSetOwner(): DictionaryValue<SetOwner> {
return {
serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeSetOwner(src)).endCell());
},
parse: (src) => {
return loadSetOwner(src.loadRef().beginParse());
}
}
}
export type WithdrawalRequests = { export type WithdrawalRequests = {
$$type: 'WithdrawalRequests'; $$type: 'WithdrawalRequests';
addresses: Dictionary<bigint, Address>; addresses: Dictionary<bigint, Address>;
@ -1517,6 +1558,135 @@ function dictValueParserWithdrawalRequests(): DictionaryValue<WithdrawalRequests
} }
} }
} }
export type Proposal = {
$$type: 'Proposal';
type: bigint;
blacklistAddress: Address | null;
distribution: Distribution | null;
}
export function storeProposal(src: Proposal) {
return (builder: Builder) => {
let b_0 = builder;
b_0.storeInt(src.type, 257);
b_0.storeAddress(src.blacklistAddress);
if (src.distribution !== null && src.distribution !== undefined) { b_0.storeBit(true); b_0.store(storeDistribution(src.distribution)); } else { b_0.storeBit(false); }
};
}
export function loadProposal(slice: Slice) {
let sc_0 = slice;
let _type = sc_0.loadIntBig(257);
let _blacklistAddress = sc_0.loadMaybeAddress();
let _distribution = sc_0.loadBit() ? loadDistribution(sc_0) : null;
return { $$type: 'Proposal' as const, type: _type, blacklistAddress: _blacklistAddress, distribution: _distribution };
}
function loadTupleProposal(source: TupleReader) {
let _type = source.readBigNumber();
let _blacklistAddress = source.readAddressOpt();
const _distribution_p = source.readTupleOpt();
const _distribution = _distribution_p ? loadTupleDistribution(_distribution_p) : null;
return { $$type: 'Proposal' as const, type: _type, blacklistAddress: _blacklistAddress, distribution: _distribution };
}
function storeTupleProposal(source: Proposal) {
let builder = new TupleBuilder();
builder.writeNumber(source.type);
builder.writeAddress(source.blacklistAddress);
if (source.distribution !== null && source.distribution !== undefined) {
builder.writeTuple(storeTupleDistribution(source.distribution));
} else {
builder.writeTuple(null);
}
return builder.build();
}
function dictValueParserProposal(): DictionaryValue<Proposal> {
return {
serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeProposal(src)).endCell());
},
parse: (src) => {
return loadProposal(src.loadRef().beginParse());
}
}
}
export type Vote = {
$$type: 'Vote';
id: bigint;
votes: Dictionary<bigint, bigint>;
vote_end: bigint;
proposal: Proposal;
quorum_percent: bigint;
ended: boolean;
result: boolean | null;
}
export function storeVote(src: Vote) {
return (builder: Builder) => {
let b_0 = builder;
b_0.storeInt(src.id, 257);
b_0.storeDict(src.votes, Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257));
b_0.storeInt(src.vote_end, 257);
let b_1 = new Builder();
b_1.store(storeProposal(src.proposal));
let b_2 = new Builder();
b_2.storeInt(src.quorum_percent, 257);
b_2.storeBit(src.ended);
if (src.result !== null && src.result !== undefined) { b_2.storeBit(true).storeBit(src.result); } else { b_2.storeBit(false); }
b_1.storeRef(b_2.endCell());
b_0.storeRef(b_1.endCell());
};
}
export function loadVote(slice: Slice) {
let sc_0 = slice;
let _id = sc_0.loadIntBig(257);
let _votes = Dictionary.load(Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257), sc_0);
let _vote_end = sc_0.loadIntBig(257);
let sc_1 = sc_0.loadRef().beginParse();
let _proposal = loadProposal(sc_1);
let sc_2 = sc_1.loadRef().beginParse();
let _quorum_percent = sc_2.loadIntBig(257);
let _ended = sc_2.loadBit();
let _result = sc_2.loadBit() ? sc_2.loadBit() : null;
return { $$type: 'Vote' as const, id: _id, votes: _votes, vote_end: _vote_end, proposal: _proposal, quorum_percent: _quorum_percent, ended: _ended, result: _result };
}
function loadTupleVote(source: TupleReader) {
let _id = source.readBigNumber();
let _votes = Dictionary.loadDirect(Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257), source.readCellOpt());
let _vote_end = source.readBigNumber();
const _proposal = loadTupleProposal(source.readTuple());
let _quorum_percent = source.readBigNumber();
let _ended = source.readBoolean();
let _result = source.readBooleanOpt();
return { $$type: 'Vote' as const, id: _id, votes: _votes, vote_end: _vote_end, proposal: _proposal, quorum_percent: _quorum_percent, ended: _ended, result: _result };
}
function storeTupleVote(source: Vote) {
let builder = new TupleBuilder();
builder.writeNumber(source.id);
builder.writeCell(source.votes.size > 0 ? beginCell().storeDictDirect(source.votes, Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257)).endCell() : null);
builder.writeNumber(source.vote_end);
builder.writeTuple(storeTupleProposal(source.proposal));
builder.writeNumber(source.quorum_percent);
builder.writeBoolean(source.ended);
builder.writeBoolean(source.result);
return builder.build();
}
function dictValueParserVote(): DictionaryValue<Vote> {
return {
serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeVote(src)).endCell());
},
parse: (src) => {
return loadVote(src.loadRef().beginParse());
}
}
}
export type ChangeOwner = { export type ChangeOwner = {
$$type: 'ChangeOwner'; $$type: 'ChangeOwner';
newOwner: Address; newOwner: Address;
@ -1692,11 +1862,26 @@ const PseudoStaking_errors: { [key: number]: { message: string } } = {
136: { message: `Invalid address` }, 136: { message: `Invalid address` },
4429: { message: `Invalid sender` }, 4429: { message: `Invalid sender` },
6384: { message: `not enough money for withdraw` }, 6384: { message: `not enough money for withdraw` },
6873: { message: `Only an admin can initiate a vote` },
13650: { message: `Invalid bounced message` }, 13650: { message: `Invalid bounced message` },
16059: { message: `Invalid value` }, 16059: { message: `Invalid value` },
16994: { message: `Vote is finished` },
18474: { message: `only the owner can set a new owner` },
19362: { message: `Invalid quorum percent` },
29720: { message: `Invalid vote` },
29821: { message: `Voting requires at least 1 ton for the fees` },
30386: { message: `Vote already ended` },
32366: { message: `not enough money for deposit` }, 32366: { message: `not enough money for deposit` },
34326: { message: `Vote is not finished yet` },
37444: { message: `Only a founder can request unstake` },
41207: { message: `invalid sender` }, 41207: { message: `invalid sender` },
42983: { message: `No profit to collect` },
44816: { message: `Wallet is blacklisted` }, 44816: { message: `Wallet is blacklisted` },
46931: { message: `Invalid vote id` },
49606: { message: `Invalid admin index` },
53981: { message: `Only an admin can collect profit` },
56549: { message: `Only an admin can vote` },
61070: { message: `Invalid vote time` },
61265: { message: `Only the owner can trigger un-staking` }, 61265: { message: `Only the owner can trigger un-staking` },
62972: { message: `Invalid balance` }, 62972: { message: `Invalid balance` },
} }

2
sources/output/jetton_TONB.abi

File diff suppressed because one or more lines are too long

BIN
sources/output/jetton_TONB.code.boc

Binary file not shown.

25
sources/output/jetton_TONB.code.fc

@ -229,6 +229,12 @@ cell __gen_writecell_Unstake((int) v) inline_ref {
return (sc_0, (v'amount)); return (sc_0, (v'amount));
} }
(slice, ((slice))) __gen_read_SetOwner(slice sc_0) inline {
throw_unless(129, sc_0~load_uint(32) == 3072093686);
var v'owner = sc_0~__tact_load_address();
return (sc_0, (v'owner));
}
builder __gen_write_WithdrawalRequests(builder build_0, (cell, cell, int) v) inline { builder __gen_write_WithdrawalRequests(builder build_0, (cell, cell, int) v) inline {
var (v'addresses, v'amounts, v'n_requests) = v; var (v'addresses, v'amounts, v'n_requests) = v;
build_0 = build_0.store_dict(v'addresses); build_0 = build_0.store_dict(v'addresses);
@ -590,6 +596,14 @@ _ $__gen_get_owner() method_id(83229) {
return (($self'totalSupply, $self'owner, $self'content, $self'mintable, $self'first_linker, $self'last_linker, $self'n_linkers, $self'staking_pool, $self'in_the_pool, ($self'withdrawal_requests'addresses, $self'withdrawal_requests'amounts, $self'withdrawal_requests'n_requests)), ()); return (($self'totalSupply, $self'owner, $self'content, $self'mintable, $self'first_linker, $self'last_linker, $self'n_linkers, $self'staking_pool, $self'in_the_pool, ($self'withdrawal_requests'addresses, $self'withdrawal_requests'amounts, $self'withdrawal_requests'n_requests)), ());
} }
(((int, slice, cell, int, slice, slice, int, slice, int, (cell, cell, int))), ()) $__gen_TONB_receive_SetOwner((int, slice, cell, int, slice, slice, int, slice, int, (cell, cell, int)) $self, (slice) $msg) impure inline {
var ($self'totalSupply, $self'owner, $self'content, $self'mintable, $self'first_linker, $self'last_linker, $self'n_linkers, $self'staking_pool, $self'in_the_pool, ($self'withdrawal_requests'addresses, $self'withdrawal_requests'amounts, $self'withdrawal_requests'n_requests)) = $self;
var ($msg'owner) = $msg;
throw_unless(18474, __tact_address_eq($self'owner, __gen_Context_get_sender(__tact_context_get())));
$self'owner = $msg'owner;
return (($self'totalSupply, $self'owner, $self'content, $self'mintable, $self'first_linker, $self'last_linker, $self'n_linkers, $self'staking_pool, $self'in_the_pool, ($self'withdrawal_requests'addresses, $self'withdrawal_requests'amounts, $self'withdrawal_requests'n_requests)), ());
}
(((int, slice, cell, int, slice, slice, int, slice, int, (cell, cell, int))), ()) $__gen_TONB_receive_TokenUpdateContent((int, slice, cell, int, slice, slice, int, slice, int, (cell, cell, int)) $self, (cell) $msg) impure inline { (((int, slice, cell, int, slice, slice, int, slice, int, (cell, cell, int))), ()) $__gen_TONB_receive_TokenUpdateContent((int, slice, cell, int, slice, slice, int, slice, int, (cell, cell, int)) $self, (cell) $msg) impure inline {
var ($self'totalSupply, $self'owner, $self'content, $self'mintable, $self'first_linker, $self'last_linker, $self'n_linkers, $self'staking_pool, $self'in_the_pool, ($self'withdrawal_requests'addresses, $self'withdrawal_requests'amounts, $self'withdrawal_requests'n_requests)) = $self; var ($self'totalSupply, $self'owner, $self'content, $self'mintable, $self'first_linker, $self'last_linker, $self'n_linkers, $self'staking_pool, $self'in_the_pool, ($self'withdrawal_requests'addresses, $self'withdrawal_requests'amounts, $self'withdrawal_requests'n_requests)) = $self;
var ($msg'content) = $msg; var ($msg'content) = $msg;
@ -731,6 +745,15 @@ _ $__gen_get_owner() method_id(83229) {
return (); return ();
} }
;; Receive SetOwner message
if (op == 3072093686) {
var self = __gen_load_TONB();
var msg = in_msg~__gen_read_SetOwner();
self~$__gen_TONB_receive_SetOwner(msg);
__gen_store_TONB(self);
return ();
}
;; Receive TokenUpdateContent message ;; Receive TokenUpdateContent message
if (op == 201882270) { if (op == 201882270) {
var self = __gen_load_TONB(); var self = __gen_load_TONB();
@ -802,5 +825,5 @@ _ supported_interfaces() method_id {
} }
_ get_abi_ipfs() { _ get_abi_ipfs() {
return "ipfs://QmZei32YRHJRnTCv7qY3WpT16zADJCXJ6BC996CpHaiRqG"; return "ipfs://QmdViWXtZGNYCoQZNSUs9hgbK9arhozuqfVQidHJKMgjor";
} }

43
sources/output/jetton_TONB.code.fif

@ -33,6 +33,7 @@ PROGRAM{
DECLPROC __gen_write_Unstake DECLPROC __gen_write_Unstake
DECLPROC __gen_writecell_Unstake DECLPROC __gen_writecell_Unstake
DECLPROC __gen_read_Unstake DECLPROC __gen_read_Unstake
DECLPROC __gen_read_SetOwner
DECLPROC __gen_write_WithdrawalRequests DECLPROC __gen_write_WithdrawalRequests
DECLPROC __gen_read_WithdrawalRequests DECLPROC __gen_read_WithdrawalRequests
DECLPROC __gen_read_Deposit DECLPROC __gen_read_Deposit
@ -74,6 +75,7 @@ PROGRAM{
DECLPROC $__gen_TONB_receive DECLPROC $__gen_TONB_receive
DECLPROC $__gen_TONB_receive_Withdraw DECLPROC $__gen_TONB_receive_Withdraw
DECLPROC $__gen_TONB_receive_SetStakingPool DECLPROC $__gen_TONB_receive_SetStakingPool
DECLPROC $__gen_TONB_receive_SetOwner
DECLPROC $__gen_TONB_receive_TokenUpdateContent DECLPROC $__gen_TONB_receive_TokenUpdateContent
DECLPROC $__gen_TONB_receive_TokenBurnNotification DECLPROC $__gen_TONB_receive_TokenBurnNotification
DECLPROC $__gen_TONB_receive_BlacklistWallet DECLPROC $__gen_TONB_receive_BlacklistWallet
@ -405,6 +407,14 @@ PROGRAM{
LDIX LDIX
SWAP SWAP
}> }>
__gen_read_SetOwner PROCINLINE:<{
32 LDU
SWAP
3072093686 PUSHINT
EQUAL
129 THROWIFNOT
__tact_load_address INLINECALLDICT
}>
__gen_write_WithdrawalRequests PROCINLINE:<{ __gen_write_WithdrawalRequests PROCINLINE:<{
s2 s3 XCHG2 s2 s3 XCHG2
STDICT STDICT
@ -1023,6 +1033,15 @@ PROGRAM{
$__gen_TONB_receive_SetStakingPool PROCINLINE:<{ $__gen_TONB_receive_SetStakingPool PROCINLINE:<{
s5 POP s5 POP
}> }>
$__gen_TONB_receive_SetOwner PROCINLINE:<{
18474 PUSHINT
__tact_context_get INLINECALLDICT
__gen_Context_get_sender INLINECALLDICT
s1 s13 XCHG
__tact_address_eq INLINECALLDICT
s1 s12 XCHG
THROWANYIFNOT
}>
$__gen_TONB_receive_TokenUpdateContent PROCINLINE:<{ $__gen_TONB_receive_TokenUpdateContent PROCINLINE:<{
12 -ROLL 12 -ROLL
$__gen_TONB_requireOwner INLINECALLDICT $__gen_TONB_requireOwner INLINECALLDICT
@ -1389,6 +1408,28 @@ PROGRAM{
__gen_store_TONB INLINECALLDICT __gen_store_TONB INLINECALLDICT
}> }>
DUP DUP
3072093686 PUSHINT
EQUAL
IFJMP:<{
DROP
__gen_load_TONB INLINECALLDICT
s0 s12 XCHG
__gen_read_SetOwner INLINECALLDICT
NIP
s11 s12 XCHG
s10 s11 XCHG
s9 s10 XCHG
s8 s9 XCHG
s7 s8 XCHG
s6 s7 XCHG
s5 s6 XCHG
s4 s5 XCHG
s3 s4 XCHG
s1 s3 s0 XCHG3
$__gen_TONB_receive_SetOwner INLINECALLDICT
__gen_store_TONB INLINECALLDICT
}>
DUP
201882270 PUSHINT 201882270 PUSHINT
EQUAL EQUAL
IFJMP:<{ IFJMP:<{
@ -1523,6 +1564,6 @@ PROGRAM{
86142586315491086060343270784266291122 PUSHINT 86142586315491086060343270784266291122 PUSHINT
}> }>
get_abi_ipfs PROC:<{ get_abi_ipfs PROC:<{
x{697066733a2f2f516d5a656933325952484a526e5443763771593357705431367a41444a43584a3642433939364370486169527147} PUSHSLICE x{697066733a2f2f516d6456695758745a474e59436f515a4e535573396867624b396172686f7a75716656516964484a4b4d676a6f72} PUSHSLICE
}> }>
}END>c }END>c

242
sources/output/jetton_TONB.code.rev.fif

@ -170,7 +170,7 @@ SETCP0
2 GETGLOBVAR 2 GETGLOBVAR
MYADDR MYADDR
ROT ROT
56 CALLDICT 57 CALLDICT
}> CALLREF }> CALLREF
2DUP 2DUP
<{ <{
@ -207,7 +207,7 @@ SETCP0
2 GETGLOBVAR 2 GETGLOBVAR
MYADDR MYADDR
10 2 -2 PU2XC 10 2 -2 PU2XC
58 CALLDICT 59 CALLDICT
2DUP 2DUP
<{ <{
0 PUSHINT 0 PUSHINT
@ -1199,7 +1199,7 @@ SETCP0
2 GETGLOBVAR 2 GETGLOBVAR
MYADDR MYADDR
ROT ROT
56 CALLDICT 57 CALLDICT
}> CALLREF }> CALLREF
2DUP 2DUP
<{ <{
@ -1717,6 +1717,213 @@ SETCP0
}> PUSHCONT }> PUSHCONT
IFJMP IFJMP
s0 PUSH s0 PUSH
3072093686 PUSHINT
EQUAL
<{
s0 POP
c4 PUSH
CTOS
LDREF
s0 s1 XCHG
2 SETGLOBVAR
LDGRAMS
LDMSGADDR
s0 s1 XCHG
s0 s1 XCHG
1 LDI
s0 s1 XCHG
<{
LDREF
}> PUSHCONT
<{
PUSHNULL
s0 s1 XCHG
}> PUSHCONT
IFELSE
1 LDI
LDMSGADDR
s1 PUSH
2 PLDU
0 NEQINT
<{
s0 s1 XCHG
}> PUSHCONT
<{
s1 POP
PUSHNULL
}> PUSHCONT
IFELSE
s0 s1 XCHG
LDMSGADDR
s1 PUSH
2 PLDU
0 NEQINT
<{
s0 s1 XCHG
}> PUSHCONT
<{
s1 POP
PUSHNULL
}> PUSHCONT
IFELSE
s0 s1 XCHG
LDREF
s0 s1 XCHG
CTOS
257 PUSHINT
LDI
LDMSGADDR
s1 PUSH
2 PLDU
0 NEQINT
<{
s0 s1 XCHG
}> PUSHCONT
<{
s1 POP
PUSHNULL
}> PUSHCONT
IFELSE
s0 s1 XCHG
257 PUSHINT
LDI
LDREF
s0 POP
CTOS
LDDICT
LDDICT
257 PUSHINT
LDI
3 1 BLKSWAP
s3 POP
s6 s12 XCHG
s6 s11 XCHG
s6 s10 XCHG
s6 s9 XCHG
s6 s8 XCHG
s6 s7 XCHG
ROT
1 12 BLKDROP2
s0 s12 XCHG
32 LDU
s0 s1 XCHG
3072093686 PUSHINT
EQUAL
129 THROWIFNOT
LDMSGADDR
s0 s1 XCHG
s1 POP
s11 s12 XCHG
s10 s11 XCHG
s9 s10 XCHG
s8 s9 XCHG
s7 s8 XCHG
s6 s7 XCHG
s5 s6 XCHG
s4 s5 XCHG
s3 s4 XCHG
s1 s3 s0 XCHG3
18474 PUSHINT
1 GETGLOBVAR
4 UNTUPLE
s2 s3 XCHG
3 BLKDROP
s1 s13 XCHG
SDEQ
s1 s12 XCHG
THROWANYIFNOT
NEWC
2 GETGLOBVAR
s0 s1 XCHG
STREF
12 1 BLKSWAP
s12 s11 XCHG2
STGRAMS
s0 s9 XCHG2
STSLICER
s7 PUSH
ISNULL
NOT
<{
-1 PUSHINT
s0 s1 XCHG
1 STI
s1 s7 XCHG
STREF
}> PUSHCONT
<{
s7 POP
0 PUSHINT
s0 s7 XCHG2
1 STI
}> PUSHCONT
IFELSE
s1 s5 XCHG
1 STI
s0 s3 XCHG2
s0 PUSH
ISNULL
<{
s0 POP
0 PUSHINT
s0 s1 XCHG
2 STU
}> PUSHCONT
<{
STSLICER
}> PUSHCONT
IFELSE
s0 s1 XCHG
s0 PUSH
ISNULL
<{
s0 POP
0 PUSHINT
s0 s1 XCHG
2 STU
}> PUSHCONT
<{
STSLICER
}> PUSHCONT
IFELSE
s0 s1 XCHG
NEWC
257 PUSHINT
STIX
ROT
s0 PUSH
ISNULL
<{
s0 POP
0 PUSHINT
s0 s1 XCHG
2 STU
}> PUSHCONT
<{
STSLICER
}> PUSHCONT
IFELSE
s1 s2 XCHG
257 PUSHINT
STIX
NEWC
s3 s1 s3 XCHG3
s5 s4 XCHG2
s2 s3 XCHG2
STDICT
STDICT
257 PUSHINT
STIX
ENDC
ROT
STREF
ENDC
s0 s1 XCHG
STREF
ENDC
c4 POP
}> IFJMPREF
s0 PUSH
201882270 PUSHINT 201882270 PUSHINT
EQUAL EQUAL
<{ <{
@ -1936,7 +2143,8 @@ SETCP0
STREF STREF
ENDC ENDC
c4 POP c4 POP
}> IFJMPREF }> PUSHCONT
IFJMP
s0 PUSH s0 PUSH
2078119902 PUSHINT 2078119902 PUSHINT
EQUAL EQUAL
@ -2077,7 +2285,7 @@ SETCP0
2 GETGLOBVAR 2 GETGLOBVAR
MYADDR MYADDR
ROT ROT
56 CALLDICT 57 CALLDICT
}> CALLREF }> CALLREF
s0 s1 XCHG s0 s1 XCHG
4429 PUSHINT 4429 PUSHINT
@ -2508,7 +2716,7 @@ SETCP0
2 GETGLOBVAR 2 GETGLOBVAR
MYADDR MYADDR
ROT ROT
56 CALLDICT 57 CALLDICT
}> CALLREF }> CALLREF
12 2 BLKDROP2 12 2 BLKDROP2
<{ <{
@ -3094,7 +3302,7 @@ SETCP0
2 GETGLOBVAR 2 GETGLOBVAR
MYADDR MYADDR
ROT ROT
56 CALLDICT 57 CALLDICT
}> CALLREF }> CALLREF
<{ <{
0 PUSHINT 0 PUSHINT
@ -3484,7 +3692,7 @@ SETCP0
2 GETGLOBVAR 2 GETGLOBVAR
MYADDR MYADDR
ROT ROT
56 CALLDICT 57 CALLDICT
}> CALLREF }> CALLREF
2DUP 2DUP
<{ <{
@ -3531,7 +3739,7 @@ SETCP0
s9 s-1 PUXC s9 s-1 PUXC
s17 PUSH s17 PUSH
s0 s1 XCHG s0 s1 XCHG
58 CALLDICT 59 CALLDICT
2DUP 2DUP
<{ <{
0 PUSHINT 0 PUSHINT
@ -4958,7 +5166,7 @@ SETCP0
IFELSE IFELSE
130 THROW 130 THROW
55: 56:
0 PUSHINT 0 PUSHINT
PUSHNULL PUSHNULL
PUSHNULL PUSHNULL
@ -5014,7 +5222,7 @@ SETCP0
STREF STREF
ENDC ENDC
56: 57:
s0 s2 XCHG s0 s2 XCHG
CTOS CTOS
LDDICT LDDICT
@ -5037,9 +5245,9 @@ SETCP0
STDICT STDICT
ENDC ENDC
s0 s0 s3 XCHG3 s0 s0 s3 XCHG3
55 CALLDICT 56 CALLDICT
57: 58:
PUSHNULL PUSHNULL
s0 s4 XCHG s0 s4 XCHG
NEWC NEWC
@ -5071,7 +5279,7 @@ SETCP0
STREF STREF
ENDC ENDC
58: 59:
s0 s3 XCHG s0 s3 XCHG
CTOS CTOS
LDDICT LDDICT
@ -5095,7 +5303,7 @@ SETCP0
ENDC ENDC
3 1 BLKSWAP 3 1 BLKSWAP
s0 s4 XCHG s0 s4 XCHG
57 CALLDICT 58 CALLDICT
owner: owner:
c4 PUSH c4 PUSH
@ -5276,7 +5484,7 @@ SETCP0
2 GETGLOBVAR 2 GETGLOBVAR
MYADDR MYADDR
ROT ROT
56 CALLDICT 57 CALLDICT
}> CALLREF }> CALLREF
12 2 BLKDROP2 12 2 BLKDROP2
<{ <{
@ -5402,7 +5610,7 @@ SETCP0
2 GETGLOBVAR 2 GETGLOBVAR
MYADDR MYADDR
ROT ROT
56 CALLDICT 57 CALLDICT
}> CALLREF }> CALLREF
8 2 BLKDROP2 8 2 BLKDROP2
s0 POP s0 POP

22
sources/output/jetton_TONB.md

@ -1,9 +1,9 @@
# TACT Compilation Report # TACT Compilation Report
Contract: TONB Contract: TONB
BOC Size: 4090 bytes BOC Size: 4276 bytes
# Types # Types
Total Types: 33 Total Types: 36
## StateInit ## StateInit
TLB: `_ code:^cell data:^cell = StateInit` TLB: `_ code:^cell data:^cell = StateInit`
@ -85,9 +85,9 @@ Signature: `InitiateLiquidationVote{adminIndex:int257,quorum_percent:int257,vote
TLB: `finish_vote#2a574443 voteId:int257 = FinishVote` TLB: `finish_vote#2a574443 voteId:int257 = FinishVote`
Signature: `FinishVote{voteId:int257}` Signature: `FinishVote{voteId:int257}`
## Vote ## VoteMsg
TLB: `vote#b670f4ce voteId:int257 adminIndex:int257 vote:int257 = Vote` TLB: `vote_msg#58fde8ab voteId:int257 adminIndex:int257 vote:int257 = VoteMsg`
Signature: `Vote{voteId:int257,adminIndex:int257,vote:int257}` Signature: `VoteMsg{voteId:int257,adminIndex:int257,vote:int257}`
## AddressList ## AddressList
TLB: `_ addresses:dict<int, address> length:int257 = AddressList` TLB: `_ addresses:dict<int, address> length:int257 = AddressList`
@ -121,10 +121,22 @@ Signature: `RequestUnstake{founderIndex:int257}`
TLB: `collect_profit#51912735 adminIndex:int257 = CollectProfit` TLB: `collect_profit#51912735 adminIndex:int257 = CollectProfit`
Signature: `CollectProfit{adminIndex:int257}` Signature: `CollectProfit{adminIndex:int257}`
## SetOwner
TLB: `set_owner#b71c6df6 owner:address = SetOwner`
Signature: `SetOwner{owner:address}`
## WithdrawalRequests ## WithdrawalRequests
TLB: `_ addresses:dict<int, address> amounts:dict<int, int> n_requests:int257 = WithdrawalRequests` TLB: `_ addresses:dict<int, address> amounts:dict<int, int> n_requests:int257 = WithdrawalRequests`
Signature: `WithdrawalRequests{addresses:dict<int, address>,amounts:dict<int, int>,n_requests:int257}` Signature: `WithdrawalRequests{addresses:dict<int, address>,amounts:dict<int, int>,n_requests:int257}`
## Proposal
TLB: `_ type:int257 blacklistAddress:Maybe address distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>} = Proposal`
Signature: `Proposal{type:int257,blacklistAddress:Maybe address,distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>}}`
## Vote
TLB: `_ id:int257 votes:dict<int, int> vote_end:int257 proposal:Proposal{type:int257,blacklistAddress:Maybe address,distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>}} quorum_percent:int257 ended:bool result:Maybe bool = Vote`
Signature: `Vote{id:int257,votes:dict<int, int>,vote_end:int257,proposal:Proposal{type:int257,blacklistAddress:Maybe address,distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>}},quorum_percent:int257,ended:bool,result:Maybe bool}`
## ChangeOwner ## ChangeOwner
TLB: `change_owner#0f474d03 newOwner:address = ChangeOwner` TLB: `change_owner#0f474d03 newOwner:address = ChangeOwner`
Signature: `ChangeOwner{newOwner:address}` Signature: `ChangeOwner{newOwner:address}`

2
sources/output/jetton_TONB.pkg

File diff suppressed because one or more lines are too long

220
sources/output/jetton_TONB.ts

File diff suppressed because one or more lines are too long

2
sources/output/jetton_TONBWallet.abi

File diff suppressed because one or more lines are too long

2
sources/output/jetton_TONBWallet.code.fc

@ -514,5 +514,5 @@ _ supported_interfaces() method_id {
} }
_ get_abi_ipfs() { _ get_abi_ipfs() {
return "ipfs://QmZ8U23MsSzC5NvLwmc6Wh8LzCefCn61CpNQ81T9a6A8dZ"; return "ipfs://QmWUsMjXBDmUpAiZnwRzPM5E4Q81yVQkRc88XnAJYWif2a";
} }

2
sources/output/jetton_TONBWallet.code.fif

@ -1008,6 +1008,6 @@ PROGRAM{
209778528950190195973528115415557644819 PUSHINT 209778528950190195973528115415557644819 PUSHINT
}> }>
get_abi_ipfs PROC:<{ get_abi_ipfs PROC:<{
x{697066733a2f2f516d5a385532334d73537a43354e764c776d63365768384c7a436566436e363143704e513831543961364138645a} PUSHSLICE x{697066733a2f2f516d5755734d6a5842446d557041695a6e77527a504d3545345138317956516b52633838586e414a595769663261} PUSHSLICE
}> }>
}END>c }END>c

20
sources/output/jetton_TONBWallet.md

@ -3,7 +3,7 @@ Contract: TONBWallet
BOC Size: 2111 bytes BOC Size: 2111 bytes
# Types # Types
Total Types: 33 Total Types: 36
## StateInit ## StateInit
TLB: `_ code:^cell data:^cell = StateInit` TLB: `_ code:^cell data:^cell = StateInit`
@ -85,9 +85,9 @@ Signature: `InitiateLiquidationVote{adminIndex:int257,quorum_percent:int257,vote
TLB: `finish_vote#2a574443 voteId:int257 = FinishVote` TLB: `finish_vote#2a574443 voteId:int257 = FinishVote`
Signature: `FinishVote{voteId:int257}` Signature: `FinishVote{voteId:int257}`
## Vote ## VoteMsg
TLB: `vote#b670f4ce voteId:int257 adminIndex:int257 vote:int257 = Vote` TLB: `vote_msg#58fde8ab voteId:int257 adminIndex:int257 vote:int257 = VoteMsg`
Signature: `Vote{voteId:int257,adminIndex:int257,vote:int257}` Signature: `VoteMsg{voteId:int257,adminIndex:int257,vote:int257}`
## AddressList ## AddressList
TLB: `_ addresses:dict<int, address> length:int257 = AddressList` TLB: `_ addresses:dict<int, address> length:int257 = AddressList`
@ -121,10 +121,22 @@ Signature: `RequestUnstake{founderIndex:int257}`
TLB: `collect_profit#51912735 adminIndex:int257 = CollectProfit` TLB: `collect_profit#51912735 adminIndex:int257 = CollectProfit`
Signature: `CollectProfit{adminIndex:int257}` Signature: `CollectProfit{adminIndex:int257}`
## SetOwner
TLB: `set_owner#b71c6df6 owner:address = SetOwner`
Signature: `SetOwner{owner:address}`
## WithdrawalRequests ## WithdrawalRequests
TLB: `_ addresses:dict<int, address> amounts:dict<int, int> n_requests:int257 = WithdrawalRequests` TLB: `_ addresses:dict<int, address> amounts:dict<int, int> n_requests:int257 = WithdrawalRequests`
Signature: `WithdrawalRequests{addresses:dict<int, address>,amounts:dict<int, int>,n_requests:int257}` Signature: `WithdrawalRequests{addresses:dict<int, address>,amounts:dict<int, int>,n_requests:int257}`
## Proposal
TLB: `_ type:int257 blacklistAddress:Maybe address distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>} = Proposal`
Signature: `Proposal{type:int257,blacklistAddress:Maybe address,distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>}}`
## Vote
TLB: `_ id:int257 votes:dict<int, int> vote_end:int257 proposal:Proposal{type:int257,blacklistAddress:Maybe address,distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>}} quorum_percent:int257 ended:bool result:Maybe bool = Vote`
Signature: `Vote{id:int257,votes:dict<int, int>,vote_end:int257,proposal:Proposal{type:int257,blacklistAddress:Maybe address,distribution:Maybe Distribution{addresses:AddressList{addresses:dict<int, address>,length:int257},percents:dict<address, int>}},quorum_percent:int257,ended:bool,result:Maybe bool}`
## ChangeOwner ## ChangeOwner
TLB: `change_owner#0f474d03 newOwner:address = ChangeOwner` TLB: `change_owner#0f474d03 newOwner:address = ChangeOwner`
Signature: `ChangeOwner{newOwner:address}` Signature: `ChangeOwner{newOwner:address}`

2
sources/output/jetton_TONBWallet.pkg

File diff suppressed because one or more lines are too long

211
sources/output/jetton_TONBWallet.ts

@ -1065,40 +1065,40 @@ function dictValueParserFinishVote(): DictionaryValue<FinishVote> {
} }
} }
} }
export type Vote = { export type VoteMsg = {
$$type: 'Vote'; $$type: 'VoteMsg';
voteId: bigint; voteId: bigint;
adminIndex: bigint; adminIndex: bigint;
vote: bigint; vote: bigint;
} }
export function storeVote(src: Vote) { export function storeVoteMsg(src: VoteMsg) {
return (builder: Builder) => { return (builder: Builder) => {
let b_0 = builder; let b_0 = builder;
b_0.storeUint(3060856014, 32); b_0.storeUint(1493035179, 32);
b_0.storeInt(src.voteId, 257); b_0.storeInt(src.voteId, 257);
b_0.storeInt(src.adminIndex, 257); b_0.storeInt(src.adminIndex, 257);
b_0.storeInt(src.vote, 257); b_0.storeInt(src.vote, 257);
}; };
} }
export function loadVote(slice: Slice) { export function loadVoteMsg(slice: Slice) {
let sc_0 = slice; let sc_0 = slice;
if (sc_0.loadUint(32) !== 3060856014) { throw Error('Invalid prefix'); } if (sc_0.loadUint(32) !== 1493035179) { throw Error('Invalid prefix'); }
let _voteId = sc_0.loadIntBig(257); let _voteId = sc_0.loadIntBig(257);
let _adminIndex = sc_0.loadIntBig(257); let _adminIndex = sc_0.loadIntBig(257);
let _vote = sc_0.loadIntBig(257); let _vote = sc_0.loadIntBig(257);
return { $$type: 'Vote' as const, voteId: _voteId, adminIndex: _adminIndex, vote: _vote }; return { $$type: 'VoteMsg' as const, voteId: _voteId, adminIndex: _adminIndex, vote: _vote };
} }
function loadTupleVote(source: TupleReader) { function loadTupleVoteMsg(source: TupleReader) {
let _voteId = source.readBigNumber(); let _voteId = source.readBigNumber();
let _adminIndex = source.readBigNumber(); let _adminIndex = source.readBigNumber();
let _vote = source.readBigNumber(); let _vote = source.readBigNumber();
return { $$type: 'Vote' as const, voteId: _voteId, adminIndex: _adminIndex, vote: _vote }; return { $$type: 'VoteMsg' as const, voteId: _voteId, adminIndex: _adminIndex, vote: _vote };
} }
function storeTupleVote(source: Vote) { function storeTupleVoteMsg(source: VoteMsg) {
let builder = new TupleBuilder(); let builder = new TupleBuilder();
builder.writeNumber(source.voteId); builder.writeNumber(source.voteId);
builder.writeNumber(source.adminIndex); builder.writeNumber(source.adminIndex);
@ -1106,13 +1106,13 @@ function storeTupleVote(source: Vote) {
return builder.build(); return builder.build();
} }
function dictValueParserVote(): DictionaryValue<Vote> { function dictValueParserVoteMsg(): DictionaryValue<VoteMsg> {
return { return {
serialize: (src, buidler) => { serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeVote(src)).endCell()); buidler.storeRef(beginCell().store(storeVoteMsg(src)).endCell());
}, },
parse: (src) => { parse: (src) => {
return loadVote(src.loadRef().beginParse()); return loadVoteMsg(src.loadRef().beginParse());
} }
} }
} }
@ -1468,6 +1468,47 @@ function dictValueParserCollectProfit(): DictionaryValue<CollectProfit> {
} }
} }
} }
export type SetOwner = {
$$type: 'SetOwner';
owner: Address;
}
export function storeSetOwner(src: SetOwner) {
return (builder: Builder) => {
let b_0 = builder;
b_0.storeUint(3072093686, 32);
b_0.storeAddress(src.owner);
};
}
export function loadSetOwner(slice: Slice) {
let sc_0 = slice;
if (sc_0.loadUint(32) !== 3072093686) { throw Error('Invalid prefix'); }
let _owner = sc_0.loadAddress();
return { $$type: 'SetOwner' as const, owner: _owner };
}
function loadTupleSetOwner(source: TupleReader) {
let _owner = source.readAddress();
return { $$type: 'SetOwner' as const, owner: _owner };
}
function storeTupleSetOwner(source: SetOwner) {
let builder = new TupleBuilder();
builder.writeAddress(source.owner);
return builder.build();
}
function dictValueParserSetOwner(): DictionaryValue<SetOwner> {
return {
serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeSetOwner(src)).endCell());
},
parse: (src) => {
return loadSetOwner(src.loadRef().beginParse());
}
}
}
export type WithdrawalRequests = { export type WithdrawalRequests = {
$$type: 'WithdrawalRequests'; $$type: 'WithdrawalRequests';
addresses: Dictionary<bigint, Address>; addresses: Dictionary<bigint, Address>;
@ -1517,6 +1558,135 @@ function dictValueParserWithdrawalRequests(): DictionaryValue<WithdrawalRequests
} }
} }
} }
export type Proposal = {
$$type: 'Proposal';
type: bigint;
blacklistAddress: Address | null;
distribution: Distribution | null;
}
export function storeProposal(src: Proposal) {
return (builder: Builder) => {
let b_0 = builder;
b_0.storeInt(src.type, 257);
b_0.storeAddress(src.blacklistAddress);
if (src.distribution !== null && src.distribution !== undefined) { b_0.storeBit(true); b_0.store(storeDistribution(src.distribution)); } else { b_0.storeBit(false); }
};
}
export function loadProposal(slice: Slice) {
let sc_0 = slice;
let _type = sc_0.loadIntBig(257);
let _blacklistAddress = sc_0.loadMaybeAddress();
let _distribution = sc_0.loadBit() ? loadDistribution(sc_0) : null;
return { $$type: 'Proposal' as const, type: _type, blacklistAddress: _blacklistAddress, distribution: _distribution };
}
function loadTupleProposal(source: TupleReader) {
let _type = source.readBigNumber();
let _blacklistAddress = source.readAddressOpt();
const _distribution_p = source.readTupleOpt();
const _distribution = _distribution_p ? loadTupleDistribution(_distribution_p) : null;
return { $$type: 'Proposal' as const, type: _type, blacklistAddress: _blacklistAddress, distribution: _distribution };
}
function storeTupleProposal(source: Proposal) {
let builder = new TupleBuilder();
builder.writeNumber(source.type);
builder.writeAddress(source.blacklistAddress);
if (source.distribution !== null && source.distribution !== undefined) {
builder.writeTuple(storeTupleDistribution(source.distribution));
} else {
builder.writeTuple(null);
}
return builder.build();
}
function dictValueParserProposal(): DictionaryValue<Proposal> {
return {
serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeProposal(src)).endCell());
},
parse: (src) => {
return loadProposal(src.loadRef().beginParse());
}
}
}
export type Vote = {
$$type: 'Vote';
id: bigint;
votes: Dictionary<bigint, bigint>;
vote_end: bigint;
proposal: Proposal;
quorum_percent: bigint;
ended: boolean;
result: boolean | null;
}
export function storeVote(src: Vote) {
return (builder: Builder) => {
let b_0 = builder;
b_0.storeInt(src.id, 257);
b_0.storeDict(src.votes, Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257));
b_0.storeInt(src.vote_end, 257);
let b_1 = new Builder();
b_1.store(storeProposal(src.proposal));
let b_2 = new Builder();
b_2.storeInt(src.quorum_percent, 257);
b_2.storeBit(src.ended);
if (src.result !== null && src.result !== undefined) { b_2.storeBit(true).storeBit(src.result); } else { b_2.storeBit(false); }
b_1.storeRef(b_2.endCell());
b_0.storeRef(b_1.endCell());
};
}
export function loadVote(slice: Slice) {
let sc_0 = slice;
let _id = sc_0.loadIntBig(257);
let _votes = Dictionary.load(Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257), sc_0);
let _vote_end = sc_0.loadIntBig(257);
let sc_1 = sc_0.loadRef().beginParse();
let _proposal = loadProposal(sc_1);
let sc_2 = sc_1.loadRef().beginParse();
let _quorum_percent = sc_2.loadIntBig(257);
let _ended = sc_2.loadBit();
let _result = sc_2.loadBit() ? sc_2.loadBit() : null;
return { $$type: 'Vote' as const, id: _id, votes: _votes, vote_end: _vote_end, proposal: _proposal, quorum_percent: _quorum_percent, ended: _ended, result: _result };
}
function loadTupleVote(source: TupleReader) {
let _id = source.readBigNumber();
let _votes = Dictionary.loadDirect(Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257), source.readCellOpt());
let _vote_end = source.readBigNumber();
const _proposal = loadTupleProposal(source.readTuple());
let _quorum_percent = source.readBigNumber();
let _ended = source.readBoolean();
let _result = source.readBooleanOpt();
return { $$type: 'Vote' as const, id: _id, votes: _votes, vote_end: _vote_end, proposal: _proposal, quorum_percent: _quorum_percent, ended: _ended, result: _result };
}
function storeTupleVote(source: Vote) {
let builder = new TupleBuilder();
builder.writeNumber(source.id);
builder.writeCell(source.votes.size > 0 ? beginCell().storeDictDirect(source.votes, Dictionary.Keys.BigInt(257), Dictionary.Values.BigInt(257)).endCell() : null);
builder.writeNumber(source.vote_end);
builder.writeTuple(storeTupleProposal(source.proposal));
builder.writeNumber(source.quorum_percent);
builder.writeBoolean(source.ended);
builder.writeBoolean(source.result);
return builder.build();
}
function dictValueParserVote(): DictionaryValue<Vote> {
return {
serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeVote(src)).endCell());
},
parse: (src) => {
return loadVote(src.loadRef().beginParse());
}
}
}
export type ChangeOwner = { export type ChangeOwner = {
$$type: 'ChangeOwner'; $$type: 'ChangeOwner';
newOwner: Address; newOwner: Address;
@ -1694,11 +1864,26 @@ const TONBWallet_errors: { [key: number]: { message: string } } = {
136: { message: `Invalid address` }, 136: { message: `Invalid address` },
4429: { message: `Invalid sender` }, 4429: { message: `Invalid sender` },
6384: { message: `not enough money for withdraw` }, 6384: { message: `not enough money for withdraw` },
6873: { message: `Only an admin can initiate a vote` },
13650: { message: `Invalid bounced message` }, 13650: { message: `Invalid bounced message` },
16059: { message: `Invalid value` }, 16059: { message: `Invalid value` },
16994: { message: `Vote is finished` },
18474: { message: `only the owner can set a new owner` },
19362: { message: `Invalid quorum percent` },
29720: { message: `Invalid vote` },
29821: { message: `Voting requires at least 1 ton for the fees` },
30386: { message: `Vote already ended` },
32366: { message: `not enough money for deposit` }, 32366: { message: `not enough money for deposit` },
34326: { message: `Vote is not finished yet` },
37444: { message: `Only a founder can request unstake` },
41207: { message: `invalid sender` }, 41207: { message: `invalid sender` },
42983: { message: `No profit to collect` },
44816: { message: `Wallet is blacklisted` }, 44816: { message: `Wallet is blacklisted` },
46931: { message: `Invalid vote id` },
49606: { message: `Invalid admin index` },
53981: { message: `Only an admin can collect profit` },
56549: { message: `Only an admin can vote` },
61070: { message: `Invalid vote time` },
61265: { message: `Only the owner can trigger un-staking` }, 61265: { message: `Only the owner can trigger un-staking` },
62972: { message: `Invalid balance` }, 62972: { message: `Invalid balance` },
} }

34
sources/tests/__snapshots__/jetton.spec.ts.snap

@ -13,14 +13,14 @@ exports[`jetton should deploy and deposit the wallet with the correct sum of mon
}, },
"bounce": true, "bounce": true,
"from": "kQAI-3FJVc_ywSuY4vq0bYrzR7S4Och4y7bTU_i5yLOB3A6P", "from": "kQAI-3FJVc_ywSuY4vq0bYrzR7S4Och4y7bTU_i5yLOB3A6P",
"to": "kQABEUn8yLZqJKZAi4TZjnxqafjqNKCwpuE_-kOXim3gA5il", "to": "kQAHUsQxZnU4LMhYKHdaISP9rf-1OcdDAPFWD-bZapIcRtpr",
"type": "internal", "type": "internal",
"value": 100200000000n, "value": 100200000000n,
}, },
"type": "received", "type": "received",
}, },
{ {
"gasUsed": 32815n, "gasUsed": 32790n,
"type": "processed", "type": "processed",
}, },
{ {
@ -31,8 +31,8 @@ exports[`jetton should deploy and deposit the wallet with the correct sum of mon
"type": "cell", "type": "cell",
}, },
"bounce": false, "bounce": false,
"from": "kQABEUn8yLZqJKZAi4TZjnxqafjqNKCwpuE_-kOXim3gA5il", "from": "kQAHUsQxZnU4LMhYKHdaISP9rf-1OcdDAPFWD-bZapIcRtpr",
"to": "kQCMEn5NnRirD8pMXczMDKEXDjBM8tPVXYdj6X3b9ySJdCgP", "to": "kQCFVoQORdkDXw6i10RJiDkJAzm-Kj0oq_ldL66vZpovRblF",
"type": "internal", "type": "internal",
"value": 11365000n, "value": 11365000n,
}, },
@ -43,13 +43,13 @@ exports[`jetton should deploy and deposit the wallet with the correct sum of mon
"messages": [ "messages": [
{ {
"body": { "body": {
"cell": "x{178D451900000000000000005174876E800800022293F9916CD4494C811709B31CF8D4D3F1D46941614DC27FF4872F14DBC00700023EDC525573FCB04AE638BEAD1B62BCD1ED2E0E721E32EDB4D4FE2E722CE07702_} "cell": "x{178D451900000000000000005174876E8008000EA58862CCEA705990B050EEB44247FB5BFF6A738E8601E2AC1FCDB2D524388D00023EDC525573FCB04AE638BEAD1B62BCD1ED2E0E721E32EDB4D4FE2E722CE07702_}
x{800000000000000000000000000000000000000000000000000000000000000020046093F26CE8C5587E5262EE66606508B8718267969EAAEC3B1F4BEEDFB9244BA4_}", x{800000000000000000000000000000000000000000000000000000000000000020042AB420722EC81AF87516BA224C41C84819CDF151E9455FCAE97D757B34D17A2C_}",
"type": "cell", "type": "cell",
}, },
"bounce": false, "bounce": false,
"from": "kQABEUn8yLZqJKZAi4TZjnxqafjqNKCwpuE_-kOXim3gA5il", "from": "kQAHUsQxZnU4LMhYKHdaISP9rf-1OcdDAPFWD-bZapIcRtpr",
"to": "kQBPWbXsnNaT4jX5J-TIyCfqT9ieWU1c-OxPUejeUisQd5cf", "to": "kQDyCsUcb80ZqWzhdTc0Qm-DMCQMp9QyFHBtH0Y2RlTXVSu1",
"type": "internal", "type": "internal",
"value": 41715000n, "value": 41715000n,
}, },
@ -69,14 +69,14 @@ exports[`jetton should work correctly with the staking 1`] = `
}, },
"bounce": true, "bounce": true,
"from": "kQAI-3FJVc_ywSuY4vq0bYrzR7S4Och4y7bTU_i5yLOB3A6P", "from": "kQAI-3FJVc_ywSuY4vq0bYrzR7S4Och4y7bTU_i5yLOB3A6P",
"to": "kQCWdkwB2iVEz4eqkgyEp_trwnITQd4LiGEcLGENymBCqgFX", "to": "kQDwhC8P_RtjQLYFddZ6FFl3wC95KNUcG6s-f7bIe4s6amT_",
"type": "internal", "type": "internal",
"value": 100200000000n, "value": 100200000000n,
}, },
"type": "received", "type": "received",
}, },
{ {
"gasUsed": 36098n, "gasUsed": 36073n,
"type": "processed", "type": "processed",
}, },
{ {
@ -87,8 +87,8 @@ exports[`jetton should work correctly with the staking 1`] = `
"type": "cell", "type": "cell",
}, },
"bounce": false, "bounce": false,
"from": "kQCWdkwB2iVEz4eqkgyEp_trwnITQd4LiGEcLGENymBCqgFX", "from": "kQDwhC8P_RtjQLYFddZ6FFl3wC95KNUcG6s-f7bIe4s6amT_",
"to": "kQACkI90BJ8sTu1IlFoOtzChElnpXsotC8lrmFMGJknQ_Flx", "to": "kQDg1oqtEuoPiStRfbdmM9Bifn4MUekCMD6ufYHXOsuoAizf",
"type": "internal", "type": "internal",
"value": 11365000n, "value": 11365000n,
}, },
@ -99,13 +99,13 @@ exports[`jetton should work correctly with the staking 1`] = `
"messages": [ "messages": [
{ {
"body": { "body": {
"cell": "x{178D451900000000000000005174876E8008012CEC9803B44A899F0F552419094FF6D784E42683BC1710C23858C21B94C0855500023EDC525573FCB04AE638BEAD1B62BCD1ED2E0E721E32EDB4D4FE2E722CE07702_} "cell": "x{178D451900000000000000005174876E800801E1085E1FFA36C6816C0AEBACF428B2EF805EF251AA3837567CFF6D90F71674D500023EDC525573FCB04AE638BEAD1B62BCD1ED2E0E721E32EDB4D4FE2E722CE07702_}
x{8000000000000000000000000000000000000000000000000000000000000000200014847BA024F962776A44A2D075B9850892CF4AF651685E4B5CC29831324E87E4_}", x{8000000000000000000000000000000000000000000000000000000000000000200706B4556897507C495A8BEDBB319E8313F3F0628F481181F573EC0EB9D65D4014_}",
"type": "cell", "type": "cell",
}, },
"bounce": false, "bounce": false,
"from": "kQCWdkwB2iVEz4eqkgyEp_trwnITQd4LiGEcLGENymBCqgFX", "from": "kQDwhC8P_RtjQLYFddZ6FFl3wC95KNUcG6s-f7bIe4s6amT_",
"to": "kQCO4TveQnMW97esrpa9c9juf5h1ry8gHsxGmUzPjVmBd9Sf", "to": "kQBVdGf16yM9JOGzv062bUvEyZGz2yjeJqOnGU_HMPxJxu2S",
"type": "internal", "type": "internal",
"value": 41715000n, "value": 41715000n,
}, },
@ -120,7 +120,7 @@ exports[`jetton should work correctly with the staking 1`] = `
"type": "cell", "type": "cell",
}, },
"bounce": true, "bounce": true,
"from": "kQCWdkwB2iVEz4eqkgyEp_trwnITQd4LiGEcLGENymBCqgFX", "from": "kQDwhC8P_RtjQLYFddZ6FFl3wC95KNUcG6s-f7bIe4s6amT_",
"to": "kQC5Y865mUcSTsSpJYbli0KmSiriJUBFHlKmvNqkS7T5VyUx", "to": "kQC5Y865mUcSTsSpJYbli0KmSiriJUBFHlKmvNqkS7T5VyUx",
"type": "internal", "type": "internal",
"value": 99491421000n, "value": 99491421000n,

23
sources/tests/foundation.spec.ts

@ -0,0 +1,23 @@
import { toNano } from "ton";
import { ContractSystem } from "ton-emulator";
import {TONB} from '../output/jetton_TONB';
import {Foundation} from '../output/jetton_Foundation';
import { default_content } from '../utils/config';
import { TONBWallet } from '../output/jetton_TONBWallet';
import { beginCell } from 'ton-core';
import { PseudoStaking } from '../output/jetton_PseudoStaking';
import { createDistribution, createAddressList } from "../utils/interactions";
describe('jetton', () => {
it('should be able to create a vote', async () => {
// Create jetton
let system = await ContractSystem.create();
let owner = system.treasure('owner');
let tonb = system.open(await TONB.fromInit(owner.address, default_content, null));
let foundation = system.open(await Foundation.fromInit(
createDistribution([owner.address], [100n]),
createAddressList([]), tonb.address));
tonb.send(owner, { value: toNano('1') }, { $$type: 'SetOwner', owner: foundation.address });
let tracker = system.track(foundation.address);
});
});

19
sources/tests/voting.spec.ts

@ -1,19 +0,0 @@
import { toNano, Address } from "ton";
import { ContractSystem } from "ton-emulator";
import {TONB} from '../output/jetton_TONB';
import { default_content } from '../utils/config';
import { TONBWallet } from '../output/jetton_TONBWallet';
import { beginCell } from 'ton-core';
import { PseudoStaking } from '../output/jetton_PseudoStaking';
describe('jetton', () => {
it('should be able to create a vote', async () => {
// Create jetton
let system = await ContractSystem.create();
let owner = system.treasure('owner');
let contract = system.open(await TONB.fromInit(owner.address, default_content, null));
let tracker = system.track(contract.address);
});
});

28
sources/utils/interactions.ts

@ -4,6 +4,8 @@ import { TON } from "./helpers";
import { wallet_data, owner, default_content, workchain } from './config'; import { wallet_data, owner, default_content, workchain } from './config';
import { TONB } from "../output/jetton_TONB"; import { TONB } from "../output/jetton_TONB";
import { TONBWallet } from '../output/jetton_TONBWallet'; import { TONBWallet } from '../output/jetton_TONBWallet';
import { Distribution, AddressList } from '../output/jetton_TONBWallet';
import { Dictionary } from 'ton-core';
export async function sendMessage(wallet: any, secretKey: Buffer, msg: { value: string | bigint, to: Address, bounce?: boolean, init?: { code?: Cell, data?: Cell }, body?: any }) { export async function sendMessage(wallet: any, secretKey: Buffer, msg: { value: string | bigint, to: Address, bounce?: boolean, init?: { code?: Cell, data?: Cell }, body?: any }) {
let seqno: number = await wallet.getSeqno(); let seqno: number = await wallet.getSeqno();
@ -74,7 +76,31 @@ export async function getTONB(tonb_content?: any) {
if (!tonb_content) { if (!tonb_content) {
tonb_content = default_content; tonb_content = default_content;
} }
return await TONB.fromInit(owner, tonb_content); return await TONB.fromInit(owner, tonb_content, null);
}
export function createAddressList(addresses: Address[]): AddressList {
let dict: Dictionary<bigint, Address> = Dictionary.empty();
for (let i = 0; i < addresses.length; i++) {
dict.set(BigInt(i), addresses[i]);
}
return {
$$type: 'AddressList',
addresses: dict,
length: BigInt(addresses.length)
};
}
export function createDistribution(addresses: Address[], percents: bigint[]): Distribution {
let dict: Dictionary<Address, bigint> = Dictionary.empty();
for (let i = 0; i < addresses.length; i++) {
dict.set(addresses[i], percents[i]);
}
return {
$$type: 'Distribution',
addresses: createAddressList(addresses),
percents: dict
};
} }
export async function deployTONB(tonb_content?: any, cancel: boolean = false) { export async function deployTONB(tonb_content?: any, cancel: boolean = false) {

Loading…
Cancel
Save