Skip to content
Security
Skill

/bit-shift-safety

Trigger Pattern Always (Aptos Move) - Move VM aborts on shift = bit width - Inject Into Breadth agents, depth-edge-case

From plugin
plamen
276160 skills12 agents4 commands
Install
$ npx -y skills add PlamenTSV/plamen --skill bit-shift-safety --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/bit-shift-safety

Context preview

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

Trigger Pattern Always (Aptos Move) - Move VM aborts on shift = bit width - Inject Into Breadth agents, depth-edge-case

SKILL.md

bit-shift-safety.SKILL.md
name: "bit-shift-safety"
description: "Trigger Pattern Always (Aptos Move) - Move VM aborts on shift = bit width - Inject Into Breadth agents, depth-edge-case"

BIT_SHIFT_SAFETY Skill

> **Trigger Pattern**: Always (Aptos Move) --- Move VM aborts on shift >= bit width > **Inject Into**: Breadth agents, depth-edge-case

The Move VM performs a runtime check on every bit shift operation: if the shift amount is greater than or equal to the bit width of the operand type, the transaction aborts. This is not a silent wraparound --- it is a hard abort that reverts the entire transaction. Any user-controllable or computed shift amount that can reach the bit width threshold is a denial-of-service vector.

1. Shift Operation Inventory

**MANDATORY GREP**: Search all `.move` files for `<<` and `>>` operators.

For each shift operation found:

| Location (file:line) | Operand Type | Bit Width | Shift Amount Source | User-Controllable? | Bounded? | |-----------------------|-------------|-----------|--------------------|--------------------|----------| | {file}:{line} | u8/u16/u32/u64/u128/u256 | 8/16/32/64/128/256 | constant / parameter / computed | YES/NO | YES/NO --- {how} |

**Classification of shift amount sources**:

  • **Constant**: Hardcoded literal (e.g., `1 << 64`). Safe if < bit width, abort if >= bit width. Check constants that equal or exceed the bit width --- this is a compile-time-detectable bug but Move does not always catch it.
  • **Parameter**: Passed into the function from a caller. Trace the call chain to determine if externally controllable.
  • **Computed**: Result of arithmetic (e.g., `1 << (decimals - offset)`). Requires boundary analysis.

2. Shift Amount Bound Verification

For each shift operation where the shift amount is NOT a safe constant:

2a. Bit Width Threshold Table

| Type | Bit Width | Max Safe Shift | Abort Condition | |------|-----------|---------------|-----------------| | u8 | 8 | 7 | shift >= 8 | | u16 | 16 | 15 | shift >= 16 | | u32 | 32 | 31 | shift >= 32 | | u64 | 64 | 63 | shift >= 64 | | u128 | 128 | 127 | shift >= 128 | | u256 | 256 | 255 | shift >= 256 |

2b. Bound Verification Per Shift

For each non-constant shift:

| Location | Shift Amount Expression | Minimum Value | Maximum Value | Exceeds Bit Width? | Guard Present? | |----------|------------------------|---------------|---------------|-------------------|----------------| | {location} | {expression} | {min} | {max} | YES/NO | YES --- {assert/min/if} / NO |

**Verification method**: Trace the shift amount back to its origin. For each variable in the expression: 1. What is its declared type? (constrains range) 2. Is there an `assert!()` that bounds it before the shift? 3. Is there a `min()` or `if` guard? 4. Can the variable be set by an external caller (entry function parameter, stored value set by a public function)?

Tag: `[BOUNDARY:shift_amount={val} → abort at bit_width={W}]`

3. Computed Shift Analysis

For shift amounts derived from arithmetic, perform boundary value analysis:

3a. Subtraction Underflow in Shift Amount

Pattern: `1 << (a - b)` where both `a` and `b` are unsigned integers.

| Location | Expression | Can `b > a`? | Underflow Result | Impact | |----------|-----------|-------------|-----------------|--------| | {location} | `1 << (decimals - 6)` | YES if decimals < 6 | Wraps to large u8/u64 → abort | DoS |

**Check**: Move unsigned subtraction aborts on underflow (no wraparound). So `a - b` where `b > a` aborts BEFORE the shift. This is a separate DoS vector (arithmetic underflow). Document both: 1. Underflow abort if `b > a` 2. Shift abort if `a - b >= bit_width`

3b. Addition/Multiplication Overflow in Shift Amount

Pattern: `value << (a + b)` or `value << (a * b)`

| Location | Expression | Can Sum/Product >= Bit Width? | Impact | |----------|-----------|------------------------------|--------| | {location} | {expression} | YES/NO --- {boundary values} | {DoS / safe} |

3c. Shift Result Overflow

Even if the shift amount is safe, the RESULT of the shift may overflow the type:

| Location | Expression | Operand Max Value | Shift Amount | Result Exceeds Type Max? | Impact | |----------|-----------|-------------------|-------------|-------------------------|--------| | {location} | `amount << decimals` | {max} | {amount} | YES/NO | {silent truncation / abort} |

**Note**: Move does NOT abort on shift result overflow --- the result is silently truncated (high bits discarded). This is a correctness bug, not a DoS bug, but can cause incorrect calculations (e.g., `1u64 << 63` = 9223372036854775808, but `3u64 << 63` = 9223372036854775808 due to truncation).

Tag: `[BOUNDARY:shift_result=truncated at type_max]`

4. DoS Impact Assessment

For each shift operation that can abort:

4a. Abort Impact Trace

| Location | Function | Entry Point? | Who Calls This? | Abort Blocks What? | Severity | |----------|----------|-------------|----------------|--------------------|---------| | {location} | {function} | YES/NO | {callers} | {blocked operations} | {H/M/L} |

**Trace from the aborting shift outward**: 1. Which function contains the shift? 2. Is that function called by entry functions (user-facing)? 3. Is it called in a critical path (deposit, withdraw, claim, liquidation)? 4. Can an attacker provide input that triggers the abort? 5. Does the abort affect ONLY the attacker's transaction, or does it block other users?

**Severity guide**:

  • Shift in view function only -> Low (informational, no state impact)
  • Shift in user's own transaction path (self-DoS only) -> Low
  • Shift in shared operation (affects all users) -> Medium to High
  • Shift in critical path (deposits/withdrawals blocked for all) triggered by attacker input -> High
  • Shift in liquidation/price computation path -> High to Critical (can block liquidations, enable insolvency)

4b. Attacker-Triggerable Analysis

For shifts that can abort and are in shared/critical paths:

1. Attac
Read more
Ships withplamen

Autonomous Web3 security auditor for Claude Code and OpenAI Codex CLI. Orchestrates 18-100 AI agents across 40+ phases to produce audit reports with verified PoC exploits — for smart contracts and L1 node-client infrastructure.

Get the whole plugin