Skip to content

Commit

Permalink
feat(docs): Release 0.6
Browse files Browse the repository at this point in the history
  • Loading branch information
jubnzv committed Dec 22, 2024
1 parent 8ef0421 commit 2cd3ca9
Show file tree
Hide file tree
Showing 48 changed files with 2,176 additions and 0 deletions.
45 changes: 45 additions & 0 deletions versioned_docs/version-0.6/detectors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
id: detectors
title: Detectors Overview
---

# Detectors Overview

## Built-in Detectors

| # | Detector | Severity | Requires Soufflé | Enabled by default |
|----|-----------|-----------|--------------------|---------------------|
| 1 | [ArgCopyMutation](./detectors/ArgCopyMutation.md) | High | ||
| 2 | [AsmIsUsed](./detectors/AsmIsUsed.md) | Info | | |
| 3 | [BranchDuplicate](./detectors/BranchDuplicate.md) | High | ||
| 4 | [CellBounds](./detectors/CellBounds.md) | Critical | ||
| 5 | [ConstantAddress](./detectors/ConstantAddress.md) | Info | | |
| 6 | [DivideBeforeMultiply](./detectors/DivideBeforeMultiply.md) | High |||
| 7 | [DumpIsUsed](./detectors/DumpIsUsed.md) | Info | | |
| 8 | [DuplicatedCondition](./detectors/DuplicatedCondition.md) | High | ||
| 9 | [EnsurePrgSeed](./detectors/EnsurePrgSeed.md) | Medium | ||
| 10 | [EtaLikeSimplifications](./detectors/EtaLikeSimplifications.md) | Low | ||
| 11 | [ExitCodeUsage](./detectors/ExitCodeUsage.md) | High | ||
| 12 | [FalseCondition](./detectors/FalseCondition.md) | Medium | ||
| 13 | [FieldDoubleInit](./detectors/FieldDoubleInit.md) | Medium | ||
| 14 | [InheritedStateMutation](./detectors/InheritedStateMutation.md) | Low | | |
| 15 | [NeverAccessedVariables](./detectors/NeverAccessedVariables.md) | Medium | ||
| 16 | [OptimalMathFunction](./detectors/OptimalMathFunction.md) | Low | ||
| 17 | [PreferAugmentedAssign](./detectors/PreferAugmentedAssign.md) | Info | ||
| 18 | [PreferredStdlibApi](./detectors/PreferredStdlibApi.md) | Info | | |
| 19 | [ReadOnlyVariables](./detectors/ReadOnlyVariables.md) | Medium |||
| 20 | [SendInLoop](./detectors/SendInLoop.md) | Medium | | |
| 21 | [ShortCircuitCondition](./detectors/ShortCircuitCondition.md) | Low | ||
| 22 | [StringReceiversOverlap](./detectors/StringReceiversOverlap.md) | High | ||
| 23 | [SuspiciousMessageMode](./detectors/SuspiciousMessageMode.md) | Medium | ||
| 24 | [UnboundLoop](./detectors/UnboundLoop.md) | High |||
| 25 | [UnboundMap](./detectors/UnboundMap.md) | Low | | |
| 26 | [UnusedExpressionResult](./detectors/UnusedExpressionResult.md) | Medium | ||
| 27 | [UnusedOptional](./detectors/UnusedOptional.md) | Low | ||
| 28 | [ZeroAddress](./detectors/ZeroAddress.md) | Low | ||

