A narrowed class mask is misreported as a buyer rejection
A narrowed class mask is misreported as a buyer rejection. Final disposition: Fixed.
Tracker: issue #20 · Status: Fixed · Verified at: audit-v3-rereview-handoff
Affected files
src/PlakxioSettlement.sol#L936-L945 src/PlakxioBadge.sol#L530-L551 src/PlakxioBadge.sol#L620-L645
Description
PlakxioSettlement._finalize() uses badge.isApprovedForAll() to check whether the settlement may transfer the ask token. However, PlakxioBadge.isApprovedForAll() returns true for any active settlement with a nonzero class mask without checking whether that mask includes the token's class.
If an administrator narrows the settlement's mask to another nonzero class, the precheck continues to pass for excluded tokens after the activation delay. The subsequent class-aware safeTransferFrom() call reverts with ClassNotPermittedForOperator, but the bare catch converts this operational failure into BuyerRejectedBadge.
The transaction remains atomic, so state changes, payments, authorization consumption, and order marks are reverted. The demonstrated impact is limited to exposing the wrong failure classification: an operator-authorization failure that should remain neutral is instead attributed to the buyer. This requires a legitimate mask change, completion of its activation delay, an affected resting order, and a settlement attempt.
Recommendations
Before the transfer catch, compare settlementClassMask(address(this)) with the bit corresponding to badge.tokenClass(ask.tokenId). Revert with SettlementNotAuthorized when the token's class is excluded.
Retain the bare catch for genuine receiver-hook failures, as it prevents a buyer contract from forging trusted error data. Add tests for an excluded class after mask activation, a zero mask, pending activation, seller opt-out, genuine receiver rejection, and a successful transfer. This check adds a class lookup and mask read to the settlement path.
Remediation
Fixed. An operator-authority fault is no longer attributed to the buyer, and the zero-mask case is pinned by test. The fix rode with #17 in a2b3e9b, as your comment said.
Verification provenance
Final disposition: Fixed. Verified at audit-v3-rereview-handoff, commit f020448976eb7c4895e1626ef3228876cff2b7d2. This earlier remediation disposition is carried forward from the prior re-review, not independently re-verified in the generation-d pass. The report-wide scope and evidence limitations remain applicable; see the final report overview.