diff --git a/docs/docs/detectors/21-incorrect-exponentiation.md b/docs/docs/detectors/21-incorrect-exponentiation.md index b2584959..b9726d37 100644 --- a/docs/docs/detectors/21-incorrect-exponentiation.md +++ b/docs/docs/detectors/21-incorrect-exponentiation.md @@ -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::Data, &((255_u128 ^ 2) - 1)); + pub fn exp_data_3(e: Env) -> u128 { + let mut data = e.storage() + .instance() + .get::(&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::Data, &(255_u128.pow(2) - 1)); + pub fn exp_data_3(e: Env) -> u128 { + let data = e.storage() + .instance() + .get::(&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