Request an Audit
Back
  • 07/19/2024

Security risk analysis of FunC language in TON blockchain smart contracts

Preface

On the TON blockchain, the development of smart contracts usually uses FunC and Tact languages. However, while there are many tools that provide developers with powerful capabilities, they also introduce a variety of security risks and vulnerabilities. These problems may not only result in loss of funds, but may also disrupt the normal operation of the contract. This article will analyze in detail the various risk issues that may be encountered when using the FunC language on the TON blockchain to help developers better write safe and reliable smart contracts.

Basic vulnerability

  1. Risks of Partial Execution of Transactions

Risk statement:

The TON blockchain uses sharding technology to improve the efficiency and scalability of transaction processing. However, this also introduces new security risks. Since transactions are processed in parallel in different shards, the execution of partial transactions may lead to state inconsistencies or cross-shard attacks. Especially in smart contracts, shard execution may cause some transactions to succeed in one shard but fail in another shard. If the contract encounters an exception during execution or runs out of gas, some transaction steps may fail. Completed, resulting in inconsistent contract status and loss of funds, causing serious security issues.

FunC Code example:

During a Jetton token transfer process, if the recipient wallet (destination_wallet) cannot process the internal transfer message (op::internal_transfer), the balance of the sender wallet (sender_wallet) will decrease, but the balance of the recipient wallet will not increase. Leading to inconsistent Jetton status and potential loss of funds. In the worst case scenario, all tokens could be stolen this way.

Safety advice:

Implement a cross-shard transaction mechanism to ensure that operations in multiple shards either all succeed or fail to maintain consistency; perform status synchronization after key operations to ensure data consistency between all shards; perform key operations after key operations Conduct sufficient error checks beforehand and handle possible exceptions to ensure that the contract can roll back or take appropriate measures when encountering errors; ensure that gas consumption is checked and managed before performing important operations to prevent transactions caused by insufficient gas. Interrupt.

  1. transaction order dependency

Risk statement:

The transaction ordering dependency problem means that the behavior of smart contracts depends on the execution order of transactions, which may lead to race conditions or inconsistent states.

FunC code example:

This code implements a simple auction function where users can place bids by calling the placeBid function. If the new bid bidAmount is higher than the current highest bid highestBid, the contract refunds the previous highest bidder’s amount and updates the highest bid and highest bidder.

Validators can choose to process lower bids first and then higher bids, thereby ensuring that a specific bidder becomes the highest bidder. In this way, the validator’s bid ensures that it will win the auction.

Security advice: Avoid designing logic that relies on the order of transactions, or ensure that the order of transactions is controlled through a locking mechanism (such as a time lock or other state lock).

  1. timestamp dependency

Risk statement:

Timestamp dependency risk means that the behavior of smart contracts depends on block timestamps, which may be manipulated by validators. For example, validators can selectively include or exclude certain transactions, or adjust timestamps to serve certain purposes. This behavior may cause the contract logic to be manipulated, causing security risks.

FunC code example:

In this example code, the contract logic relies on the current block timestamp. If miners can manipulate timestamps, they may trigger or block specific operations at inappropriate times, thereby manipulating contract behavior.

Safety advice:

Try to avoid directly relying on timestamps to make key logical judgments in the contract. If timestamps must be used, make sure to use a more reliable and uncontrollable method; use a time buffer mechanism to allow time changes within a certain range and reduce dependence on a single point in time.

  1. Integer overflow/underflow

Risk statement:

Integer overflow and underflow are exponential value operations that exceed the representation range of the variable, resulting in incorrect calculation results. Integer overflow usually occurs in operations such as addition, subtraction, and multiplication. If left unchecked, it may lead to serious security issues, such as incorrect balance calculations or unexpected fund transfers.

FunC code example:

The code in this example may overflow when calculating the new balance, for example when the sum of balance and myParam exceeds the maximum value of the integer type.

Safety advice:

Use a safe arithmetic library; check that results are within reasonable limits before and after performing critical numerical operations.

  1. rounding error

Risk statement:

The risk of rounding errors refers to errors in calculation results due to precision limitations or improper rounding methods in numerical operations. Especially when dealing with currencies or high-precision numerical values, rounding errors can lead to loss of funds or unfair distribution.

