# Randomness reuse and time-scaled ranking bias

One random value or time-scaled bonus reused across selections; check if users can cheaply shift the modulus or ranking

_Area: Smart contract access control and control flow. Seen in 2 disclosed reports; latest 2024-06-12. Updated 2026-10-24._

## How it works
A selection or ranking is meant to be fair, but the value driving it is either reused across two different ranges or scaled by elapsed time in a way users can influence. When one random number is reduced modulo two different lengths, the joint distribution is skewed, so some outcomes are more likely than others. When a bonus is computed from the incumbent's balance times elapsed time, a marginal newcomer can outrank a long-standing participant. The broken assumption is that the input is uniform or that the comparison reflects true stake; neither holds once users can cheaply change the modulus (membership) or the timing.

## Where it shows up
- A single random value feeding two modulo operations, e.g. pod selection and operator selection [E1](https://bugbountylibrary.com/r/c4%3A2022-10-holograph%3AH-04.md)
- Free join/leave or swap-on-pop that lets users reshape the set being indexed [E1](https://bugbountylibrary.com/r/c4%3A2022-10-holograph%3AH-04.md)
- Ranking formulas that add a term scaled by `timeDiff` or the incumbent's own balance [E3](https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.1.10.md)
- User-supplied arguments checked only for truthiness, not structure or emptiness [E2](https://bugbountylibrary.com/r/cantina%3Acircuit_puzzles%3A3.3.8.md)
- Documented invariants ("early sponsors protected", "highest stake wins") that the code does not actually enforce [E3](https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.1.10.md)

## How to review
Identify the exact property that must hold: the selection distribution must be uniform over the intended set, or the ranking must be monotonic in true stake independent of timing. Check whether the same random value is used for more than one reduction; if so, require independent randomness per selection or a rejection scheme. Check whether users can alter either modulus cheaply. For ranking, verify the comparison uses only the candidate's own stake, not the incumbent's balance or elapsed time. For user-supplied lists, branch on structure (head/emptiness), not truthiness [E2](https://bugbountylibrary.com/r/cantina%3Acircuit_puzzles%3A3.3.8.md).

## Variants seen
- Single random value reused across pod and operator modulo, with free membership changes [E1](https://bugbountylibrary.com/r/c4%3A2022-10-holograph%3AH-04.md)
- Truthiness check on a user list whose head is empty, steering control flow and breaking aggregation [E2](https://bugbountylibrary.com/r/cantina%3Acircuit_puzzles%3A3.3.8.md)
- Time-scaled sponsor bonus computed from incumbent balance, letting a 100-wei-higher backrunner win [E3](https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.1.10.md)

## Impact and severity
Biased selection lets an attacker gain advantage over honest operators or sponsors [E1](https://bugbountylibrary.com/r/c4%3A2022-10-holograph%3AH-04.md)[E3](https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.1.10.md); the truthiness bug lets an attacker disable aggregation and DoS a singleton [E2](https://bugbountylibrary.com/r/cantina%3Acircuit_puzzles%3A3.3.8.md). Severity rises when membership is free and when the bias is deterministic rather than probabilistic.

## Why fixes fail
Documented invariants were contradicted by the implementation, so fixes that only restate the invariant without changing the formula leave the bias intact [E3](https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.1.10.md).

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2022-10-holograph%3AH-04.md
- E2: https://bugbountylibrary.com/r/cantina%3Acircuit_puzzles%3A3.3.8.md
- E3: https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.1.10.md
