From df49a6ed04a8d326cff0b1dbc482eb71abb41175 Mon Sep 17 00:00:00 2001 From: Arturo Beccar-Varela <107512933+arturoBeccar@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:33:59 -0300 Subject: [PATCH] Add documentation for insufficiently-random-values --- .../insufficiently-random-values/README.md | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 detectors/insufficiently-random-values/README.md diff --git a/detectors/insufficiently-random-values/README.md b/detectors/insufficiently-random-values/README.md new file mode 100644 index 00000000..a7d5d0ef --- /dev/null +++ b/detectors/insufficiently-random-values/README.md @@ -0,0 +1,51 @@ +# Insuficciently random values + +### What it does +Checks the usage of `ledger().timestamp()` or `ledger().sequence()` for generation of random numbers. + +### Why is this bad? +Using `ledger().timestamp()` is not recommended because it could be potentially manipulated by validator. On the other hand, `ledger().sequence()` is publicly available, an attacker could predict the random number to be generated. + +### Example + +```rust +#[contractimpl] +impl Contract { + pub fn generate_random_value_timestamp(env: Env, max_val: u64) -> Result { + if max_val == 0 { + Err(Error::MaxValZero) + } else { + let val = env.ledger().timestamp() % max_val; + Ok(val) + } + } + pub fn generate_random_value_sequence(env: Env, max_val: u32) -> Result { + if max_val == 0 { + Err(Error::MaxValZero) + } else { + let val = env.ledger().sequence() % max_val; + Ok(val) + } + } +} +``` + +Use instead: + +```rust +#[contractimpl] +impl Contract { + pub fn generate_random_value(env: Env, max_val: u64) -> Result { + if max_val == 0 { + Err(Error::MaxValZero) + } else { + let val = env.prng().u64_in_range(0..max_val); + Ok(val) + } + } +} +``` + +### Implementation + +The detector's implementation can be found at [this link](https://github.com/CoinFabrik/scout-soroban/tree/main/detectors/insufficiently-random-values).