Skip to content

Commit

Permalink
add 29-dynamic-types-in-storage
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasavola authored Sep 12, 2024
1 parent 3911388 commit 747a208
Showing 1 changed file with 52 additions and 0 deletions.
52 changes: 52 additions & 0 deletions docs/docs/detectors/29-dynamic-types-in-storage
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Dynamic types in storage

## Description

- Category: `Authorization`
- Severity: `Critical`
- Detectors: [`dynamic-instance-storage`](https://github.com/CoinFabrik/scout-soroban/tree/main/detectors/dynamic-instance-storage)
- Test Cases: [`dynamic-instance-storage-1`](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/dynamic-instance-storage/dynamic-instance-storage-1) [`dynamic-instance-storage-2`](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/dynamic-instance-storage/dynamic-instance-storage-2) [`dynamic-instance-storage-3`](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/dynamic-instance-storage/dynamic-instance-storage-3)

In Rust, it is very useful to use `storage.persistent()` to store data that is shared among all users of the contract (e.g., a token administrator). However, using this macro with dynamic variables (such as vectors, maps, etc.) is not recommended.

## Why is this bad?

Using dynamic values with `storage.persistent()` can cause excessive storage use and may risk DoS attacks on the contract.

## Issue example

Consider the following `Soroban` contract:

```rust

pub fn store_vector(e: Env, data: Vec<i32>) {
e.storage()
.persistent()
.set(&Symbol::new(&e, "vector_data"), &data);
}

```
In this example, the function is storing a vector using `storage.persistent()`.

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

## Remediated example

Consider the following `Soroban` contract:

```rust
pub fn store_vector(e: Env, data: Vec<i32>) {
for (i, value) in data.iter().enumerate() {
let key = DataKey::VecElement(i as u32);
e.storage().persistent().set(&key, &value);
}
}
```

Instead of using `storage.persistent()` to store a vector in the storage, the data belonging to the vector can be stored directly in the storage.

The remediated code example can be found [here](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/dynamic-instance-storage/dynamic-instance-storage-1/remediated-example).

## How is it detected?

Checks the usage of `storage().persistent()` with dynamic types.

0 comments on commit 747a208

Please sign in to comment.