Skip to content

Commit

Permalink
New incorrect-exponentiation documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasavola authored Aug 9, 2024
1 parent 78af369 commit 9c33c7e
Showing 1 changed file with 43 additions and 19 deletions.
62 changes: 43 additions & 19 deletions docs/docs/detectors/21-incorrect-exponentiation.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,60 @@
# Incorrect Exponentiation
# Incorrect exponentiation

### What it does
## Description

Warns about `^` being a `bit XOR` operation instead of an exponentiation.
- Vulnerability Category: `Arithmetic`
- Vulnerability Severity: `Critical`
- Detectors: [`incorrect-exponentiation`](https://github.com/CoinFabrik/scout-soroban/tree/main/detectors/incorrect-exponentiation)
- Test Cases: [`incorrect-exponentiation-1`](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/incorrect-exponentiation/incorrect-exponentiation-1)

The operator `^` is not an exponential operator, it is a bitwise XOR. Make sure to use `pow()` instead for exponentiation. In case of performing a XOR operation, use `.bitxor()` for clarity.

### Why is this bad?
## Why is it bad?

It can introduce unexpected behaviour in the smart contract.
It can produce unexpected behaviour in the smart contract.

#### More info
## Issue example

- https://doc.rust-lang.org/std/ops/trait.BitXor.html#tymethod.bitxor
In the following example, the `^` operand is being used for exponentiation. But in Rust, `^` is the operand for an XOR operation. If misused, this could lead to unexpected behaviour in our contract.

### Example
Consider the following `Soroban` contract:

```rust
pub fn init(e: Env){
e.storage()
.instance()
.set::<DataKey, u128>(&DataKey::Data, &((255_u128 ^ 2) - 1));
pub fn exp_data_3(e: Env) -> u128 {
let mut data = e.storage()
.instance()
.get::<DataKey, u128>(&DataKey::Data)
.expect("Data not found");

data ^= 3;
data
}
```
Use instead:

The code example can be found [here](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/incorrect-exponentiation/incorrect-exponentiation-1/vulnerable-example).

## Remediated example

A possible solution is to use the method `pow()`. But, if a XOR operation is wanted, `.bitxor()` method is recommended.

```rust
pub fn init(e: Env) {
e.storage()
.instance()
.set::<DataKey, u128>(&DataKey::Data, &(255_u128.pow(2) - 1));
pub fn exp_data_3(e: Env) -> u128 {
let data = e.storage()
.instance()
.get::<DataKey, u128>(&DataKey::Data)
.expect("Data not found");

data.pow(3)
}
```

### Implementation
The remediated code example can be found [here](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/incorrect-exponentiation/incorrect-exponentiation-1/remediated-example).

## How is it detected?

Warns about `^` being a `bit XOR` operation instead of an exponentiation.


## References

The detector's implementation can be found at [this link](https://github.com/CoinFabrik/scout-soroban/tree/main/detectors/incorrect-exponentiation).
- https://doc.rust-lang.org/std/ops/trait.BitXor.html

0 comments on commit 9c33c7e

Please sign in to comment.