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:
- During
withdrawTokenId,_updateSlabMachineTokenIds(tokenId, false)is called. - In the
_available == falsebranch, the locker removes the token from each machine pool and also removes each machine fromtokenIdToSlabMachines[tokenId]. - Later, if the user sells back the token,
depositFromSendercalls_updateSlabMachineTokenIds(tokenId, true). - 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.
Recommended Solution
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:
slabMachineis enabled viasetSlabMachine, andslabMachineis 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.
Recommended Solution
- Require
slabMachines[slabMachine].enabled == trueinaddTokenIds/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:
_updateSlabMachineTokenIdsupdateSlabValues
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.
Recommended Solution
- 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
| Severity | Count | Focus |
|---|---|---|
| High | 1 | Sell-back restocking lifecycle break due assignment deletion. |
| Medium | 2 | Machine address validation and external dependency footguns. |
| Low | 1 | Missing 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.