Skip to content
Security
Skill

/dos-vectors

Detect denial-of-service vectors — unbounded loops, gas griefing, push-payment chokepoints, block-stuffing exposure, revert-on-receive blocking. Activate on loops over user-controlled arrays, batch withdrawals, push-style payouts, queues, auctions with "highest-bidder" refunds,

From plugin
rugproof
952 skills23 agents45 commands4 hooks
Install
$ npx -y skills add omermaksutii/RugProof --skill dos-vectors --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/dos-vectors

Context preview

The summary Claude sees to decide when to auto-load this skill.

Detect denial-of-service vectors — unbounded loops, gas griefing, push-payment chokepoints, block-stuffing exposure, revert-on-receive blocking. Activate on loops over user-controlled arrays, batch withdrawals, push-style payouts, queues, auctions with "highest-bidder" refunds,

SKILL.md

dos-vectors.SKILL.md
name: dos-vectors
description: Detect denial-of-service vectors — unbounded loops, gas griefing, push-payment chokepoints, block-stuffing exposure, revert-on-receive blocking. Activate on loops over user-controlled arrays, batch withdrawals, push-style payouts, queues, auctions with "highest-bidder" refunds, large airdrops.

DoS vector detection

When this applies

  • Loops iterating over user-supplied or unbounded arrays
  • Push-style payment patterns (contract pushes value to N recipients)
  • Auctions that refund the previous highest bidder via direct transfer
  • Mass `claim()` / `distribute()` functions
  • Queues / stacks of withdrawals
  • Functions whose gas cost scales with `n` users / `n` tokens
  • L2 forced inclusion mechanics

Detection patterns

Unbounded loop over user-controlled array (CRITICAL-HIGH)

function distribute() external {
    for (uint i; i < holders.length; ++i) {
        payable(holders[i]).transfer(rewards[i]);   // ← gas grows; eventually un-callable
    }
}

Worse if attacker can grow `holders` (e.g. anyone can register).

Push-payment with revert-on-receive (HIGH)

function refundPreviousBidder() internal {
    payable(highBidder).transfer(highBid);   // ← attacker bids from contract that reverts on receive → freezes auction
}

Use pull-payments: store credits, let users withdraw.

`.transfer` (2300 gas) blocks smart-wallet receivers (MEDIUM-HIGH)

Smart wallets (Gnosis Safe, Argent) have fallback functions that need >2300 gas. Their users can't receive — effectively DoS for them.

Gas griefing via large calldata (HIGH on relayers)

Relayer pays gas; user provides bloated calldata to grief. Cap calldata length or charge per-byte.

`external` reentrant fee-loop DoS (HIGH)

Withdrawals from each strategy in a vault — if any strategy reverts, the entire withdraw fails. Use try/catch per strategy.

Block-stuffing exposure (MEDIUM)

Auction ending exactly at `block.number == N` lets an attacker fill the block to prevent your bid. Use deadline windows + sniping protection (extend on late bid).

Underflow-revert DoS on legacy 0.7.x code (MEDIUM)

Unchecked subtraction in Solidity ≥0.8 reverts on underflow — function permanently broken if state lands in that range.

`selfdestruct` to force ether on a contract that asserts `address(this).balance == X` (HIGH)

Anyone can `selfdestruct` to your contract and break a balance-equality check. Don't rely on `address(this).balance` equality. *(Note EIP-6780 changed selfdestruct semantics — see [[selfdestruct-eip6780]].)*

Forced inclusion on Arbitrum / Optimism (LOW-MEDIUM)

On rollups, anyone can force-include a tx via L1 — affects "exclusive sequencer" assumptions in auctions.

Severity rubric

| Pattern | Severity | |---|---| | Unbounded loop attacker can grow → permanent function failure | **Critical** | | Push-payment to attacker-controlled `receive()` blocks core flow | **High** | | Per-strategy revert blocks entire vault withdraw | **High** | | Smart-wallet receivers can't get `.transfer` payouts | **Medium-High** | | Auction block-stuffing | **Medium** | | Balance-equality reliance | **High** | | Force-include L2 sequencer assumption | **Medium** | | Calldata gas-grief on relayer | **Medium** | | Bounded-but-large loop costing >block gas | **Medium** |

Remediation patterns

  • **Pull over push** — credit balances, users withdraw.
  • **Per-iteration isolation** — try/catch around per-element work in batch ops.
  • **Batch caps** — `require(arr.length <= MAX)`.
  • **Pagination** — `distribute(start, end)`.
  • **Use `call` not `transfer`** — forward all gas, then check return.
  • **Don't rely on `address(this).balance` equality** — track expected balance separately.
  • **Auction extensions** — extend deadline on late bid to defeat block-stuffing.

False-positive notes

  • Loops over a *contract-controlled* small bounded array (e.g. fixed 3 strategies) are fine — note the bound.
  • Internal admin functions where DoS only hurts the admin → Info.

Related

  • [[unchecked-calls]]
  • [[selfdestruct-eip6780]]
  • [[reentrancy]]
Read more
Ships withrugproof

Rugproof your code before someone else does. 🌐 Live site: omermaksutii.github.io/RugProof 📦 Latest: v1.0.0 — 45 commands · 23 agents · 45 skills · 13 MCP servers · tested, offline-first, with rule packs, a benchmark, non-EVM coverage, and post-deploy

Get the whole plugin

Other skills on rugproof.