Browse Source

Foundation, tests

master
Lev 2 years ago
parent
commit
e7c3861dab
  1. 137
      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

137
sources/foundation.tact

@ -4,7 +4,8 @@ import "./messages";
struct Proposal {
type: Int; // 0 - Blacklist, 1 - Full liquidation, 2 - Change percents
data: Cell; // Address for blacklist, Distribution for percents
blacklistAddress: Address?;
distribution: Distribution?;
}
struct Vote {
@ -17,16 +18,6 @@ struct Vote {
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 {
founders: AddressList; // aka superadmins
@ -34,7 +25,7 @@ contract Foundation {
tonb: Address;
votes: map[Int]Vote;
profits: map[Address]Int;
n_votes: Int;
n_votes: Int = 0;
init(admins: Distribution, founders: AddressList, tonb: Address) {
self.admins = admins;
@ -43,8 +34,8 @@ contract Foundation {
}
receive(msg: FinishVote) {
require(msg.vote_id < self.n_votes, "Invalid vote id");
let vote: Vote = self.votes.get(msg.vote_id)!!;
require(msg.voteId < self.n_votes, "Invalid vote id");
let vote: Vote = self.votes.get(msg.voteId)!!;
require(vote.ended == false, "Vote already ended");
require(vote.vote_end < now(), "Vote is not finished yet");
let n_yes: Int = 0;
@ -52,7 +43,7 @@ contract Foundation {
let n_abstain: Int = 0;
let i: Int = 0;
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) {
n_yes = n_yes + 1;
} else if (vote_i == 2) {
@ -72,79 +63,61 @@ contract Foundation {
vote.result = false;
}
vote.ended = true;
self.votes.set(msg.vote_id, vote);
self.votes.set(msg.voteId, vote);
if (vote.result == true) {
let vres: Cell? = vote_res(vote.proposal);
if (vres != null) {
let prop: Proposal = vote.proposal;
if (prop.type == 0) {
send(SendParameters{
to: self.tonb,
value: 0,
mode: SendRemainingValue,
body: vres!!
body: BlacklistWallet {
wallet: prop.blacklistAddress!!
}.toCell()
});
}
if(vote.proposal.type == 2) {
// self.admins = Distribution {
// addresses: vote.proposal.data.readAddressList(),
// percents: vote.proposal.data.readPercents()
// };
if (prop.type == 1) {
// todo
}
if (prop.type == 2) {
self.admins = prop.distribution!!;
}
}
}
receive(msg: Vote) {
require(msg.adminIndex < self.admins.addresses.length, "Invalid admin index")
receive(msg: VoteMsg) {
require(msg.adminIndex < self.admins.addresses.length, "Invalid admin index");
let ctx: Context = context();
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");
let vote: Vote = self.votes.get(msg.vote_id)!!;
require(msg.voteId < self.n_votes, "Invalid vote id");
let vote: Vote = self.votes.get(msg.voteId)!!;
require(vote.ended == false, "Vote already ended");
require(vote.vote_end > now(), "Vote is finished");
require(msg.vote >= 0 && msg.vote <= 2, "Invalid vote");
vote.votes.set(msg.adminIndex, msg.vote);
self.votes.set(msg.vote_id, vote);
self.votes.set(msg.voteId, vote);
}
receive(msg: InitiateBlacklistVote) {
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(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,
vote_end: now() + msg.vote_time,
proposal: Proposal {
let proposal: Proposal = Proposal {
type: 0,
data: msg.address
},
quorum_percent: msg.quorum_percent
blacklistAddress: msg.wallet,
distribution: 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: 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 {
let vote: Vote = Vote {
id: self.n_votes,
vote_end: now() + msg.vote_time,
proposal: Proposal {
type: 2,
data: msg.distribution
},
quorum_percent: msg.quorum_percent
proposal: proposal,
quorum_percent: msg.quorum_percent,
votes: emptyMap(),
result: null
};
let i: Int = 0;
while (i < self.admins.addresses.length) {
@ -155,20 +128,52 @@ contract Foundation {
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();
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.vote_time > 0 && msg.vote_time < 3 * 24 * 3600, "Invalid vote time");
let vote = Vote {
let vote: Vote = Vote {
id: self.n_votes,
vote_end: now() + msg.vote_time,
proposal: Proposal {
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;
while (i < self.admins.addresses.length) {
@ -187,7 +192,7 @@ contract Foundation {
let i: Int = 0;
while (i < self.admins.addresses.length) {
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;
// todo: record the profit
let current_profit: Int = 0;
@ -204,10 +209,10 @@ contract Foundation {
receive(msg: RequestUnstake) {
// If this is sent by one of the founders, it means that the user wants to unstake
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{
to: self.tonb,
value: msg.amount,
value: 0,
mode: SendRemainingValue,
body: Unstake { amount: 0 }.toCell()
});

6
sources/jetton.tact

@ -6,6 +6,7 @@ import "./jetton_trait";
import "./staking";
import "./constants";
import "./pseudostaking";
import "./foundation";
message Deposit {
amount: Int as coins;
@ -60,4 +61,9 @@ contract TONB with TONBTrait {
receive(msg: SetStakingPool) {
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;
}
message Vote {
message VoteMsg {
voteId: Int;
adminIndex: Int;
vote: Int; // 0 - abstain, 1 - yes, 2 - no
@ -146,3 +146,7 @@ message RequestUnstake {
message CollectProfit {
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() {
return "ipfs://QmeGA7QUi3FCDzQtd9VhqDi1VpHx2sbycwoWaDsMsQNDS3";
return "ipfs://QmPdxwain9Y3xSr42K9ApJ5UsTURQZGtDmdhUSMQqrzYux";
}

2
sources/output/jetton_Linker.code.fif

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

20
sources/output/jetton_Linker.md

@ -3,7 +3,7 @@ Contract: Linker
BOC Size: 645 bytes
# Types
Total Types: 33
Total Types: 36
## 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`
Signature: `FinishVote{voteId:int257}`
## Vote
TLB: `vote#b670f4ce voteId:int257 adminIndex:int257 vote:int257 = Vote`
Signature: `Vote{voteId:int257,adminIndex:int257,vote:int257}`
## VoteMsg
TLB: `vote_msg#58fde8ab voteId:int257 adminIndex:int257 vote:int257 = VoteMsg`
Signature: `VoteMsg{voteId:int257,adminIndex:int257,vote: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`
Signature: `CollectProfit{adminIndex:int257}`
## SetOwner
TLB: `set_owner#b71c6df6 owner:address = SetOwner`
Signature: `SetOwner{owner:address}`
## 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}`
## 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
TLB: `change_owner#0f474d03 newOwner:address = ChangeOwner`
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 = {
$$type: 'Vote';
export type VoteMsg = {
$$type: 'VoteMsg';
voteId: bigint;
adminIndex: bigint;
vote: bigint;
}
export function storeVote(src: Vote) {
export function storeVoteMsg(src: VoteMsg) {
return (builder: 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.adminIndex, 257);
b_0.storeInt(src.vote, 257);
};
}
export function loadVote(slice: Slice) {
export function loadVoteMsg(slice: 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 _adminIndex = 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 _adminIndex = 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();
builder.writeNumber(source.voteId);
builder.writeNumber(source.adminIndex);
@ -1106,13 +1106,13 @@ function storeTupleVote(source: Vote) {
return builder.build();
}
function dictValueParserVote(): DictionaryValue<Vote> {
function dictValueParserVoteMsg(): DictionaryValue<VoteMsg> {
return {
serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeVote(src)).endCell());
buidler.storeRef(beginCell().store(storeVoteMsg(src)).endCell());
},
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 = {
$$type: 'WithdrawalRequests';
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 = {
$$type: 'ChangeOwner';
newOwner: Address;
@ -1695,11 +1865,26 @@ const Linker_errors: { [key: number]: { message: string } } = {
136: { message: `Invalid address` },
4429: { message: `Invalid sender` },
6384: { message: `not enough money for withdraw` },
6873: { message: `Only an admin can initiate a vote` },
13650: { message: `Invalid bounced message` },
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` },
34326: { message: `Vote is not finished yet` },
37444: { message: `Only a founder can request unstake` },
41207: { message: `invalid sender` },
42983: { message: `No profit to collect` },
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` },
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() {
return "ipfs://QmTpVYvpJy7wvLrPak1F6KJSC44yccvcdix7pmrnjZmAHa";
return "ipfs://QmauXGiekdCW4GNrULhiN8JhMuRfKgUTpLsD9DTSjKjW2f";
}

2
sources/output/jetton_PseudoStaking.code.fif

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

20
sources/output/jetton_PseudoStaking.md

@ -3,7 +3,7 @@ Contract: PseudoStaking
BOC Size: 876 bytes
# Types
Total Types: 33
Total Types: 36
## 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`
Signature: `FinishVote{voteId:int257}`
## Vote
TLB: `vote#b670f4ce voteId:int257 adminIndex:int257 vote:int257 = Vote`
Signature: `Vote{voteId:int257,adminIndex:int257,vote:int257}`
## VoteMsg
TLB: `vote_msg#58fde8ab voteId:int257 adminIndex:int257 vote:int257 = VoteMsg`
Signature: `VoteMsg{voteId:int257,adminIndex:int257,vote: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`
Signature: `CollectProfit{adminIndex:int257}`
## SetOwner
TLB: `set_owner#b71c6df6 owner:address = SetOwner`
Signature: `SetOwner{owner:address}`
## 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}`
## 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
TLB: `change_owner#0f474d03 newOwner:address = ChangeOwner`
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 = {
$$type: 'Vote';
export type VoteMsg = {
$$type: 'VoteMsg';
voteId: bigint;
adminIndex: bigint;
vote: bigint;
}
export function storeVote(src: Vote) {
export function storeVoteMsg(src: VoteMsg) {
return (builder: 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.adminIndex, 257);
b_0.storeInt(src.vote, 257);
};
}
export function loadVote(slice: Slice) {
export function loadVoteMsg(slice: 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 _adminIndex = 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 _adminIndex = 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();
builder.writeNumber(source.voteId);
builder.writeNumber(source.adminIndex);
@ -1106,13 +1106,13 @@ function storeTupleVote(source: Vote) {
return builder.build();
}
function dictValueParserVote(): DictionaryValue<Vote> {
function dictValueParserVoteMsg(): DictionaryValue<VoteMsg> {
return {
serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeVote(src)).endCell());
buidler.storeRef(beginCell().store(storeVoteMsg(src)).endCell());
},
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 = {
$$type: 'WithdrawalRequests';
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 = {
$$type: 'ChangeOwner';
newOwner: Address;
@ -1692,11 +1862,26 @@ const PseudoStaking_errors: { [key: number]: { message: string } } = {
136: { message: `Invalid address` },
4429: { message: `Invalid sender` },
6384: { message: `not enough money for withdraw` },
6873: { message: `Only an admin can initiate a vote` },
13650: { message: `Invalid bounced message` },
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` },
34326: { message: `Vote is not finished yet` },
37444: { message: `Only a founder can request unstake` },
41207: { message: `invalid sender` },
42983: { message: `No profit to collect` },
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` },
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));
}
(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 {
var (v'addresses, v'amounts, v'n_requests) = v;
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)), ());
}
(((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 {
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;
@ -731,6 +745,15 @@ _ $__gen_get_owner() method_id(83229) {
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
if (op == 201882270) {
var self = __gen_load_TONB();
@ -802,5 +825,5 @@ _ supported_interfaces() method_id {
}
_ 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_writecell_Unstake
DECLPROC __gen_read_Unstake
DECLPROC __gen_read_SetOwner
DECLPROC __gen_write_WithdrawalRequests
DECLPROC __gen_read_WithdrawalRequests
DECLPROC __gen_read_Deposit
@ -74,6 +75,7 @@ PROGRAM{
DECLPROC $__gen_TONB_receive
DECLPROC $__gen_TONB_receive_Withdraw
DECLPROC $__gen_TONB_receive_SetStakingPool
DECLPROC $__gen_TONB_receive_SetOwner
DECLPROC $__gen_TONB_receive_TokenUpdateContent
DECLPROC $__gen_TONB_receive_TokenBurnNotification
DECLPROC $__gen_TONB_receive_BlacklistWallet
@ -405,6 +407,14 @@ PROGRAM{
LDIX
SWAP
}>
__gen_read_SetOwner PROCINLINE:<{
32 LDU
SWAP
3072093686 PUSHINT
EQUAL
129 THROWIFNOT
__tact_load_address INLINECALLDICT
}>
__gen_write_WithdrawalRequests PROCINLINE:<{
s2 s3 XCHG2
STDICT
@ -1023,6 +1033,15 @@ PROGRAM{
$__gen_TONB_receive_SetStakingPool PROCINLINE:<{
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:<{
12 -ROLL
$__gen_TONB_requireOwner INLINECALLDICT
@ -1389,6 +1408,28 @@ PROGRAM{
__gen_store_TONB INLINECALLDICT
}>
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
EQUAL
IFJMP:<{
@ -1523,6 +1564,6 @@ PROGRAM{
86142586315491086060343270784266291122 PUSHINT
}>
get_abi_ipfs PROC:<{
x{697066733a2f2f516d5a656933325952484a526e5443763771593357705431367a41444a43584a3642433939364370486169527147} PUSHSLICE
x{697066733a2f2f516d6456695758745a474e59436f515a4e535573396867624b396172686f7a75716656516964484a4b4d676a6f72} PUSHSLICE
}>
}END>c

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

@ -170,7 +170,7 @@ SETCP0
2 GETGLOBVAR
MYADDR
ROT
56 CALLDICT
57 CALLDICT
}> CALLREF
2DUP
<{
@ -207,7 +207,7 @@ SETCP0
2 GETGLOBVAR
MYADDR
10 2 -2 PU2XC
58 CALLDICT
59 CALLDICT
2DUP
<{
0 PUSHINT
@ -1199,7 +1199,7 @@ SETCP0
2 GETGLOBVAR
MYADDR
ROT
56 CALLDICT
57 CALLDICT
}> CALLREF
2DUP
<{
@ -1717,6 +1717,213 @@ SETCP0
}> PUSHCONT
IFJMP
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
EQUAL
<{
@ -1936,7 +2143,8 @@ SETCP0
STREF
ENDC
c4 POP
}> IFJMPREF
}> PUSHCONT
IFJMP
s0 PUSH
2078119902 PUSHINT
EQUAL
@ -2077,7 +2285,7 @@ SETCP0
2 GETGLOBVAR
MYADDR
ROT
56 CALLDICT
57 CALLDICT
}> CALLREF
s0 s1 XCHG
4429 PUSHINT
@ -2508,7 +2716,7 @@ SETCP0
2 GETGLOBVAR
MYADDR
ROT
56 CALLDICT
57 CALLDICT
}> CALLREF
12 2 BLKDROP2
<{
@ -3094,7 +3302,7 @@ SETCP0
2 GETGLOBVAR
MYADDR
ROT
56 CALLDICT
57 CALLDICT
}> CALLREF
<{
0 PUSHINT
@ -3484,7 +3692,7 @@ SETCP0
2 GETGLOBVAR
MYADDR
ROT
56 CALLDICT
57 CALLDICT
}> CALLREF
2DUP
<{
@ -3531,7 +3739,7 @@ SETCP0
s9 s-1 PUXC
s17 PUSH
s0 s1 XCHG
58 CALLDICT
59 CALLDICT
2DUP
<{
0 PUSHINT
@ -4958,7 +5166,7 @@ SETCP0
IFELSE
130 THROW
55:
56:
0 PUSHINT
PUSHNULL
PUSHNULL
@ -5014,7 +5222,7 @@ SETCP0
STREF
ENDC
56:
57:
s0 s2 XCHG
CTOS
LDDICT
@ -5037,9 +5245,9 @@ SETCP0
STDICT
ENDC
s0 s0 s3 XCHG3
55 CALLDICT
56 CALLDICT
57:
58:
PUSHNULL
s0 s4 XCHG
NEWC
@ -5071,7 +5279,7 @@ SETCP0
STREF
ENDC
58:
59:
s0 s3 XCHG
CTOS
LDDICT
@ -5095,7 +5303,7 @@ SETCP0
ENDC
3 1 BLKSWAP
s0 s4 XCHG
57 CALLDICT
58 CALLDICT
owner:
c4 PUSH
@ -5276,7 +5484,7 @@ SETCP0
2 GETGLOBVAR
MYADDR
ROT
56 CALLDICT
57 CALLDICT
}> CALLREF
12 2 BLKDROP2
<{
@ -5402,7 +5610,7 @@ SETCP0
2 GETGLOBVAR
MYADDR
ROT
56 CALLDICT
57 CALLDICT
}> CALLREF
8 2 BLKDROP2
s0 POP

22
sources/output/jetton_TONB.md

@ -1,9 +1,9 @@
# TACT Compilation Report
Contract: TONB
BOC Size: 4090 bytes
BOC Size: 4276 bytes
# Types
Total Types: 33
Total Types: 36
## 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`
Signature: `FinishVote{voteId:int257}`
## Vote
TLB: `vote#b670f4ce voteId:int257 adminIndex:int257 vote:int257 = Vote`
Signature: `Vote{voteId:int257,adminIndex:int257,vote:int257}`
## VoteMsg
TLB: `vote_msg#58fde8ab voteId:int257 adminIndex:int257 vote:int257 = VoteMsg`
Signature: `VoteMsg{voteId:int257,adminIndex:int257,vote: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`
Signature: `CollectProfit{adminIndex:int257}`
## SetOwner
TLB: `set_owner#b71c6df6 owner:address = SetOwner`
Signature: `SetOwner{owner:address}`
## 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}`
## 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
TLB: `change_owner#0f474d03 newOwner:address = ChangeOwner`
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() {
return "ipfs://QmZ8U23MsSzC5NvLwmc6Wh8LzCefCn61CpNQ81T9a6A8dZ";
return "ipfs://QmWUsMjXBDmUpAiZnwRzPM5E4Q81yVQkRc88XnAJYWif2a";
}

2
sources/output/jetton_TONBWallet.code.fif

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

20
sources/output/jetton_TONBWallet.md

@ -3,7 +3,7 @@ Contract: TONBWallet
BOC Size: 2111 bytes
# Types
Total Types: 33
Total Types: 36
## 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`
Signature: `FinishVote{voteId:int257}`
## Vote
TLB: `vote#b670f4ce voteId:int257 adminIndex:int257 vote:int257 = Vote`
Signature: `Vote{voteId:int257,adminIndex:int257,vote:int257}`
## VoteMsg
TLB: `vote_msg#58fde8ab voteId:int257 adminIndex:int257 vote:int257 = VoteMsg`
Signature: `VoteMsg{voteId:int257,adminIndex:int257,vote: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`
Signature: `CollectProfit{adminIndex:int257}`
## SetOwner
TLB: `set_owner#b71c6df6 owner:address = SetOwner`
Signature: `SetOwner{owner:address}`
## 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}`
## 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
TLB: `change_owner#0f474d03 newOwner:address = ChangeOwner`
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 = {
$$type: 'Vote';
export type VoteMsg = {
$$type: 'VoteMsg';
voteId: bigint;
adminIndex: bigint;
vote: bigint;
}
export function storeVote(src: Vote) {
export function storeVoteMsg(src: VoteMsg) {
return (builder: 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.adminIndex, 257);
b_0.storeInt(src.vote, 257);
};
}
export function loadVote(slice: Slice) {
export function loadVoteMsg(slice: 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 _adminIndex = 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 _adminIndex = 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();
builder.writeNumber(source.voteId);
builder.writeNumber(source.adminIndex);
@ -1106,13 +1106,13 @@ function storeTupleVote(source: Vote) {
return builder.build();
}
function dictValueParserVote(): DictionaryValue<Vote> {
function dictValueParserVoteMsg(): DictionaryValue<VoteMsg> {
return {
serialize: (src, buidler) => {
buidler.storeRef(beginCell().store(storeVote(src)).endCell());
buidler.storeRef(beginCell().store(storeVoteMsg(src)).endCell());
},
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 = {
$$type: 'WithdrawalRequests';
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 = {
$$type: 'ChangeOwner';
newOwner: Address;
@ -1694,11 +1864,26 @@ const TONBWallet_errors: { [key: number]: { message: string } } = {
136: { message: `Invalid address` },
4429: { message: `Invalid sender` },
6384: { message: `not enough money for withdraw` },
6873: { message: `Only an admin can initiate a vote` },
13650: { message: `Invalid bounced message` },
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` },
34326: { message: `Vote is not finished yet` },
37444: { message: `Only a founder can request unstake` },
41207: { message: `invalid sender` },
42983: { message: `No profit to collect` },
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` },
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,
"from": "kQAI-3FJVc_ywSuY4vq0bYrzR7S4Och4y7bTU_i5yLOB3A6P",
"to": "kQABEUn8yLZqJKZAi4TZjnxqafjqNKCwpuE_-kOXim3gA5il",
"to": "kQAHUsQxZnU4LMhYKHdaISP9rf-1OcdDAPFWD-bZapIcRtpr",
"type": "internal",
"value": 100200000000n,
},
"type": "received",
},
{
"gasUsed": 32815n,
"gasUsed": 32790n,
"type": "processed",
},
{
@ -31,8 +31,8 @@ exports[`jetton should deploy and deposit the wallet with the correct sum of mon
"type": "cell",
},
"bounce": false,
"from": "kQABEUn8yLZqJKZAi4TZjnxqafjqNKCwpuE_-kOXim3gA5il",
"to": "kQCMEn5NnRirD8pMXczMDKEXDjBM8tPVXYdj6X3b9ySJdCgP",
"from": "kQAHUsQxZnU4LMhYKHdaISP9rf-1OcdDAPFWD-bZapIcRtpr",
"to": "kQCFVoQORdkDXw6i10RJiDkJAzm-Kj0oq_ldL66vZpovRblF",
"type": "internal",
"value": 11365000n,
},
@ -43,13 +43,13 @@ exports[`jetton should deploy and deposit the wallet with the correct sum of mon
"messages": [
{
"body": {
"cell": "x{178D451900000000000000005174876E800800022293F9916CD4494C811709B31CF8D4D3F1D46941614DC27FF4872F14DBC00700023EDC525573FCB04AE638BEAD1B62BCD1ED2E0E721E32EDB4D4FE2E722CE07702_}
x{800000000000000000000000000000000000000000000000000000000000000020046093F26CE8C5587E5262EE66606508B8718267969EAAEC3B1F4BEEDFB9244BA4_}",
"cell": "x{178D451900000000000000005174876E8008000EA58862CCEA705990B050EEB44247FB5BFF6A738E8601E2AC1FCDB2D524388D00023EDC525573FCB04AE638BEAD1B62BCD1ED2E0E721E32EDB4D4FE2E722CE07702_}
x{800000000000000000000000000000000000000000000000000000000000000020042AB420722EC81AF87516BA224C41C84819CDF151E9455FCAE97D757B34D17A2C_}",
"type": "cell",
},
"bounce": false,
"from": "kQABEUn8yLZqJKZAi4TZjnxqafjqNKCwpuE_-kOXim3gA5il",
"to": "kQBPWbXsnNaT4jX5J-TIyCfqT9ieWU1c-OxPUejeUisQd5cf",
"from": "kQAHUsQxZnU4LMhYKHdaISP9rf-1OcdDAPFWD-bZapIcRtpr",
"to": "kQDyCsUcb80ZqWzhdTc0Qm-DMCQMp9QyFHBtH0Y2RlTXVSu1",
"type": "internal",
"value": 41715000n,
},
@ -69,14 +69,14 @@ exports[`jetton should work correctly with the staking 1`] = `
},
"bounce": true,
"from": "kQAI-3FJVc_ywSuY4vq0bYrzR7S4Och4y7bTU_i5yLOB3A6P",
"to": "kQCWdkwB2iVEz4eqkgyEp_trwnITQd4LiGEcLGENymBCqgFX",
"to": "kQDwhC8P_RtjQLYFddZ6FFl3wC95KNUcG6s-f7bIe4s6amT_",
"type": "internal",
"value": 100200000000n,
},
"type": "received",
},
{
"gasUsed": 36098n,
"gasUsed": 36073n,
"type": "processed",
},
{
@ -87,8 +87,8 @@ exports[`jetton should work correctly with the staking 1`] = `
"type": "cell",
},
"bounce": false,
"from": "kQCWdkwB2iVEz4eqkgyEp_trwnITQd4LiGEcLGENymBCqgFX",
"to": "kQACkI90BJ8sTu1IlFoOtzChElnpXsotC8lrmFMGJknQ_Flx",
"from": "kQDwhC8P_RtjQLYFddZ6FFl3wC95KNUcG6s-f7bIe4s6amT_",
"to": "kQDg1oqtEuoPiStRfbdmM9Bifn4MUekCMD6ufYHXOsuoAizf",
"type": "internal",
"value": 11365000n,
},
@ -99,13 +99,13 @@ exports[`jetton should work correctly with the staking 1`] = `
"messages": [
{
"body": {
"cell": "x{178D451900000000000000005174876E8008012CEC9803B44A899F0F552419094FF6D784E42683BC1710C23858C21B94C0855500023EDC525573FCB04AE638BEAD1B62BCD1ED2E0E721E32EDB4D4FE2E722CE07702_}
x{8000000000000000000000000000000000000000000000000000000000000000200014847BA024F962776A44A2D075B9850892CF4AF651685E4B5CC29831324E87E4_}",
"cell": "x{178D451900000000000000005174876E800801E1085E1FFA36C6816C0AEBACF428B2EF805EF251AA3837567CFF6D90F71674D500023EDC525573FCB04AE638BEAD1B62BCD1ED2E0E721E32EDB4D4FE2E722CE07702_}
x{8000000000000000000000000000000000000000000000000000000000000000200706B4556897507C495A8BEDBB319E8313F3F0628F481181F573EC0EB9D65D4014_}",
"type": "cell",
},
"bounce": false,
"from": "kQCWdkwB2iVEz4eqkgyEp_trwnITQd4LiGEcLGENymBCqgFX",
"to": "kQCO4TveQnMW97esrpa9c9juf5h1ry8gHsxGmUzPjVmBd9Sf",
"from": "kQDwhC8P_RtjQLYFddZ6FFl3wC95KNUcG6s-f7bIe4s6amT_",
"to": "kQBVdGf16yM9JOGzv062bUvEyZGz2yjeJqOnGU_HMPxJxu2S",
"type": "internal",
"value": 41715000n,
},
@ -120,7 +120,7 @@ exports[`jetton should work correctly with the staking 1`] = `
"type": "cell",
},
"bounce": true,
"from": "kQCWdkwB2iVEz4eqkgyEp_trwnITQd4LiGEcLGENymBCqgFX",
"from": "kQDwhC8P_RtjQLYFddZ6FFl3wC95KNUcG6s-f7bIe4s6amT_",
"to": "kQC5Y865mUcSTsSpJYbli0KmSiriJUBFHlKmvNqkS7T5VyUx",
"type": "internal",
"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 { TONB } from "../output/jetton_TONB";
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 }) {
let seqno: number = await wallet.getSeqno();
@ -74,7 +76,31 @@ export async function getTONB(tonb_content?: any) {
if (!tonb_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) {

Loading…
Cancel
Save