TON Masterchain Contracts Formal Verification

CertiKCode version: not recorded (see the report)

CertiK reviewed TON (TON Masterchain Contracts Formal Verification) on 14 Sep 2022: 5 findings, 0 critical; 4 marked fixed, 1 open.

No open critical findings
Open the reportOpen TON’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings5

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High000
Medium001
Low103
MediumPortion of bid above `max_stake` silently discardFixed

The function `process_new_stake` has a test that the submitted stake is larger than `min_stake`. ```func if (msg_value < min_stake) { ;; stake too small, return it return return_stake(s_addr, query_id, 5); } ``` However, nothing prevents a user from submitting a bid larger that `max_stake`. The function `try_elect` will then restrict the bid to be less than `max_stake`: ```func var (stake, _, pubkey) = (min(key~load_uint(128), max_stake), key~load_uint(32), key.preload_uint(256)); ``` If the user submitted more than `max_stake`, then at this point the contract will forget about the excess part, which will become unretrievably locked in the contract balance. Note that `max_stake` is a configuration parameter which can be changed at any time by the owner of the config contract. This makes the situation potentially more error prone, because such a change could happen between the user's bid submission and the next election. So if the limit was lowered, the user could submit a bid which was valid at the time time of submission but triggered this bug at the time of election.

LowNo check for existing key in `annouce_new_electioFixed

The `conduct_elections` function computes the next validator set and then stores it in the `past_elect` dictionary. The key it is stored under is the `elect_at` field, the time at which the election takes place. If there somehow was already a past validator set stored under the same key, the past set would be overwritten and all the stakes in it lost. The `elect_at` field is chosen in `announce_new_elections` to be a time in the future (`now() + elect_begin_before`), so intuitively it will be distinct from other election times in the past. However, there is some extra logic that can move it to a slightly earlier time ("pretend that the elections started at t0"). Exactly which time `t0` would be depends on configuration parameters which are set and changed outside the elector contract, which makes it hard to formally prove that there can never be a clash. The likelihood of this going wrong may seem remote, but another check would make the contract more self-contained.

LowNot deducting message cost in `conduct_elections`Fixed

There are two cases in the elector contract when it sends a message and includes approximately 1 Gram of value in order to pay for the message processing costs. These are in `process_new_stake` (the call to `send_confirmation`) and in `conduct_elections` (the call to `send_validator_set_to_config`). In `process_new_stake` this cost is deducted from the posted stake, so that the accounting is correct: ```func msg_value -= 1000000000; ;; deduct GR$1 for sending confirmation ``` However, there is no logic in `conduct_elections` which explains where the value of the message should be deducted from, which breaks the invariant that data structures reflect the current balance of the contract.

LowUnused function argument in `announce_new_electioFixed

The function `announce_new_elections` takes an argument `elect` despite declaring a local variable with the same name which is used in the function body. The argument is redundant.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Part of TON’s security record

TON
Audits6 audits by 2 firmsLast audit Mar 2024, by Trail of Bits.
Critical findingsNo open critical findingsAcross 6 reports.
Open TON’s security record

Security firm

CertiK

1,045 projects reviewed · 1,376 reports · latest May 2025

See CertiK’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us