Skip to content

Commit 9b477fe

Browse files
committed
Add TON not so smart contracts examples.
* Integer as Boolean values
1 parent 2d638c7 commit 9b477fe

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed

not-so-smart-contracts/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ This repository contains examples of common smart contract vulnerabilities, incl
77
- [Cosmos](./cosmos/README.md)
88
- [Solana](./solana/README.md)
99
- [Substrate](./substrate/README.md)
10+
- [TON](./ton/README.md)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# (Not So) Smart Contracts
2+
3+
This repository contains examples of common TON smart contract vulnerabilities, featuring code from real smart contracts. Utilize the Not So Smart Contracts to learn about TON vulnerabilities, refer to them during security reviews, and use them as a benchmark for security analysis tools.
4+
5+
## Features
6+
7+
Each _Not So Smart Contract_ consists of a standard set of information:
8+
9+
- Vulnerability type description
10+
- Attack scenarios to exploit the vulnerability
11+
- Recommendations to eliminate or mitigate the vulnerability
12+
- Real-world contracts exhibiting the flaw
13+
- References to third-party resources providing more information
14+
15+
## Vulnerabilities
16+
17+
| Not So Smart Contract | Description |
18+
| ---------------------------------------------------------------------------- | ------------------------------------------------------------ |
19+
| [Int as Boolean](int_as_boolean) | Unexpected result of logical operations on the int type |
20+
21+
## Credits
22+
23+
These examples are developed and maintained by [Trail of Bits](https://www.trailofbits.com/).
24+
25+
If you have any questions, issues, or wish to learn more, join the #ethereum channel on the [Empire Hacking Slack](https://slack.empirehacking.nyc/) or [contact us](https://www.trailofbits.com/contact/) directly.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Using int as boolean values
2+
3+
In FunC, booleans are represented as integers; false is represented as 0 and true is represented as -1 (257 ones in binary notation).
4+
5+
Logical operations are done as bitwise operations over the binary representation of the integer values. Notably, The not operation `~` flips all the bits of an integer value; therefore, a non-zero value other than -1 becomes another non-zero value.
6+
7+
When a condition is checked, every non-zero integer is considered a true value. This, combined with the logical operations being bitwise operations, leads to an unexpected behavior of `if` conditions using the logical operations.
8+
9+
## Example
10+
11+
The following simplified code highlights the unexpected behavior of the `~` operator on a non-zero interger value.
12+
13+
```FunC
14+
#include "imports/stdlib.fc";
15+
16+
() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
17+
int correct_true = -1;
18+
if (correct_true) {
19+
~strdump("correct_true is true"); ;; printed
20+
} else {
21+
~strdump("correct_true is false");
22+
}
23+
24+
if (~ correct_true) {
25+
~strdump("~correct_true is true");
26+
} else {
27+
~strdump("~correct_true is false"); ;; printed
28+
}
29+
30+
int correct_false = 0;
31+
if (correct_false) {
32+
~strdump("correct_false is true");
33+
} else {
34+
~strdump("correct_false is false"); ;; printed
35+
}
36+
37+
if (~ correct_false) {
38+
~strdump("~correct_false is true"); ;; printed
39+
} else {
40+
~strdump("~correct_false is false");
41+
}
42+
43+
int positive = 10;
44+
if (positive) {
45+
~strdump("positive is true"); ;; printed
46+
} else {
47+
~strdump("positive is false");
48+
}
49+
50+
if (~ positive) {
51+
~strdump("~positive is true"); ;; printed but unexpected
52+
} else {
53+
~strdump("~positive is false");
54+
}
55+
56+
int negative = -10;
57+
if (negative) {
58+
~strdump("negative is true"); ;; printed
59+
} else {
60+
~strdump("negative is false");
61+
}
62+
63+
if (~ negative) {
64+
~strdump("~negative is true"); ;; printed but unexpected
65+
} else {
66+
~strdump("~negative is false");
67+
}
68+
}
69+
```
70+
71+
The `recv_internal` function above prints the following debug logs:
72+
```
73+
#DEBUG#: correct_true is true
74+
#DEBUG#: ~correct_true is false
75+
#DEBUG#: correct_false is false
76+
#DEBUG#: ~correct_false is true
77+
#DEBUG#: positive is true
78+
#DEBUG#: ~positive is true
79+
#DEBUG#: negative is true
80+
#DEBUG#: ~negative is true
81+
```
82+
83+
It demonstrats that the `~ 10` and `~ -10` both evaluate to `true` instead of becoming `false` with the `~` operator.
84+
85+
## Mitigations
86+
87+
- Always use `0` or `-1` in condition checks to get correct results.
88+
- Be careful with the logical operator usage on non-zero integer values.
89+
- Implement test cases to verify correct behavior of all condition checks with different interger values.

0 commit comments

Comments
 (0)