FunC code example

The code in this example may produce inaccurate results due to rounding of integer division when performing multiplication and division operations. For example, the result of 3 / 2 is 1 in integer arithmetic, not 1.5.

Safety advice:

Avoid using floating point numbers and use fixed-point representation for high-precision numerical operations.

  1. Denial of service

Risk statement:

Denial of service risk refers to consuming the computing resources of smart contracts or triggering error conditions, causing the contract to fail to execute normally or fall into endless operations. This may prevent legitimate users from interacting with the contract, or even prevent the contract’s status from being updated.

FunC code example

The code in this example performs computationally intensive operations in a loop. If myParam is very large, it will cause the contract to consume a lot of computing resources, and may even exceed the Gas limit, causing the transaction to fail or the contract to fall into endless operations.

Safety advice:

Limit the number of loops or recursion depth to avoid long-running operations; check remaining Gas before key operations to avoid transaction failure due to insufficient Gas; use efficient algorithms and data structures to reduce computing resource consumption.

  1. Access control

Risk statement:

Access control risk means that certain sensitive operations in smart contracts do not properly restrict calling permissions, resulting in unauthorized users being able to perform these operations. This may lead to the contract being maliciously manipulated, funds stolen, or the contract logic being destroyed.

FunC code example:

The code in this example does not authenticate the caller, anyone can call the function and set a new balance.

Safety advice:

Implement a permission management mechanism, such as only allowing specific addresses to call certain functions; define different roles and assign different permissions to each role.

  1. centralization of power

Risk statement:

The risk of centralization of authority means that certain key operational powers in smart contracts are too concentrated in the hands of a single or a few accounts. When these accounts are maliciously attacked or abuse their authority, the security and fairness of the entire contract are threatened. This centralization makes the contract lack the advantages of decentralization and increases the risk of single points of failure and malicious behavior.

FunC code example:

The code in this example concentrates all power on one account of the contract owner, and there is a greater risk of centralization of authority.

Safety advice:

Require multiple authorized parties to co-sign transactions to reduce the risk of single points of failure; assign different permissions to different roles and accounts to avoid excessive concentration of power; introduce a community voting mechanism to allow community members to jointly decide on important operations.

  1. Business logic

Risk statement:

Business logic vulnerabilities refer to design flaws or implementation errors in smart contracts when implementing their business processes, causing the contract to behave unexpectedly under certain circumstances. These vulnerabilities may be exploited by malicious users, leading to serious consequences such as loss of funds, data tampering, or contract function failure. Business logic vulnerabilities are usually not coding errors, but misunderstandings or imperfect implementations of business requirements and processes.

FunC code example

The code in this example has multiple business logic vulnerabilities. For example, the transfer operation does not check the legitimacy of the recipient, which may cause funds to be transferred to invalid addresses or malicious addresses.

Safety advice:

Ensure that the contract logic is clear and clear, avoiding confusing and repetitive logic; strictly verify all input parameters to ensure their legality and correctness; regularly audit the business logic to ensure that it meets business needs and security requirements; add detailed comments to the code and documentation to aid understanding and maintenance.

  1. Gas usage

Risk statement:

The risks of using Gas are the following situations in the TON blockchain:

1. Smart contracts consume too much computing resources (Gas) during execution, resulting in transaction failure or excessive fees; this risk may cause the contract to fail to execute normally under high load, or due to exceeding the Gas upper limit set by the user. was aborted. Especially in complex operations or loops, unoptimized code can cause serious gas consumption problems.

2. If there is not enough gas, the transaction will be partially executed.

3. If there is too much Gas and the contract does not return the excess Gas, funds will accumulate in the contract over time.

FunC code example:

This code has high gas consumption and partial execution risk. Due to the number of loops and operation complexity, it may consume a large amount of gas or cause the transaction to fail.

Safety advice:

1. Use efficient algorithms and data structures to reduce unnecessary calculation and storage operations and improve efficiency;

2. Check the remaining Gas before critical operations to ensure that there is enough Gas to complete the operation to avoid transaction failure due to Gas exhaustion.

