-
Notifications
You must be signed in to change notification settings - Fork 63
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Description
While testing the DeDust example from the Tact cookbook, I encountered a VM crash when the vault tried to interact with the USDT jetton-wallet.
handling exception code 9: failed to load library cell
default exception handler, terminating vm with exit code 9
"@ton/blueprint": ">=0.40.0",
"@ton/sandbox": ">=0.37.0",
Steps to Reproduce
npm create ton@latest
- Then a contract was written
//
// Helper structs described earlier on this page
//
struct SwapStep {
poolAddress: Address;
kind: Int as uint1 = 0;
limit: Int as coins = 0;
nextStep: Cell?;
}
struct SwapParams {
deadline: Int as uint32 = 0;
recipientAddress: Address? = null;
referralAddress: Address? = null;
fulfillPayload: Cell? = null;
rejectPayload: Cell? = null;
}
/// https://docs.dedust.io/reference/tlb-schemes#message-swap
message(0xea06185d) NativeSwap {
// Unique identifier used to trace transactions across multiple contracts
// Defaults to 0, which means we don't mark messages to trace their chains
queryId: Int as uint64 = 0;
// Toncoin amount for the swap
amount: Int as coins;
// Inlined fields of SwapStep struct
poolAddress: Address;
kind: Int as uint1 = 0;
limit: Int as coins = 0;
nextStep: SwapStep? = null;
// Set of parameters relevant for the whole swap
swapParams: SwapParams;
}
/// https://docs.dedust.io/reference/tlb-schemes#message-swap-1
message(0xe3a0d482) JettonSwapPayload {
// Inlined fields of SwapStep struct
poolAddress: Address;
kind: Int as uint1 = 0;
limit: Int as coins = 0;
nextStep: SwapStep? = null;
// Set of parameters relevant for the entire swap
swapParams: SwapParams;
}
message(0xf8a7ea5) JettonTransfer {
queryId: Int as uint64;
amount: Int as coins;
destination: Address;
responseDestination: Address;
customPayload: Cell? = null;
forwardTonAmount: Int as coins;
forwardPayload: Cell?; // slightly adjusted
}
message SwapTon {
swapAmount: Int;
}
message SwapJetton {
swapAmount: Int;
targetJettonWalletAddress: Address;
}
contract DeDust {
receive(swap: SwapTon) {
// Let's say `swapAmount` is `ton("0.1")`, which is 10000000 nanoToncoins
send(SendParameters {
// Address of the TON vault to send the message to
to: address("EQDa4VOnTYlLvDJ0gZjNYm5PXfSmmtL6Vs6A_CZEtXCNICq_"),
// Amount to swap plus a trade fee
value: swap.swapAmount + ton("0.2"),
body: NativeSwap {
amount: swap.swapAmount,
// Address of the swap pool, which is the TON/USDT pair in this case
// poolAddress: address("EQAvtGe8Nep_XncmQYJrqzWjjdsTaygzL17bvH_8Rjryz1xu"), // DeDust Pool: TONNEL/TON
poolAddress: address("EQA-X_yo3fzzbDbJ_0bzFWKqtRuZFIRa1sJsveZJ1YpViO3r"), // DeDust Pool: TON/USDT
// Set of parameters relevant for the whole swap
swapParams: SwapParams {}, // use defaults
}.toCell(),
});
}
receive(swap: SwapJetton) {
send(SendParameters {
to: swap.targetJettonWalletAddress,
value: ton("0.3"),
body: JettonTransfer {
// Unique identifier used to trace transactions across multiple contracts.
// Set to 0, which means we don't mark messages to trace their chains.
queryId: 0,
// Jetton amount for the swap.
amount: swap.swapAmount, // NOTE: change to your amount
// Address of the Jetton vault to send the message to.
destination: address("EQC8jbJfR7Mu7K5oeyiIoHC3gWLmdCju2pUBucXqmQClB__N"), // DeDust Vault
// Address to return any exceeding funds.
responseDestination: myAddress(),
forwardTonAmount: ton("0.25"),
forwardPayload: JettonSwapPayload {
// Address of the swap pool, which is the TON/USDT pair in this case.
poolAddress: address("EQAvtGe8Nep_XncmQYJrqzWjjdsTaygzL17bvH_8Rjryz1xu"), // DeDust Pool: TONNEL/TON
// Set of parameters relevant for the entire swap.
swapParams: SwapParams {}, // use defaults
}.toCell(),
}.toCell(),
});
}
receive() {
cashback(sender());
}
}
- Tests were implemented
import {
Blockchain,
SandboxContract,
TreasuryContract,
RemoteBlockchainStorage,
wrapTonClient4ForRemote,
} from '@ton/sandbox';
import { TonClient4 } from '@ton/ton';
import { Address, fromNano, Sender, toNano } from '@ton/core';
import { DeDust } from '../build/DeDust/DeDust_DeDust';
import '@ton/test-utils';
describe('DeDust', () => {
let blockchain: Blockchain;
let deployer: SandboxContract<TreasuryContract>;
let deDust: SandboxContract<DeDust>;
beforeEach(async () => {
blockchain = await Blockchain.create({
storage: new RemoteBlockchainStorage(
wrapTonClient4ForRemote(
new TonClient4({
endpoint: 'https://mainnet-v4.tonhubapi.com',
}),
),
),
});
deDust = blockchain.openContract(await DeDust.fromInit());
deployer = await blockchain.treasury('deployer', {});
const deployResult = await deDust.send(
deployer.getSender(),
{
value: toNano('0.05'),
},
null,
);
expect(deployResult.transactions).toHaveTransaction({
from: deployer.address,
to: deDust.address,
deploy: true,
success: true,
});
});
it('should deploy', async () => {
console.log('My Balance', fromNano(await deployer.getBalance()));
console.log('DeDustSwapper', fromNano((await blockchain.getContract(deDust.address)).balance));
const TxResult = await deDust.send(
deployer.getSender(),
{
value: toNano('1.3'),
},
{ $$type: 'SwapTon', swapAmount: toNano(1) },
);
console.log(TxResult);
console.log('My Balance', fromNano(await deployer.getBalance()));
console.log('DeDustSwapper', fromNano((await blockchain.getContract(deDust.address)).balance));
});
});
-
Run
npx blueprint test
-
You can find the error here
console.log(TxResult);
Environment
Windows 10
Logs or Screenshots
{
address: 61901089978021766573933745695147471064659099173648288175756929695054453318535n,
lt: 61872258000011n,
prevTransactionHash: 8089611070652109801654583336794466648641561177747294017534910868700693763909n,
prevTransactionLt: 61872258000010n,
now: 1758716651,
outMessagesCount: 1,
oldStatus: 'active',
endStatus: 'active',
inMessage: [Object],
outMessages: [Dictionary],
totalFees: [Object],
stateUpdate: [Object],
description: [Object],
raw: x{788DAC67CCEADB9CAE6FAAC7118F05C0FA95DF36C2A92E686AC39D96310D0A38700003845C1F5A48B11E28EBF6639BEB6AB2706379E989EC368674F23F1A701B50445C0B4EF17974500003845C1F5A48A68D3E2EB0003461046A6}
x{E_}
x{680031551C5DDAA2E8FB5C06780F3727107B28395B1ECA8B3E5DD39AE8E96D71DABB002236B19F33AB6E72B9BEAB1C463C1703EA577CDB0AA4B9A1AB0E7658C43428E1D02BCE9340060E9DB20000708B83EB4914D1A7C5D6C_}
x{0F8A7EA5000000000000000032B2436800355B48BEA2B7CC3AC4182DF9751CDE2C40E37A03F9AEE3EE8CA115DCBD0E29850006AB6917D456F987588305BF2EA39BC5881C6F407F35DC7DD19422BB97A1C5308810075520}
x{DF_}
x{580111B58CF99D5B7395CDF558E231E0B81F52BBE6D85525CD0D5873B2C621A1470F00062AA38BBB545D1F6B80CF01E6E4E20F65072B63D95167CBBA735D1D2DAE3B57502B9DBF400608235A0000708B83EB4918D1A7C5D67FFFFFFF87C53F528000000000000000195921B4001AADA45F515BE61D620C16FCBA8E6F4_}
x{72AB820549B33D13008C60E8EA86C81686AE2E03D191DB0A37A814EEA86A32393BF8B9C591177C3C6CEE96F7BCD53B92EDCAF33BA63DFF6B3067939A63739A9205}
x{040902BCE9341060C3500E0181046998208D6A_}
x{407D0C1C095400000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000},
hash: [Function: hash],
blockchainLogs: '[ 4][t 0][2025-09-24 12:24:11.633000][transaction.cpp:445]\tunpacking account 88DAC67CCEADB9CAE6FAAC7118F05C0FA95DF36C2A92E686AC39D96310D0A387\n' +
'[ 4][t 0][2025-09-24 12:24:11.633000][transaction.cpp:278]\tlast_paid=0; cells=0 bits=0\n' +
'[ 4][t 0][2025-09-24 12:24:11.633000][transaction.cpp:508]\tend of Account.unpack() for 0:88DAC67CCEADB9CAE6FAAC7118F05C0FA95DF36C2A92E686AC39D96310D0A387 (balance = 1799935430627ng ; last_trans_lt = 61872258000010..61872258000011)\n' +
'[ 4][t 0][2025-09-24 12:24:11.633000][transaction.cpp:4006]\tblock random seed set to 0000000000000000000000000000000000000000000000000000000000000000\n' +
'[ 4][t 0][2025-09-24 12:24:11.633000][transaction.cpp:1292]\tgas limits: max=1000000, limit=459349, credit=0\n' +
'[ 4][t 0][2025-09-24 12:24:11.633000][transaction.cpp:1706]\tin_msg_state is null\n' +
'[ 3][t 0][2025-09-24 12:24:11.633000][transaction.cpp:1785]\tUnknown precompiled contract (code_hash=89468F02C78E570802E39979C8516FC38DF07EA76A48357E0536F2BA7B3EE37B, gas_usage=1000), running VM\n' +
'[ 4][t 0][2025-09-24 12:24:11.633000][transaction.cpp:1799]\tcreating VM\n' +
'[ 4][t 0][2025-09-24 12:24:11.633000][transaction.cpp:1417]\tSmartContractInfo initialized with [ 124711402 0 0 1758716651 10000000 61872258000011 31001199375342540328671374741713225991918088502499606102394480502517547827387 [ 1800119170227 (null) ] CS{Cell{026dc0088dac67cceadb9cae6faac7118f05c0fa95df36c2a92e686ac39d96310d0a387000000000000000e11707d6922d8068c520c3f8d340} bits: 1..268; refs: 0..0} C{0BC9F6FFD54A6C031C516C4AD2CD9257D49DA3458F89C12B53F90A548D3BD668} C{89468F02C78E570802E39979C8516FC38DF07EA76A48357E0536F2BA7B3EE37B} [ 183739600 (null) ] 0 (null) [ CS{Cell{004dd06600000000000000000000000080000000000000fa00000000000001f4000000000003d09040} bits: 9..305; refs: 0..0} CS{Cell{0008ffffff11} bits: 0..32; refs: 0..0} CS{Cell{0094d1000000000000006400000000000f4240de000000002710000000000000000f424000000000042c1d80000000000000271000000000002625a00000000005f5e100000000003b9aca00} bits: 0..592; refs: 0..0} CS{Cell{0094d100000000000000640000000000009c40de000000000190000000000000000f424000000000000f4240000000000000271000000000009896800000000005f5e100000000003b9aca00} bits: 0..592; refs:
0..0} CS{Cell{0042ea000000000098968000000000271000000000000f424000000001800055555555} bits: 0..264; refs: 0..0} CS{Cell{0042ea0000000000061a800000000001900000000000009c4000000001800055555555} bits: 0..264; refs: 0..0} (null) ] 0 1000 [ -1 0 CS{Cell{01b1680031551c5ddaa2e8fb5c06780f3727107b28395b1eca8b3e5dd39ae8e96d71dabb002236b19f33ab6e72b9beab1c463c1703ea577cdb0aa4b9a1ab0e7658c43428e1d02bce9340060e9db20000708b83eb4914d1a7c5d6c0} bits: 4..271; refs: 0..0} 478937 61872258000010 1758716651 183739600 183739600 (null) (null) ] ]\n' +
'[ 4][t 0][2025-09-24 12:24:11.634000][transaction.cpp:1834]\tstarting VM\n' +
'[ 4][t 0][2025-09-24 12:24:11.634000][transaction.cpp:1839]\tVM terminated with exit code 9\n' +
'[ 3][t 0][2025-09-24 12:24:11.634000][transaction.cpp:1861]\tsteps: 2 gas: used=160, max=1000000, limit=1000000, credit=0\n' +
'[ 3][t 0][2025-09-24 12:24:11.634000][transaction.cpp:1863]\tout_of_gas=false, accepted=true, success=false, time=0.000267s\n' +
'[ 4][t 0][2025-09-24 12:24:11.634000][transaction.cpp:1898]\tgas fees: 400000 = 26214400 * 1000 /2^16 ; price=26214400; flat rate=[40000 for 100]; remaining balance=1800118770227ng\n',
vmLogs: 'execute implicit JMPREF\n' +
'handling exception code 9: failed to load library cell\n' +
'default exception handler, terminating vm with exit code 9\n',
debugLogs: '',
oldStorage: undefined,
newStorage: undefined,
outActions: undefined,
events: [Array],
parent: [Object],
children: [Array],
externals: [],
mode: 0
},
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working