Tier: Hard
Description: An address can hold multiple roles (e.g. Company then later Guardian) since set_role maintains both a per-role flag map and a single legacy Role(addr) pointer. storage::revoke_role unconditionally resets the legacy pointer, and the public revoke_role only operates on storage::get_role() — never iterating actual per-role flags. There's no way to revoke a non-primary role, and revoking "the" role can leave stale UserRole flags true while get_role reports Unassigned.
Files: contracts/shipment/src/storage.rs:386-393, contracts/shipment/src/lib.rs:1937-1958
Tasks:
Tier: Hard
Description: An address can hold multiple roles (e.g. Company then later Guardian) since
set_rolemaintains both a per-role flag map and a single legacyRole(addr)pointer.storage::revoke_roleunconditionally resets the legacy pointer, and the publicrevoke_roleonly operates onstorage::get_role()— never iterating actual per-role flags. There's no way to revoke a non-primary role, and revoking "the" role can leave staleUserRoleflagstruewhileget_rolereportsUnassigned.Files:
contracts/shipment/src/storage.rs:386-393,contracts/shipment/src/lib.rs:1937-1958Tasks:
revoke_roleto accept and clear a specific role from the per-role flag map, not just the legacy slotAcceptance Criteria:
get_role