Hooks.wtf

Slab V2

SlabLocker.sol

This document summarizes the security-focused review of SlabLocker.sol, including interaction analysis with SlabMachineV2 and RarityCalculatorV2. The review specifically validates the intended 1:n model where one locker serves many machines sharing the same slab inventory.


[HIGH] Sell-Back Restocking Breaks Because Assignment State Is Cleared on Withdrawal

The locker docs and interface state that depositFromSender “re-adds the token to the rarity pools of assigned machines.” In practice, this does not hold after a normal pull/withdraw flow:

  1. During withdrawTokenId, _updateSlabMachineTokenIds(tokenId, false) is called.
  2. In the _available == false branch, the locker removes the token from each machine pool and also removes each machine from tokenIdToSlabMachines[tokenId].
  3. Later, if the user sells back the token, depositFromSender calls _updateSlabMachineTokenIds(tokenId, true).
  4. At that point, tokenIdToSlabMachines[tokenId] is empty, so the token is not re-added to any machine pool.

Result: token returns to locker custody but becomes unassigned inventory and cannot be pulled again unless the owner manually calls addTokenIds.

This is a core lifecycle break and directly affects the 1:n shared-pool model.

Separate “assignment membership” from “currently available in pool”:

  • Keep assignment mapping (tokenIdToSlabMachines) intact when a token is withdrawn to a user.
  • Remove only availability sets (tokenIds + rarityTokenIds) while token is out of locker custody.
  • On depositFromSender, use persistent assignment mapping to re-add into all assigned machine pools.

If this behavior was intentional, update docs and interfaces immediately because current comments and API semantics state the opposite.


[MEDIUM] Admin Footgun: addTokenIds/removeTokenIds Trust Any Address as a Machine

addTokenIds and removeTokenIds call ISlabMachineV2(slabMachine).rarityCalculator() without validating that:

  • slabMachine is enabled via setSlabMachine, and
  • slabMachine is a well-formed machine contract.

If an invalid address is used, these calls can revert and fail batch operations. This is owner-only, but still a sharp edge for operational safety.

  • Require slabMachines[slabMachine].enabled == true in addTokenIds/removeTokenIds, or
  • Add explicit machine registration checks before assignments.

This makes “configured and enabled machine” the safe default path.


[MEDIUM] External Dependency DoS Surface in Value and Sell-Back Paths

Locker logic calls machine-side calculator contracts during:

  • _updateSlabMachineTokenIds
  • updateSlabValues

A single assigned machine address that reverts on rarityCalculator() or returns an incompatible contract can block updates for affected tokens. Again, this is mostly an owner-configuration risk, but it can stop lifecycle operations.

  • Validate machine contract compatibility on registration.
  • Fail fast with clearer errors during assignment.
  • Consider isolating per-machine failures in admin batch operations where feasible.

Summary

SeverityCountFocus
High1Sell-back restocking lifecycle break due assignment deletion.
Medium2Machine address validation and external dependency footguns.
Low1Missing dedicated 1:n integration coverage.

SlabLocker has a solid base for central custody and accounting, but the current withdrawal/sell-back interaction breaks expected pool restoration and should be fixed before relying on automated buyback recirculation at scale.

Previous
SlabBridge.sol