Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Scans TON (The Open Network) smart contracts for 3 critical vulnerabilities including integer-as-boolean misuse, fake Jetton contracts, and forward TON without gas checks. Use when auditing FunC contracts.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 242% | 0% |
| case-17 | ✗→✓ | ▲ Improved | 90% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 272% | 0% |
| case-08 | ✓→✓ | = Same ✓ | 87% | 0% |
| case-22 | ✓→✓ | = Same ✓ | 101% | 0% |
Systematically scan TON blockchain smart contracts written in FunC for platform-specific security vulnerabilities related to boolean logic, Jetton token handling, and gas management. This skill encodes 3 critical vulnerability patterns unique to TON's architecture.
.fc, .funcfunc;; FunC contract indicators #include "imports/stdlib.fc"; () recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure { ;; Contract logic } () recv_external(slice in_msg) impure { ;; External message handler } ;; Common patterns send_raw_message() load_uint(), load_msg_addr(), load_coins() begin_cell(), end_cell(), store_*() transfer_notification operation op::transfer, op::transfer_notification .store_uint().store_slice().store_coins()
contracts/*.fc - FunC contract sourcewrappers/*.ts - TypeScript wrapperstests/*.spec.ts - Contract testston.config.ts or wasm.config.ts - TON project configWhen invoked, I will:
When vulnerabilities are found, you'll get a report like this:
=== TON VULNERABILITY SCAN RESULTS ===
Project: my-ton-contract
Files Scanned: 3 (.fc, .tact)
Vulnerabilities Found: 2
---
[CRITICAL] Missing Replay Protection
File: contracts/wallet.fc:45
Pattern: No sequence number or nonce validation
---
## 5. Vulnerability Patterns (3 Patterns)
I check for 3 critical vulnerability patterns unique to TON. For detailed detection patterns, code examples, mitigations, and testing strategies, see [VULNERABILITY_PATTERNS.md](resources/VULNERABILITY_PATTERNS.md).
### Pattern Summary:
1. **Missing Sender Check** ⚠️ CRITICAL - No sender validation on privileged operations
2. **Integer Overflow** ⚠️ CRITICAL - Unchecked arithmetic in FunC
3. **Improper Gas Handling** ⚠️ HIGH - Insufficient gas reservations
For complete vulnerability patterns with code examples, see [VULNERABILITY_PATTERNS.md](resources/VULNERABILITY_PATTERNS.md).
## 5. Scanning Workflow
### Step 1: Platform Identification
1. Verify FunC language (`.fc` or `.func` files)
2. Check for TON Blueprint or toncli project structure
3. Locate contract source files
4. Identify Jetton-related contracts
### Step 2: Boolean Logic Reviewrg "int.is_|int.has_|int.flag|int.enabled" contracts/
rg "= 1;|return 1;" contracts/ | grep -E "is_|has_|flag|enabled|valid"
rg "~.\(|~ " contracts/
For each boolean:
- [ ] Uses -1 for true, 0 for false
- [ ] NOT using 1 or other positive integers
- [ ] Logic operations work correctly
### Step 3: Jetton Handler Analysisrg "transfer_notification|op::transfer_notification" contracts/
For each Jetton handler:
- [ ] Validates sender address
- [ ] Sender checked against stored Jetton wallet address
- [ ] Cannot trust forward_payload without sender validation
- [ ] Has admin function to set Jetton wallet address
### Step 4: Gas/Forward Amount Reviewrg "forward_ton_amount|forward_amount" contracts/ rg "load_coins\(\)" contracts/
rg "send_raw_message" contracts/
For each outgoing message:
- [ ] Forward amounts are fixed/bounded
- [ ] OR user-provided amounts validated against msg_value
- [ ] Cannot drain contract balance
- [ ] Appropriate send_raw_message flags used
### Step 5: Manual Review
TON contracts require thorough manual review:
- Boolean logic with `~`, `&`, `|` operators
- Message parsing and validation
- Gas economics and fee calculations
- Storage operations and data serialization
---
## 6. Reporting Format
### Finding TemplateLocation: contracts/staking.fc:85-95 (recv_internal, transfer_notification handler)
Description: The transfer_notification operation handler does not validate that the sender is the expected Jetton wallet contract. Any attacker can send a fake transfer_notification message claiming to have transferred tokens, crediting themselves without actually depositing any Jettons.
Vulnerable Code:
func// staking.fc, line 85 if (op == op::transfer_notification) { int jetton_amount = in_msg_body~load_coins(); slice from_user = in_msg_body~load_msg_addr(); ;; WRONG: No validation of sender_address! ;; Attacker can claim any jetton_amount credit_user(from_user, jetton_amount); }
Attack Scenario:
transfer_notification message to staking contractProof of Concept:
typescript// Attacker sends fake transfer_notification const attackerContract = await blockchain.treasury("attacker"); await stakingContract.sendInternalMessage(attackerContract.getSender(), { op: OP_CODES.TRANSFER_NOTIFICATION, jettonAmount: toNano("1000000"), // Fake amount fromUser: attackerContract.address, }); // Attacker successfully credited without sending real Jettons const balance = await stakingContract.getUserBalance(attackerContract.address); expect(balance).toEqual(toNano("1000000")); // Attack succeeded
Recommendation: Store expected Jetton wallet address and validate sender:
funcglobal slice jetton_wallet_address; () recv_internal(...) impure { load_data(); ;; Load jetton_wallet_address from storage slice cs = in_msg_full.begin_parse(); int flags = cs~load_uint(4); slice sender_address = cs~load_msg_addr(); int op = in_msg_body~load_uint(32); if (op == op::transfer_notification) { ;; CRITICAL: Validate sender throw_unless(error::wrong_jetton_wallet, equal_slices(sender_address, jetton_wallet_address)); int jetton_amount = in_msg_body~load_coins(); slice from_user = in_msg_body~load_msg_addr(); ;; Safe to credit user credit_user(from_user, jetton_amount); } }
References:
---
## 7. Priority Guidelines
### Critical (Immediate Fix Required)
- Fake Jetton contract (unauthorized minting/crediting)
### High (Fix Before Launch)
- Integer as boolean (logic errors, broken conditions)
- Forward TON without gas check (balance drainage)
---
## 8. Testing Recommendations
### Unit Testsimport { Blockchain } from "@ton/sandbox"; import { toNano } from "ton-core";
describe("Security tests", () => { let blockchain: Blockchain; let contract: Contract;
beforeEach(async () => { blockchain = await Blockchain.create(); contract = blockchain.openContract(await Contract.fromInit()); });
it("should use correct boolean values", async () => { // Test that TRUE = -1, FALSE = 0 const result = await contract.getFlag(); expect(result).toEqual(-1n); // True expect(result).not.toEqual(1n); // Not 1! });
it("should reject fake jetton transfer", async () => { const attacker = await blockchain.treasury("attacker");
const result = await contract.send( attacker.getSender(), { value: toNano("0.05") }, { $$type: "TransferNotification", query_id: 0n, amount: toNano("1000"), from: attacker.address, } );
expect(result.transactions).toHaveTransaction({ success: false, // Should reject }); });
it("should validate gas for forward amount", async () => { const result = await contract.send( user.getSender(), { value: toNano("0.01") }, // Insufficient gas { $$type: "Transfer", to: recipient.address, forward_ton_amount: toNano("1"), // Trying to forward 1 TON } );
expect(result.transactions).toHaveTransaction({ success: false, }); }); });
### Integration Tests// Test with real Jetton wallet it("should accept transfer from real jetton wallet", async () => { // Deploy actual Jetton minter and wallet const jettonMinter = await blockchain.openContract(JettonMinter.create()); const userJettonWallet = await jettonMinter.getWalletAddress(user.address);
// Set jetton wallet in contract await contract.setJettonWallet(userJettonWallet);
// Real transfer from Jetton wallet const result = await userJettonWallet.sendTransfer( user.getSender(), contract.address, toNano("100"), {} );
expect(result.transactions).toHaveTransaction({ to: contract.address, success: true, }); });
---
## 9. Additional Resources
- **Building Secure Contracts**: `building-secure-contracts/not-so-smart-contracts/ton/`
- **TON Documentation**: https://docs.ton.org/
- **FunC Documentation**: https://docs.ton.org/develop/func/overview
- **TON Blueprint**: https://github.com/ton-org/blueprint
- **Jetton Standard**: https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md
---
## 10. Quick Reference Checklist
Before completing TON contract audit:
**Boolean Logic (HIGH)**:
- [ ] All boolean values use -1 (true) and 0 (false)
- [ ] NO positive integers (1, 2, etc.) used as booleans
- [ ] Functions returning booleans return -1 for true
- [ ] Boolean logic with `~`, `&`, `|` uses correct values
- [ ] Tests verify boolean operations work correctly
**Jetton Security (CRITICAL)**:
- [ ] `transfer_notification` handler validates sender address
- [ ] Sender checked against stored Jetton wallet address
- [ ] Jetton wallet address stored during initialization
- [ ] Admin function to set/update Jetton wallet
- [ ] Cannot trust forward_payload without sender validation
- [ ] Tests with fake Jetton contracts verify rejection
**Gas & Forward Amounts (HIGH)**:
- [ ] Forward TON amounts are fixed/bounded
- [ ] OR user-provided amounts validated: `msg_value >= tx_fee + forward_amount`
- [ ] Contract balance protected from drainage
- [ ] Appropriate `send_raw_message` flags used
- [ ] Tests verify cannot drain contract with excessive forward amounts
**Testing**:
- [ ] Unit tests for all three vulnerability types
- [ ] Integration tests with real Jetton contracts
- [ ] Gas cost analysis for all operations
- [ ] Testnet deployment before mainnetOther measured skills in the registry, with their headline benchmark lift.