21 published rules

What the review
looks for.

The studio reads your source with these rules on every keystroke. Comments and string contents are ignored, so a rule fires only on code. They catch common mistakes fast; they do not understand your business logic, and a clean result is not a proof of safety.

high

Likely to lose funds or hand control to the wrong account.

  • Authorization with tx.origin

    tx.origin is the account that started the transaction, so any contract that account calls can act with its rights.

    rule id: tx-origin

  • Low-level call result ignored

    A failed .call does not revert on its own; ignoring the returned flag treats a failed payment as a sent one.

    rule id: unchecked-call

  • Mint without a caller check

    A public mint function that never looks at msg.sender lets anyone create supply.

    rule id: unguarded-mint

  • delegatecall present

    delegatecall runs foreign code with this contract's storage and balance. It needs a fixed, trusted target.

    rule id: delegatecall

medium

Can go wrong under specific conditions; worth fixing before value arrives.

  • State written after an external call

    Updating balances after sending ETH or calling out opens the door to re-entrancy. Write state first, call last.

    rule id: state-after-call

  • Constructor reads msg.sender

    Deployed through WerboPress, the constructor's msg.sender is the press, not you. Pass the owner as an argument.

    rule id: constructor-sender

  • Randomness from block values

    Timestamps, block hashes and prevrandao can be predicted or nudged; they are not a fair source of chance.

    rule id: weak-randomness

  • ETH can come in but never leave

    The contract accepts ETH but has no path that sends ETH out, so anything received stays forever.

    rule id: locked-ether

  • Raw ecrecover

    ecrecover returns address(0) for bad signatures and accepts both s values. Check for zero and bound s.

    rule id: ecrecover

  • selfdestruct present

    Since Cancun it no longer deletes code except in the creating transaction, and it is deprecated.

    rule id: selfdestruct

low

Robustness and precision issues that usually cost gas or surprise users.

  • ETH sent with transfer or send

    Both forward a fixed 2300 gas, which smart-contract wallets often need more than. Use call and check the result.

    rule id: transfer-send

  • Loop over a growing storage array

    If the array can grow without limit, the loop can one day cost more gas than a block holds.

    rule id: storage-loop

  • Constructor address not checked for zero

    An empty address argument usually means a typo, and immutable values cannot be fixed afterwards.

    rule id: zero-address

  • Division before multiplication

    Integer division rounds down; dividing first throws away precision that the multiplication would have kept.

    rule id: divide-first

info

Things to know and decide on purpose.

  • block.number used

    On Arbitrum-based chains such as Robinhood Chain, block.number follows the parent chain, not this chain's blocks. Use block.timestamp for time.

    rule id: block-number

  • Floating pragma

    ^0.8.x lets a later compiler build it. Fine for drafts; pin the exact version you tested before deploying.

    rule id: floating-pragma

  • Inline assembly

    Assembly skips the compiler's safety checks. Read each block line by line.

    rule id: assembly

  • unchecked arithmetic

    Inside unchecked blocks overflow wraps silently. Each one needs a reason it cannot overflow.

    rule id: unchecked-math

  • State changes without events

    Without events, wallets, explorers and indexers cannot follow what the contract did.

    rule id: no-events

  • One account holds special rights

    Everything the owner can do depends on one key. Say so plainly to users, or use a multisig as the owner.

    rule id: single-owner

  • No SPDX license line

    Explorers and other builders look for an SPDX-License-Identifier comment at the top of the file.

    rule id: missing-license