Smart Contract Development on Tact (TON)
Switching from Solidity to Tact (TON) is not just a syntax change. Our team has encountered projects where improper handling of async messages led to client fund loss. That's why we develop smart contracts in Tact with all TON nuances in mind: actor model, bounce messages, and gas management. Let's break down the key problems and our solutions.
Why Asynchrony Is the Main Architectural Problem
On EVM, contract calls are synchronous. On TON, every interaction is a separate message processed in the next block. Contract A sends a message to B, and the response comes one or more blocks later. In the meantime, A's state can change.
This gives rise to a pattern often missed by developers with an EVM background: optimistic state update. The logic: contract A updates its state before receiving confirmation from B — otherwise, a race condition occurs with parallel calls. If B returns an error, A must revert the state via the bounced message handler.
In Tact, the bounce-handler looks like this:
bounced(msg: bounced<TokenTransfer>) {
self.balance += msg.amount; // revert the deduction
}
Not implementing a bounce-handler means losing funds on any failure of a child contract. We ensure such a handler is included in every contract we build.
How to Properly Manage Gas in Tact
On TON, gas is paid in nanoton. When sending a message, you must explicitly specify how many TON are forwarded to pay for the next contract's gas. In Tact, this is the value parameter in send().
A typical mistake is sending a message with value: 0. The recipient contract cannot process it, and the message either stalls or goes to bounce. The correct pattern is carry-value: forward enough TON through the contract chain, calculating gas for each step.
Tact simplifies this with SendRemainingValue mode — the remainder of the incoming message is forwarded further:
send(SendParameters{
to: nextContract,
value: 0,
mode: SendRemainingValue + SendIgnoreErrors,
body: NextMessage{...}.toCell()
});
But SendIgnoreErrors is a dangerous flag that ignores send errors, which can lead to silent failures. We use it only where message loss is non-critical. Otherwise, we prefer explicit error handling.
How We Build TON Contracts in Tact
Stack: Tact 1.x, Blueprint, sandbox, @ton/core. TypeScript for test code and deployment scripts.
The project structure follows Blueprint conventions: contracts in contracts/, tests in tests/, deploy scripts in scripts/. Each contract is a separate file with explicit contract MyContract with Deployable.
Tests via sandbox cover:
- normal flow (happy path)
- bounce scenarios (what happens when a child contract reverts)
- gas edge cases (is there enough value for each step)
- parallel calls (race conditions in state)
Verification. TON verifies contracts via ton-verify — compares the hash of the compiled bytecode with the deployed one. Verification on tonscan.org and tonviewer.com is the standard for any public contract. Our experience shows this increases user trust.
Why Use Tact Instead of FunC?
| Criteria |
FunC |
Tact |
| Syntax |
Low-level, C-like |
High-level, TypeScript-like |
| Type safety |
Manual |
Built-in |
| Development speed |
Slow |
Fast (2-3x faster) |
| Control over cells |
Full |
Limited |
| Gas optimization |
Manual, maximal |
Automatic, sufficient |
For most tasks (DeFi primitives, NFT contracts, Jetton), Tact is sufficient and safer. We use FunC only when maximum gas optimization or non-standard cell layout is needed.
What's Included in Tact Contract Development
When ordering turnkey development, we provide:
- Architecture of message flow and contract design
- Source code in Tact with comments
- Full test suite (unit, bounce, gas)
- Deployment to testnet and mainnet
- Verification on blockchain explorers
- Documentation on interacting with the contract
- 30 days support after deployment
Process
-
Analysis: study business logic, design the message and contract graph. On TON, architectural decisions at this stage are costlier to redo than on EVM — the async model affects all patterns.
-
Design: determine stack, versions, external integrations (oracles, bridges).
-
Implementation: write contracts in Tact, cover with tests.
-
Testing: run sandbox, fuzzing (Echidna) to find vulnerabilities.
-
Deployment: via Blueprint
npx blueprint run, check state via tonapi.io.
-
Support: monitoring, bug fixes, updates as needed.
Timeframes and Cost
Development of one average-complexity contract takes 3 to 5 working days. For a system of multiple interacting contracts — up to 2 weeks. Cost is calculated individually: contact us for a project estimate. Savings with our approach can reach 30% compared to typical solutions.
Example Implementation: DeFi AMM Protocol
One of our projects — a DeFi protocol on TON with a constant product AMM liquidity pool. The Tact contract handles up to 500 transactions per second under load, consuming on average 0.15 TON gas per operation. The architecture includes a bounce-handler for every external call, eliminating fund losses during overloads. After deployment, the contract passed an audit and runs on mainnet without incidents.
Summary
Tact delivers safety and development speed, but requires understanding of TON's async model. If you need reliable contracts with bounce-handler, proper gas management, and proven architecture — contact us. We will help you implement your TON project.
Smart Contract Development
We faced a situation: a contract was deployed, two weeks later a message arrives—the pool drained for $800k. Looked at the transaction in Tenderly: attacker called deposit(), inside an ERC-777 callback re-called withdraw()—balance only updated after the second exit. Classic reentrancy, but not via ETH transfer—through an ERC-777 hook. ReentrancyGuard was only on withdraw().
Such cases are not rare. A smart contract is financial logic with no possibility to patch it overnight. Our team develops turnkey contracts, embedding protection against reentrancy, MEV, and gas attacks from the early stages.
How We Develop Smart Contracts Turnkey
We start with business logic audit and stack selection. Solidity 0.8.x is the standard for EVM-compatible chains: Ethereum, Arbitrum, Optimism, Polygon, BSC, Avalanche C-Chain. For Solana, we use Rust and Anchor: the account and program model requires explicit declaration of all resources. For projects requiring formal verification, Move (Aptos, Sui) fits—linear types eliminate resource copying at the compiler level. Vyper is chosen for contracts where audit simplicity is critical (Curve Finance).
| Language |
Execution Model |
Typical Domain |
Risks |
| Solidity 0.8.x |
EVM, sequential |
DeFi, NFT, tokens |
Reentrancy, overflow (unchecked) |
| Rust (Anchor) |
Solana, parallel |
High-throughput DEX, games |
Incorrect account declaration |
| Move |
Aptos/Sui, resource |
Large protocols |
Ecosystem complexity |
| Vyper |
EVM, limited syntax |
Critical contracts (Curve) |
Compiler stability dependency |
Gas optimization is not premature optimization—it is an architectural decision. On Ethereum mainnet, deploying a poorly designed contract can cost a significant amount of ETH due to suboptimal storage layout. Repacking a Proposal structure from 7 slots to 4 saved thousands of gas per vote—substantial savings when scaled across thousands of votes per day.
Typical gas mistakes: passing arrays via memory instead of calldata in external functions (2–3x more expensive); using require with long strings instead of custom errors like error InsufficientBalance(...). Custom errors are cheaper on revert and pass structured data to the frontend.
Why Smart Contract Audit Is Critical for Security
Audit is not a one-time check—it is a built-in development stage. We use three levels:
-
Static analysis—
Slither (30 seconds in CI) detects reentrancy, uninitialized variables, dangerous delegatecall.
-
Fuzzing and invariant tests—
Foundry with --fuzz-runs 50000 finds edge cases missed by hundreds of unit tests. Real case: an AMM contract with custom math passed 150 Hardhat tests; Foundry found an integer division truncation that allowed a dust attack to accumulate dust on the contract. Echidna checks invariants ("sum of all balances ≤ totalSupply").
-
Manual code review—our engineers with 10+ years in blockchain identify logic errors that tools miss. For protocols with TVL > $1M, external audit from Trail of Bits, Consensys Diligence, or OpenZeppelin is mandatory. Timeline: 2–4 weeks.
Any upgradeable protocol must have a timelock. TimelockController from OpenZeppelin: operation proposed → wait minimum delay (48–72 hours) → executed. Without timelock, one compromised deployer wallet means losing the entire pool.
What Upgrade Patterns Do We Choose?
| Pattern |
Mechanism |
Risk |
When to Use |
Our Experience |
| Transparent Proxy (OZ) |
admin vs user separation |
Storage collision, centralization |
Standard projects |
15+ implementations |
| UUPS |
Upgrade logic in implementation |
Forget _authorizeUpgrade → contract permanently broken |
Gas-optimized projects |
7 projects |
| Diamond (EIP-2535) |
Multiple facets |
Audit complexity |
Large protocols with 10+ contracts |
3 deployments |
| Beacon Proxy |
One beacon for multiple proxies |
Beacon = single point of failure |
Factories of identical contracts |
5 factories |
Storage collision is the main danger of proxies. Implementation v2 must not add variables before existing ones. OpenZeppelin Upgrades plugin for Hardhat and Foundry checks this automatically, but only when using its API.
How to Protect a Contract from MEV and Front-Running
On Ethereum mainnet, transactions in the mempool are visible to all. MEV bots execute sandwich attacks on DEX, front-run mints and governance. Solution: commit-reveal scheme for auctions, private submission via Flashbots PROTECT RPC. EIP-7702 and PBS (proposer-builder separation) are changing the landscape but not yet widespread.
What Is the Development Process?
-
Analysis—functional specification, call diagram, edge case analysis. Without this, coding starts in vain.
-
Development—Solidity/Rust with tests in parallel. Test → code → refactoring. Use Foundry for fuzz and invariant tests.
-
Internal audit—Slither + Echidna + manual code review. Foundry invariant tests for protocol invariants.
-
External audit—for projects with real money. Timeline: 2–4 weeks.
-
Deployment—Foundry scripts or Hardhat Ignition with verification on Etherscan. Gnosis Safe for ownership transfer immediately after deployment.
-
Monitoring—Tenderly alerts, OpenZeppelin Defender, Forta Network.
What Is Included
- Architecture documentation and contract specification (NatSpec).
- Source code with repository and CI (Slither, Foundry, coverage).
- Deployed contract with verification on blockchain explorer.
- Audit results (internal and external upon request).
- Access to monitoring and management (Gnosis Safe).
- Code warranty: critical bug fixes within one month after deployment.
- Consultation on web integration (wagmi, RainbowKit).
Estimated Timelines
- ERC-20 token with basic functions: 1–2 weeks
- Vesting contract with cliff/linear schedule: 2–3 weeks
- NFT ERC-721/1155 with marketplace: 4–6 weeks
- AMM or lending protocol: 2–4 months
- Multichain protocol with bridge: 4–7 months
Audit adds 3–6 weeks and runs in parallel with final testing where possible. Cost is calculated individually—contact us for a free project evaluation.
Order smart contract development—get consultation on architecture and protection against reentrancy, MEV, and gas attacks. Want to discuss details? Write to us—we will select the optimal stack for your task.