Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7eace49
Add Wrapped TON (wTON) - init
krebernisak May 20, 2026
1c8e98e
Add wTON README.md + nolint:opcode
krebernisak May 20, 2026
ad06d92
Add TON handling on wTON transfer/burn
krebernisak May 20, 2026
c9268c8
Fix ChangeMinterMetadataUri
krebernisak May 20, 2026
0de29f1
Remove UpgradeMinterCode from in msgs
krebernisak May 20, 2026
8e0ea90
Add MintNewJettons handling, audit
krebernisak May 21, 2026
d5e7e6f
Make compile w/ tolk 1.2, add tests
krebernisak May 21, 2026
54d6b92
Lint fix
krebernisak May 21, 2026
95237a1
mv test, add wton errors bindings
krebernisak May 21, 2026
bf7054a
Fix lint add /contracts/.envrc
krebernisak May 21, 2026
494093f
Cleanup TOP_UP opcode
krebernisak May 21, 2026
ade0133
Polish and add tests
krebernisak May 22, 2026
f2a24a9
Add gas-report calibration
krebernisak May 25, 2026
b1258df
Add missing test cases, adjust burn-budgeting
krebernisak May 25, 2026
84e10d0
Unskip a test - burn notification bounces
krebernisak May 25, 2026
29a568b
Add test - refunds bounced mint
krebernisak May 25, 2026
449378d
Add checkAmountIsEnoughToMint on mint
krebernisak May 25, 2026
c1c2283
Polish Jetton TS bindings - first pass
krebernisak May 26, 2026
079a20e
Add workchain guard to burn flow
krebernisak May 26, 2026
0142a19
Polish Jetton TS bindings - consts/payloads
krebernisak May 26, 2026
5acd17b
Add 'internalTransferMsg.sendExcessesTo.getWorkchain()' check and a f…
krebernisak May 26, 2026
8e6f43f
Add high-level info to README
krebernisak May 26, 2026
38feac3
Fix test
krebernisak May 27, 2026
8c2e2b2
Restructure and polish minter/wallet bindings
krebernisak May 27, 2026
a01efad
Remove unused errors, fmt
krebernisak May 27, 2026
b7aa74c
Avoid minting to minter addr
krebernisak May 28, 2026
7951ea4
rm admin requirement from bindings/tests - wTON has no admin
krebernisak May 28, 2026
dd85e20
Remove ChangeMinterMetadataUri and custom error - throw 0xffff
krebernisak May 28, 2026
156c67e
Add burn BOUNCE_ON_ACTION_FAIL test
krebernisak May 28, 2026
54aae5d
Add in.originalForwardFee test - payload size check
krebernisak May 28, 2026
4508733
Add wallet.AskToWithdrawExcess, add wallet.InternalTransferStep surpl…
krebernisak May 29, 2026
5b28f2d
Add extra coverage
krebernisak May 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions contracts/.envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
watch_file shell.nix
use flake .#contracts || use nix
10 changes: 7 additions & 3 deletions contracts/contracts/examples/jetton/onramp_mock.tolk
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: MIT
tolk 1.2

import "@stdlib/common.tolk"
import "../../lib/jetton/jetton_client.tolk"
import "../../lib/jetton/messages.tolk"
import "../../lib/jetton/utils.tolk"
import "../../lib/utils.tolk"
Comment thread
krebernisak marked this conversation as resolved.

// OnrampMock contract in Tolk
Expand All @@ -12,6 +13,9 @@ const FEE = 5
const INCORRECT_SENDER_ERROR = 100
const FORWARD_PAYLOAD_REQUIRED_ERROR = 101

// Jetton wallet utilities for Tolk
const JETTON_TOPIC : int = 0x351 // for easier indexing