3. Return excess Gas after the transaction is completed to avoid funds accumulating in the contract.

4. Decompose complex operations into multiple smaller steps and complete them through multiple transactions to avoid consuming too much Gas in a single transaction.

  1. storage

Risk statement:

In TON blockchain smart contract development, storage management is an important consideration. Improperly managed storage can lead to several risks, including code that is difficult to maintain, potential security holes, and unnecessary gas consumption.

Difficulty in code maintenance: If there are a large number of storage fields in a smart contract, the load_data() and save_data() functions need to be updated every time a field needs to be modified or added. This not only increases the workload, but also easily introduces errors.

Namespace pollution: If a storage field and a local variable have the same name, it may cause the storage field to be obscured by the local variable, which may lead to unexpected state changes or security vulnerabilities.

High Gas consumption: Parsing the entire storage and repackaging all data every time a function is called will increase Gas consumption and reduce the operating efficiency of the contract.

FunC Code example:

There are a large number of storage fields in smart contracts. Every time a field needs to be modified or added, the load_data() and save_data() functions need to be updated. This not only increases the workload, but also easily introduces errors.

Safety advice:

Use global variables for rapid development during the prototyping stage, but the number of global variables is limited and you should switch to nested storage mode. Flexibly switch between global variables and nested storage as needed to ensure development efficiency and contract performance.

  1. Unchecked return value

Risk statement:

The unchecked return value vulnerability means that the smart contract does not check the return value of the external function or contract call when processing the transaction request, which may lead to unexpected behavior or errors that are not caught. Especially when processing requests with values, if the request cannot be executed (for example, due to insufficient Gas) and the return value is not processed correctly, it may be exploited by attackers, resulting in contract logic failure, fund loss, or data tampering.

FunC code example:

The return value of the operation was not checked when processing the request. If the operation fails, funds may be lost and refunded funds are sent to jettonA_wallet_address instead of sender_address. An attacker can forge messages, causing Jetton to be incorrectly returned, resulting in loss of funds.

() handle_transfer_notification(...) impure {

    ...

    int jetton_amount = in_msg_body~load_coins();

    slice from_address = in_msg_body~load_msg_addr();

    slice from_jetton_address = in_msg_body~load_msg_addr();

    if (msg_value < gas_consumption) { ;; not enough gas provided

        if (equal_slices(from_jetton_address, jettonA_address)) {

            var msg = begin_cell()

                .store_uint(0x18, 6)

                .store_slice(jettonA_wallet_address)

                .store_coins(0)

                .store_uint(1, 1 + 4 + 4 + 64 + 32 + 1 + 1)

            ...

        }

    ...

}

Safety advice:

Every time you call an external function or contract, check whether the return value is as expected, and handle it accordingly; when processing a transaction request, always check the return value of the external call to ensure the operation is successful; always return Jetton to the sender address, rather than a fixed address, to avoid forged message attacks.

Vulnerabilities in the DeFi scene

The order of passing parameters is incorrect

The incoming parameters can be controlled to cause unexpected logic in contract execution.

Correctness of message format not verified

Insufficient rewards

The message cannot be called normally

Unexpected transfer of funds due to unsatisfied payload

Transaction fees or rewards cannot be withdrawn

Reward or fee calculation errors

Global variables are not updated in time

Return data error

Preemptive initialization

Uncalculated Gas consumption

Pledged funds can be stolen

Vulnerabilities in the Token scenario

Fee calculation error

Arbitrary Mint Risk

Centralization risk

Multisig can be controlled by one address

Balance calculation error

Gas calculation error

Summarize

Through the analysis and examples of this article, we can see the various security risks that smart contracts on the TON blockchain may face, including partial execution of transactions, transaction ordering dependence, timestamp dependence, integer overflow/underflow, rounding errors, rejection Services, access control vulnerabilities, permission centralization risks, business logic vulnerabilities, Gas usage issues, storage management issues, and unchecked return value vulnerabilities. In order to ensure the security and reliability of contracts, developers should strictly follow best practices, conduct comprehensive security audits and testing, and consider all potential risks when designing and implementing contracts. Protect users’ assets to the greatest extent and improve the security and user experience of blockchain applications.