Skip to content
Request an audit

Bit manipulation first: packing layouts, negative rounding, and unchecked blocks

We continued the Panoptic contest on Code4rena.

Lesson Summary:

  • Master bit manipulation first — Prioritize learning shifts (<<, >>), masks (&, |, ~), packing/unpacking, and signed integer behavior before diving deep; once comfortable, most "complex" libraries become straightforward helpers.
  • Treat bit-packing as storage optimization, not magic — Expect every value (ticks, liquidity, pointers, legs, flags) crammed into 256-bit words with manual getters/setters; always trace back to the packing layout comment or constants to verify offsets and ranges.
  • Watch for negative number rounding traps — When averaging or dividing for medians/averages (e.g., (a + b) / 2), Solidity’s toward-zero division rounds negative numbers “up” (toward zero) — flag this for consistency checks in tick/price calculations.
  • Be extra suspicious of unchecked blocks — They appear everywhere in extreme-optimization code; carefully verify arithmetic (especially +, - in clamps or deltas) can’t overflow/underflow in ways that break logic (e.g., int24 wrap-around making values unexpectedly small).Lean on fuzz testing for confidence — Once you understand the bit logic, write fuzz tests for encode/decode/update functions — deterministic packing is usually easy to prove correct (or find bugs) with good coverage, so don’t skip this step even if it initially looks clean.
Message on Telegram All 62 posts