> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ton.org/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.ton.org/feedback

```json
{
  "path": "/foundations/system",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# System contracts

export const Aside = ({type = "note", title = "", icon = "", iconType = "regular", children}) => {
  const asideVariants = ["note", "tip", "caution", "danger"];
  const asideComponents = {
    note: {
      outerStyle: "border-sky-500/20 bg-sky-50/50 dark:border-sky-500/30 dark:bg-sky-500/10",
      innerStyle: "text-sky-900 dark:text-sky-200",
      calloutType: "note",
      icon: <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-sky-500" aria-label="Note">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M7 1.3C10.14 1.3 12.7 3.86 12.7 7C12.7 10.14 10.14 12.7 7 12.7C5.48908 12.6974 4.0408 12.096 2.97241 11.0276C1.90403 9.9592 1.30264 8.51092 1.3 7C1.3 3.86 3.86 1.3 7 1.3ZM7 0C3.14 0 0 3.14 0 7C0 10.86 3.14 14 7 14C10.86 14 14 10.86 14 7C14 3.14 10.86 0 7 0ZM8 3H6V8H8V3ZM8 9H6V11H8V9Z"></path>
        </svg>
    },
    tip: {
      outerStyle: "border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10",
      innerStyle: "text-emerald-900 dark:text-emerald-200",
      calloutType: "tip",
      icon: <svg width="11" height="14" viewBox="0 0 11 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="text-emerald-600 dark:text-emerald-400/80 w-3.5 h-auto" aria-label="Tip">
          <path d="M3.12794 12.4232C3.12794 12.5954 3.1776 12.7634 3.27244 12.907L3.74114 13.6095C3.88471 13.8248 4.21067 14 4.46964 14H6.15606C6.41415 14 6.74017 13.825 6.88373 13.6095L7.3508 12.9073C7.43114 12.7859 7.49705 12.569 7.49705 12.4232L7.50055 11.3513H3.12521L3.12794 12.4232ZM5.31288 0C2.52414 0.00875889 0.5 2.26889 0.5 4.78826C0.5 6.00188 0.949566 7.10829 1.69119 7.95492C2.14321 8.47011 2.84901 9.54727 3.11919 10.4557C3.12005 10.4625 3.12175 10.4698 3.12261 10.4771H7.50342C7.50427 10.4698 7.50598 10.463 7.50684 10.4557C7.77688 9.54727 8.48281 8.47011 8.93484 7.95492C9.67728 7.13181 10.1258 6.02703 10.1258 4.78826C10.1258 2.15486 7.9709 0.000106649 5.31288 0ZM7.94902 7.11267C7.52078 7.60079 6.99082 8.37878 6.6077 9.18794H4.02051C3.63739 8.37878 3.10743 7.60079 2.67947 7.11294C2.11997 6.47551 1.8126 5.63599 1.8126 4.78826C1.8126 3.09829 3.12794 1.31944 5.28827 1.3126C7.2435 1.3126 8.81315 2.88226 8.81315 4.78826C8.81315 5.63599 8.50688 6.47551 7.94902 7.11267ZM4.87534 2.18767C3.66939 2.18767 2.68767 3.16939 2.68767 4.37534C2.68767 4.61719 2.88336 4.81288 3.12521 4.81288C3.36705 4.81288 3.56274 4.61599 3.56274 4.37534C3.56274 3.6515 4.1515 3.06274 4.87534 3.06274C5.11719 3.06274 5.31288 2.86727 5.31288 2.62548C5.31288 2.38369 5.11599 2.18767 4.87534 2.18767Z"></path>
        </svg>
    },
    caution: {
      outerStyle: "border-amber-500/20 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-500/10",
      innerStyle: "text-amber-900 dark:text-amber-200",
      calloutType: "warning",
      icon: <svg className="flex-none w-5 h-5 text-amber-400 dark:text-amber-300/80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-label="Warning">
          <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
        </svg>
    },
    danger: {
      outerStyle: "border-red-500/20 bg-red-50/50 dark:border-red-500/30 dark:bg-red-500/10",
      innerStyle: "text-red-900 dark:text-red-200",
      calloutType: "danger",
      icon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" className="text-red-600 dark:text-red-400/80 w-4 h-4" aria-label="Danger">
          <path d="M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zm41.6-48c-4.3 7.4-4.3 16.6 0 24l88.3 152.9c4.3 7.4 12.2 12 20.8 12l176.6 0c8.6 0 16.5-4.6 20.8-12L453.4 268c4.3-7.4 4.3-16.6 0-24L365.1 91.1c-4.3-7.4-12.2-12-20.8-12l-176.6 0c-8.6 0-16.5 4.6-20.8 12L58.6 244zM256 128c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"></path>
        </svg>
    }
  };
  let variant = type;
  let gotInvalidVariant = false;
  if (!asideVariants.includes(type)) {
    gotInvalidVariant = true;
    variant = "danger";
  }
  const iconVariants = ["regular", "solid", "light", "thin", "sharp-solid", "duotone", "brands"];
  if (!iconVariants.includes(iconType)) {
    iconType = "regular";
  }
  return <>
      <div className={`callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border ${asideComponents[variant].outerStyle}`} data-callout-type={asideComponents[variant].calloutType}>
        <div className="mt-0.5 w-4" data-component-part="callout-icon">
          {}
          {icon === "" ? asideComponents[variant].icon : <Icon icon={icon} iconType={iconType} size={14} />}
        </div>
        <div className={`text-sm prose min-w-0 w-full ${asideComponents[variant].innerStyle}`} data-component-part="callout-content">
          {gotInvalidVariant ? <p>
              <span className="font-bold">
                Invalid <code>type</code> passed!
              </span>
              <br />
              <span className="font-bold">Received: </span>
              {type}
              <br />
              <span className="font-bold">Expected one of: </span>
              {asideVariants.join(", ")}
            </p> : <>
              {title && <p className="font-bold">{title}</p>}
              {children}
            </>}
        </div>
      </div>
    </>;
};

<Aside>
  These are low-level TON Blockchain internals. You typically do not need to write or deploy these contracts.
</Aside>

<Aside>
  System contracts are smart contracts and have on‑chain addresses. See [config parameters 1–4](https://tonviewer.com/config). The Config account stores the Config contract address. To track changes, review proposals to the Config contract.
</Aside>

In TON, a set of special smart contracts controls consensus parameters for node operation — including TVM, catchain, fees, and chain topology — and how these parameters are stored and updated. Unlike older blockchains that hardcode these parameters, TON enables transparent on‑chain governance. The current governance contracts include the **Elector** and **Config** contracts, with expansion plans (for example, the extra‑currency **Minter**).

## Elector

The **Elector** smart contract manages validator elections, validation rounds, and reward distribution. To become a validator and interact with the Elector, follow the [validator instructions](https://ton.org/validator).

### Data storage

The Elector stores:

* Non-withdrawn Toncoin in the `credits` hashmap.
* New validator applications in the `elect` hashmap.
* Past election data in the `past_elections` hashmap (including complaints and `frozen` stakes held for `stake_held_for` periods, defined in [**ConfigParam 15**](https://tonviewer.com/config#15)).

### Key functions

1. **Process validator applications**
2. **Conduct elections**
3. **Handle validator misbehavior reports**
4. **Distribute validation rewards**

#### Processing applications

To apply, a validator must:

1. Send a message to the Elector with their Abstract Datagram Network Layer (ADNL) address, public key, `max_factor`, and stake (TON amount).
2. The Elector validates the parameters and either registers the application or refunds the stake.
   *Note:* Only masterchain addresses can apply.

### Conducting elections

The Elector is a special smart contract triggered by **Tick and Tock transactions** (forced executions at the start and end of each block). It checks whether it’s time to conduct a new election during each block.

**Process details:**

* Take applications with stake ≥ `min_stake` ([**ConfigParam 17**](https://tonviewer.com/config#17)).
* Arrange candidates by stake in descending order.
* If applicants exceed `max_validators` ([**ConfigParam 16**](https://tonviewer.com/config#16)), discard the lowest-staked candidates.
* For each subset size `i` (from 1 to remaining candidates):
* Assume the `i`-th candidate (lowest in the subset) defines the baseline.
* Calculate effective stake (`true_stake`) for each `j`-th candidate (`j < i`) as:

```python not runnable theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
min(stake[i] * max_factor[j], stake[j])
```

* Track the subset with the highest **total effective stake (TES)**.
* Submit the winning validator set to the **Config** contract.
* Return unused stakes and excess amounts (e.g., `stake[j] - min(stake[i] * max_factor[j], stake[j])`) to `credits`.

**Example breakdown**:

* **Case 1**: 9 candidates stake 100,000 TON (`max_factor=2.7`), 1 candidate stakes 10,000.

* *Without the 10,000-stake candidate*: TES = 900,000.

* *With the 10,000-stake candidate*: TES = 9 \* 27,000 + 10,000 = 253,000.

* **Result**: 10,000-stake candidate are excluded.

* **Case 2**: 1 candidate stakes 100,000-stake (`max_factor=2.7`), 9 stake 10,000.

* Effective stake for the 100,000-stake candidate: `10,000 * 2.7 = 27,000`.

* Excess: `100,000 - 27,000 = 73,000` → sent to `credits`.

* **Result**: All 10 participate.

**Election constraints**:

* `min_validators` ≤ participants ≤ `max_validators` (**ConfigParam 16**).
* Stakes must satisfy:
* `min_stake` ≤ stake ≤ `max_stake`
* `min_total_stake` ≤ total stake ≤ `max_total_stake`
* Stake ratios ≤ `max_stake_factor` (**ConfigParam 17**).
* If conditions aren’t met, elections are **postponed**.

### Report validator misbehavior

Each validator is periodically assigned the duty to create new blocks, with the frequency of assignments determined by their weight. After a validation round, anyone can audit the blocks to check whether the actual number of blocks produced by a validator significantly deviates from the expected number (based on their weight). A statistically significant underperformance (e.g., fewer blocks created than expected) constitutes misbehavior.

To report misbehavior, a user must:

1. Generate a **Merkle proof** demonstrating the validator's failure to produce the expected blocks.
2. Propose a fine proportional to the severity of the offense.
3. Submit the proof and fine proposal to the Elector contract, covering the associated storage costs.

The Elector registers the complaint in the `past_elections` hashmap. Current round validators then verify the complaint. If the proof is valid and the proposed fine aligns with the severity of the misbehavior, validators vote on the complaint. Approval requires agreement from over **two-thirds of the total validator weight** (not just a majority of participants).

The fine is deducted from the validator's `frozen` stake in the relevant `past_elections` record if approved. These funds stay locked for the period defined by [**ConfigParam 15**](https://tonviewer.com/config#15) (`stake_held_for`).

#### Distributing rewards

The Elector releases `frozen` stakes and rewards (gas fees plus block rewards) proportionally to past validators. Funds move to `credits`, and the election record clears from `past_elections`.

## Config

The **Config** contract manages TON’s configuration parameters, validator set updates, and proposal voting.

### Validator set updates

1. The **Elector** notifies **Config** of a new validator set.
2. **Config** stores it in `ConfigParam 36` (*next validators*).
3. At the scheduled time (`utime_since`), **Config**:

* Moves the old set to `ConfigParam 32` (*previous validators*).
* Promotes `ConfigParam 36` to `ConfigParam 34` (*current validators*).

### Proposal/voting mechanism

1. **Submit a proposal**: Pay storage fees to propose parameter changes.
2. **Vote**: Validators (from **ConfigParam 34**) sign approval messages.
3. **Outcome**:

* **Approved**: After `min_wins` rounds (**ConfigParam 11**) with ≥3/4 weighted votes.
* **Rejected**: After `max_losses` rounds.
* *Critical parameters* (**ConfigParam 10**) require more rounds.

#### Emergency updates

* Reserved indexes (`-999`, `-1000`, `-1001`) allow urgent updates to **Config**/**Elector** code.
* A temporary emergency key (assigned to the TON Foundation in 2021) accelerated fixes but couldn't alter contracts.
* **Key retired** on Nov 22, 2023 (**block 34312810**), replaced with zeros.
* Later patched to a fixed byte sequence (`sha256("Not a valid curve point")`) to prevent exploits.

**Historical uses**:

* **Apr 2022**: Increased gas limits (**blocks 19880281/19880300**) to unblock elections.
* **Mar 2023**: Raised `special_gas_limit` to 25M (**block 27747086**) for election throughput.