Some of the detectors require [Soufflé](https://souffle-lang.github.io/install) to be installed. If no Soufflé installation is found, these detectors won't be executed.

A few detectors are optional and aimed at auditors to help uncover subtle issues in the source code. To enable all detectors, use the `--all-detectors` option. You can find a full list of configuration options on the [configuration page](./tutorial/configuration.md).

Each detector targets a specific type of problem in your code. Click on the detector name to learn more.
33 changes: 33 additions & 0 deletions versioned_docs/version-0.6/detectors/ArgCopyMutation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# ArgCopyMutation
A detector that highlights cases where function argument mutations are ineffective
due to [call-by-value semantics](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_value) in Tact.

## Why is it bad?
In Tact, function arguments are passed by value, meaning that any mutations applied
to these arguments will only affect the local copy of the variable within the function.
Such mutations are unobservable outside the function, except for potentially
increasing gas consumption or causing exceptions.

## Example
```tact
fun addEntry(m: map<Int,Int>) {
m.set(1, 10); // Bad: Mutating the copy
}
```

Use instead:
```tact
fun addEntry() {
self.m.set(1, 10); // OK: Changing contract's state
}
```

Alternatively, you could redesign the method:
```tact
fun generateNewValue(): Int {
// ... produce new value for the map
return self.nextValue + 1;
}
m.set(self.nextKey, self.generateNewValue()); // OK
```
13 changes: 13 additions & 0 deletions versioned_docs/version-0.6/detectors/AsmIsUsed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# AsmIsUsed
An optional detector that highlights all the `asm` functions.

## Why is it bad?
Using TVM Assembly is a potentially dangerous operation that requires additional
attention from an auditor. This optional detector will highlight all its uses to
assist in contract security audits.

## Example
```tact
// Highlighted: the asm function use should be audited
asm fun getStorageFee(cells: Int, bits: Int, seconds: Int, is_masterchain: Bool): Int { GETSTORAGEFEE }
```
26 changes: 26 additions & 0 deletions versioned_docs/version-0.6/detectors/BranchDuplicate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# BranchDuplicate
Detector that reports duplicated code in conditional branches.

## Why is it bad?
Duplicated code in branches is bad because it:
1. **Reduces Readability**: Repetition makes the code harder to understand.
2. **Increases Maintenance**: Changes must be made in multiple places, risking errors.
3. **Signals Poor Design**: It suggests missed opportunities for cleaner, more abstract code.

## Example
```tact
if (a > 42) {
a = 43; // bad: duplicated code
} else {
a = 43;
}
```

Use instead:
```tact
if (a > 42) {
a = inc(b); // ok
} else {
a = 43;
}
```
46 changes: 46 additions & 0 deletions versioned_docs/version-0.6/detectors/CellBounds.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# CellBounds
A detector that identifies cell overflow and underflow problems.

## Why is it bad?
Cell overflow and underflow are issues specific to the TON blockchain. TON
stores data in cells, which are low-level data structures used for serialization
and deserialization.

The overflow issue occurs when the user attempts to store more data in a cell
than it supports. The current limitation is 1023 bits and 4 references to other
cells. When these limits are exceeded, the contract throws an error with the
exit code `8` during the compute phase.

The underflow issue occurs when the user attempts to get more data from a
structure than it supports. cells. When it happens, the contract throws an
error with the exit code `9` during the compute phase.

## Example
```tact
// Bad: storeRef is used more than 4 times
beginCell()
.storeRef(...)
.storeAddress(myAddress())
.storeRef(...)
.storeRef(...)
.storeRef(...)
.storeRef(...)
.endCell()
```

Use instead:
```tact
// OK: Fixed after the analyzer highlighted it
beginCell()
.storeRef(...)
.storeAddress(myAddress())
.storeRef(...)
.storeRef(...)
.storeRef(...)
.endCell()
```

## Resources
1. [Cell & Bag of Cells (BoC) | TON Docs](https://docs.ton.org/develop/data-formats/cell-boc)
2. [TVM Exit codes | TON Docs](https://docs.ton.org/learn/tvm-instructions/tvm-exit-codes)
3. [Cells, Builders and Slices | Tact Docs](https://docs.tact-lang.org/ref/core-cells/)
31 changes: 31 additions & 0 deletions versioned_docs/version-0.6/detectors/ConstantAddress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# ConstantAddress
An optional detector that highlights all the constant addresses appearing in the source code.

## Why is it bad?
Using hardcoded addresses can sometimes indicate poor contract design.
Some constant addresses may need to be set dynamically, e.g., using
`contractAddress`, or at least have a way to change them at runtime, for
example, when upgrading a contract.

## Example
```tact
contract Main {
proxy: Address;
init() {
// Bad: Constant address highlighted by the analyzer.
self.proxy = address("UQBKgXCNLPexWhs2L79kiARR1phGH1LwXxRbNsCFF9doczSI");
}
}
```

Use instead:
```tact
contract Main {
proxy: Address;
init() {
let proxy: Proxy = initOf Proxy(myAddress());
// OK: Address depends on how the proxy contact has been deployed
self.proxy = contractAddress(proxy);
}
}
```
27 changes: 27 additions & 0 deletions versioned_docs/version-0.6/detectors/DivideBeforeMultiply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# DivideBeforeMultiply
A detector that identifies and corrects instances of division before multiplication to
ensure accurate mathematical operations.

## Why is it bad?
Performing division before multiplication can lead to unexpected results due to precision loss and rounding errors:
* **Precision Loss:** Dividing first can result in significant precision loss, especially when dealing with integers or fixed-point numbers.
* **Rounding Errors:** Early division might cause rounding errors that propagate through subsequent calculations.
* **Unexpected Behavior:** Incorrectly ordered operations can lead to incorrect outcomes, making debugging and maintenance more challenging.

## Example
```tact
let a: Int = 10;
let b: Int = 3;
let c: Int = 2;
// Bad: Division before multiplication
let result: Int = a / b * c;
```

Use instead:
```tact
let a: Int = 10;
let b: Int = 3;
let c: Int = 2;
// Correct: Multiplication before division
let result: Int = a * c / b;
```
27 changes: 27 additions & 0 deletions versioned_docs/version-0.6/detectors/DumpIsUsed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# DumpIsUsed
An optional detector that highlights all the `dump` debug prints.

## Why is it bad?
The `dump` function is a debug print that shouldn't be in the final code.
Even though the compiler removes it in production, its presence suggests the
developer was debugging something. This can flag areas where issues might exist,
so auditors should take a closer look at these parts of the code.

## Example
```tact
fun test(): Int {
// ... other computations
let combined: Int = (RANDOM_SEED >> half_shift) &
(MAGIC_CONSTANT << DIVIDE_BY_TWO) ^ shift_mask;
dump(combined); // Suspicious: Highlighted by the detector
}
```

Use instead:
```tact
fun test(): Int {
// ... other computations
let combined: Int = this.seed ^ shift_mask
// OK: The code was reviewed and simplified; `dump` was removed
}
```
28 changes: 28 additions & 0 deletions versioned_docs/version-0.6/detectors/DuplicatedCondition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# DuplicatedCondition
A detector that finds duplicated conditions appearing in conditional expressions.

## Why is it bad?
Typically, these cases are developer errors caused by copy-pasting code, leading
to unreachable code.

## Example
```tact
fun test(a: Int): Int {
if (a < 1) { return 1; }
else if (a > 4) { return 2; }
// Bad: A developer copy-pasted the condition
else if (a > 4) { return 3; }
return 4;
}
```

Use instead:
```tact
fun test(a: Int): Int {
if (a < 1) { return 1; }
else if (a > 4) { return 2; }
// OK: Fixed
else if (a < x) { return 3; }
return 4;
}
```
29 changes: 29 additions & 0 deletions versioned_docs/version-0.6/detectors/EnsurePrgSeed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# EnsurePrgSeed
A detector that identifies all calls to `nativeRandom` and `nativeRandomInterval`
without a preceding PRG seed initialization.

## Why is it bad?
Using `nativeRandom` or `nativeRandomInterval` without first initializing the PRG seed via
`nativePrepareRandom`, `nativeRandomize`, or `nativeRandomizeLt` may lead to unintended behavior
or weak random number generation. This detector ensures that PRG seed initialization
is always performed before any use of random functions, enhancing contract security.

## Example
```tact
// Bad: `nativeRandom` is used without prior PRG seed initialization
fun generateRandomValue(): Int {
return nativeRandom()
}
```

Use instead:
```tact
fun test(): Int {
nativePrepareRandom();
}
// OK: PRG has been initialized somewhere in the contract
fun generateRandomValue(): Int {
return nativeRandom()
}
```
34 changes: 34 additions & 0 deletions versioned_docs/version-0.6/detectors/EtaLikeSimplifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# EtaLikeSimplifications
Detects opportunities for simplifying code by eliminating redundant boolean expressions and statements.

## Why is it bad?
Redundant code can make programs less efficient and harder to read. Simplifying such code improves readability,
maintainability, and can prevent potential logical errors.

**What it checks:**
- `if` statements that return boolean literals directly based on a condition.
- Comparisons of boolean expressions with boolean literals (`true` or `false`).
- Conditional expressions (ternary operators) that return boolean literals.

## Example

```tact
// Redundant 'if' statement:
if (condition) {
return true;
} else {
return false;
}
// Simplify to:
return condition;
// Redundant comparison:
return a == true;
// Simplify to:
return a;
// Redundant conditional expression:
return b ? true : false;
// Simplify to:
return b;
```
37 changes: 37 additions & 0 deletions versioned_docs/version-0.6/detectors/ExitCodeUsage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# ExitCodeUsage
A detector that identifies improper use of exit codes outside the developer-allowed range.

## Why is it bad?
In the TON blockchain, exit codes are divided into specific ranges: 0 to 127
are reserved for the TVM or FunC, and 128 to 255 are reserved for Tact. This
structure leaves the range from 256 to 65535 for developers to define custom
exit codes.

When exit codes are defined outside this allowed range, it may lead to
conflicts with existing reserved codes, causing unintended behavior or
errors in the contract.

## Example
```tact
contract Foo {
receive("foobar") {
// Bad: exit code defined in the reserved range for Tact
let code: Int = 128;
nativeThrowUnless(code, sender() == self.owner);
}
}
```

Use instead:
```tact
contract Foo {
receive("foobar") {
// OK: using exit code from the allowed range
let code: Int = 256;
nativeThrowUnless(code, sender() == self.owner);
}
}
```

## Resources
1. [Exit Codes | Tact Docs](https://docs.tact-lang.org/book/exit-codes)
Loading

0 comments on commit 2cd3ca9

Please sign in to comment.