Comment on lines +16 to +18
struct OnrampMock {
JettonClient: JettonClient
}
Expand Down Expand Up @@ -49,13 +53,13 @@ fun OnrampMock.handleJettonTransferNotification(

// Handle the jetton transfer
if (msg.jettonAmount < FEE) {
emit(JETTON_TOPIC, InsufficientFee { queryId: msg.queryId, sender: msg.transferInitiator });
emit(JETTON_TOPIC, InsufficientFee { queryId: msg.queryId, sender: msg.transferInitiator! });
} else {
emit(
JETTON_TOPIC,
AcceptedRequest {
queryId: msg.queryId,
sender: msg.transferInitiator,
sender: msg.transferInitiator!,
payload: forwardPayloadCell!,
}
);
Expand Down
2 changes: 2 additions & 0 deletions contracts/contracts/examples/jetton/sender.tolk
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// SPDX-License-Identifier: MIT
tolk 1.2

import "@stdlib/common.tolk"
import "../../lib/jetton/jetton_client.tolk"
import "../../lib/jetton/messages.tolk"
Expand Down
2 changes: 2 additions & 0 deletions contracts/contracts/examples/jetton/simple_receiver.tolk
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// SPDX-License-Identifier: MIT
tolk 1.2

import "@stdlib/common.tolk"
import "../../lib/jetton/jetton_client.tolk"
import "../../lib/jetton/messages.tolk"
Expand Down
8 changes: 8 additions & 0 deletions contracts/contracts/lib/jetton/errors.tolk
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT

const ERROR_INVALID_OP = 72
const ERROR_NOT_OWNER = 73
Comment thread
krebernisak marked this conversation as resolved.
const ERROR_NOT_VALID_WALLET = 74
const ERROR_WRONG_WORKCHAIN = 333
const ERROR_BALANCE_ERROR = 47
const ERROR_NOT_ENOUGH_GAS = 48
24 changes: 24 additions & 0 deletions contracts/contracts/lib/jetton/jetton-utils.tolk
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT
import "storage"

fun calcDeployedJettonWallet(ownerAddress: address, minterAddress: address, jettonWalletCode: cell): AutoDeployAddress {
val emptyWalletStorage: WalletStorage = {
status: 0,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this status for?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is also defined in notcoin but not mentioned in docs

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used to lock outgoing and incoming transfers in the original notcoin impl here: https://github.com/OpenBuilders/notcoin-contract/blob/c9992514b71f1775cec5df49fbea31a85ddd87f9/contracts/jetton-wallet.fc#L44C5-L44C62

;; int outgoing_transfers_unlocked = ((status & 1) == 0);

...

;; int incoming_transfers_locked = ((status & 2) == 2);

We keep it in ther ref implementation for consistent addr derivation and get_status getter which here just returns 0 for wTON, no transfer limits

jettonBalance: 0,
ownerAddress,
minterAddress,
};

return {
workchain: BASECHAIN,
stateInit: {
code: jettonWalletCode,
Comment thread
patricios-space marked this conversation as resolved.
data: emptyWalletStorage.toCell()
}
}
}

fun calcAddressOfJettonWallet(ownerAddress: address, minterAddress: address, jettonWalletCode: cell) {
val jwDeployed = calcDeployedJettonWallet(ownerAddress, minterAddress, jettonWalletCode);
return jwDeployed.calculateAddress();
}
4 changes: 2 additions & 2 deletions contracts/contracts/lib/jetton/jetton_client.tolk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
import "./utils.tolk"
import "jetton-utils"
import "messages"

struct JettonClient {
Expand All @@ -9,7 +9,7 @@ struct JettonClient {

@inline
fun JettonClient.walletAddress(self): address {
return calculateUserJettonWalletAddress(
return calcAddressOfJettonWallet(
contract.getAddress(),
self.masterAddress,
self.jettonWalletCode
Expand Down
19 changes: 11 additions & 8 deletions contracts/contracts/lib/jetton/messages.tolk
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ struct (0x0f8a7ea5) AskToTransfer {
queryId: uint64
jettonAmount: coins
transferRecipient: address
sendExcessesTo: address
sendExcessesTo: address?
customPayload: cell?
forwardTonAmount: coins
forwardPayload: ForwardPayloadRemainder
Expand All @@ -19,16 +19,16 @@ struct (0x0f8a7ea5) AskToTransfer {
struct (0x7362d09c) TransferNotificationForRecipient {
queryId: uint64
jettonAmount: coins
transferInitiator: address
transferInitiator: address?
forwardPayload: ForwardPayloadRemainder
}

// nolint:opcode
struct (0x178d4519) InternalTransferStep {
queryId: uint64
jettonAmount: coins
transferInitiator: address
sendExcessesTo: address
transferInitiator: address? // is null when minting (not initiated by another wallet)
sendExcessesTo: address?
forwardTonAmount: coins
forwardPayload: ForwardPayloadRemainder
}
Expand All @@ -42,7 +42,7 @@ struct (0xd53276db) ReturnExcessesBack {
struct (0x595f07bc) AskToBurn {
queryId: uint64
jettonAmount: coins
sendExcessesTo: address
sendExcessesTo: address?
customPayload: cell?
}

Expand All @@ -51,7 +51,7 @@ struct (0x7bdd97de) BurnNotificationForMinter {
queryId: uint64
jettonAmount: coins
burnInitiator: address
sendExcessesTo: address
sendExcessesTo: address?
}

// nolint:opcode
Expand All @@ -64,7 +64,7 @@ struct (0x2c76b973) RequestWalletAddress {
// nolint:opcode
struct (0xd1735400) ResponseWalletAddress {
queryId: uint64
jettonWalletAddress: address
jettonWalletAddress: address?
ownerAddress: Cell<address>?
}

Expand Down Expand Up @@ -102,11 +102,14 @@ struct (0x2508d66a) UpgradeMinterCode {
// nolint:opcode
struct (0xcb862902) ChangeMinterMetadataUri {
queryId: uint64
// TODO: update to 1.4
newMetadataUri: SnakeString
}

// nolint:opcode
struct (0xd372158c) TopUpTons {}
struct (0xd372158c) TopUpTons {
}


// "forward payload" is TL/B `(Either Cell ^Cell)`;
// we want to test, that if ^Cell, no other data exists in a slice
Expand Down
12 changes: 9 additions & 3 deletions contracts/contracts/lib/jetton/storage.tolk
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: MIT
// Imported from https://github.com/ton-blockchain/tolk-bench/blob/0f416ca611fbfa25e736973d01e5fb70af485468/contracts_Tolk/03_notcoin/storage.tolk

// TODO: update to 1.4
// SnakeString describes a (potentially long) string inside a cell;
// short strings are stored as-is, like "my-picture.png";
// long strings are nested refs, like "xxxx".ref("yyyy".ref("zzzz"))
Expand All @@ -11,7 +13,7 @@ fun SnakeString.unpackFromSlice(mutate s: slice) {
// assert (s.remainingRefsCount() <= 1) throw 5;
// but since here we're matching the original FunC implementation, leave no checks
val snakeRemainder = s;
s = createEmptySlice(); // no more left to read
s = createEmptySlice(); // no more left to read
return snakeRemainder;
}

Expand All @@ -28,12 +30,15 @@ struct WalletStorage {

struct MinterStorage {
totalSupply: coins
adminAddress: address
nextAdminAddress: address
adminAddress: address?
nextAdminAddress: address?
jettonWalletCode: cell
// TODO: update to 1.4
metadataUri: Cell<SnakeString>
}



fun MinterStorage.load() {
return MinterStorage.fromCell(contract.getData());
}
Expand All @@ -42,6 +47,7 @@ fun MinterStorage.save(self) {
contract.setData(self.toCell());
}


fun WalletStorage.load() {
return WalletStorage.fromCell(contract.getData());
}
Expand Down
49 changes: 0 additions & 49 deletions contracts/contracts/lib/jetton/utils.tolk

This file was deleted.

Loading
Loading