Summary
pallet-alliance::kick_member removes a retiring member from the member role set but leaves the corresponding RetiringMembers storage entry behind.
This finding was found by the runtime whitebox fuzzer.
Severity
Medium. This creates inconsistent membership storage and violates the pallet's retiring-member try-state invariant.
Source Evidence
Reproduction Command
cargo test -p pallet-alliance tests::generated_tests::test_risk_2muff5zr_kick_retiring_member_leaves_stale_storage -- --ignored --exact --nocapture
Observed Failure
assertion `left == right` failed: RetiringMembers storage must be cleared when a retiring member is kicked
left: Some(5)
right: None
Full Relevant PoC Test
Place this file at substrate/frame/alliance/src/tests/generated_tests.rs and ensure the parent test module includes mod generated_tests;.
use super::*;
#[ignore]
#[test]
fn test_risk_2muff5zr_kick_retiring_member_leaves_stale_storage() {
new_test_ext().execute_with(|| {
assert_ok!(Alliance::give_retirement_notice(RuntimeOrigin::signed(3)));
assert!(Alliance::is_member_of(&3, MemberRole::Retiring));
assert!(alliance::RetiringMembers::<Test>::get(3).is_some());
assert_ok!(Alliance::kick_member(RuntimeOrigin::signed(2), 3));
assert!(!Alliance::is_member(&3));
assert_eq!(
alliance::RetiringMembers::<Test>::get(3),
None,
"RetiringMembers storage must be cleared when a retiring member is kicked"
);
})
}
Expected Behavior
Kicking a retiring member should clear RetiringMembers for that member, matching the cleanup performed by the normal retire path.
Summary
pallet-alliance::kick_memberremoves a retiring member from the member role set but leaves the correspondingRetiringMembersstorage entry behind.This finding was found by the runtime whitebox fuzzer.
Severity
Medium. This creates inconsistent membership storage and violates the pallet's retiring-member try-state invariant.
Source Evidence
alliance/src/lib.rs#L790-L808:retireremoves both the role entry andRetiringMembers.alliance/src/lib.rs#L812-L824:kick_memberremoves the role entry and deposit but never removesRetiringMembers.alliance/src/lib.rs#L1172-L1193: try-state requiresMembers<Retiring>andRetiringMembersto stay consistent.Reproduction Command
cargo test -p pallet-alliance tests::generated_tests::test_risk_2muff5zr_kick_retiring_member_leaves_stale_storage -- --ignored --exact --nocaptureObserved Failure
Full Relevant PoC Test
Place this file at
substrate/frame/alliance/src/tests/generated_tests.rsand ensure the parent test module includesmod generated_tests;.Expected Behavior
Kicking a retiring member should clear
RetiringMembersfor that member, matching the cleanup performed by the normalretirepath.