Skip to content

Add kick_member to Society pallet#11154

Merged
sigurpol merged 14 commits intoparitytech:masterfrom
laurogripa:kick-member-society-extrinsic
Mar 5, 2026
Merged

Add kick_member to Society pallet#11154
sigurpol merged 14 commits intoparitytech:masterfrom
laurogripa:kick-member-society-extrinsic

Conversation

@laurogripa
Copy link
Copy Markdown
Contributor

@laurogripa laurogripa commented Feb 23, 2026

Adds a kick_member extrinsic to pallet-society, callable by the Founder, that removes a member,slashes its payout and returns funds to the Society pot.

Context

Recently, a collusion was discovered where a member managed to claim membership without providing PoI. This change introduces a way for the Founder to kick and slash the bad actors.

@laurogripa laurogripa requested a review from a team as a code owner February 23, 2026 22:51
@laurogripa
Copy link
Copy Markdown
Contributor Author

/cmd prdoc --audience runtime_dev --bump minor

@laurogripa
Copy link
Copy Markdown
Contributor Author

/cmd label T1-FRAME

@paritytech-cmd-bot-polkadot-sdk paritytech-cmd-bot-polkadot-sdk bot added the T1-FRAME This PR/Issue is related to core FRAME, the framework. label Feb 23, 2026
@bkchr
Copy link
Copy Markdown
Member

bkchr commented Mar 4, 2026

/cmd fmt

@bkchr bkchr enabled auto-merge March 4, 2026 19:34
);
let who = T::Lookup::lookup(who)?;

Self::slash_payout(&who, BalanceOf::<T, I>::max_value());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it intentional that we don't call unreserve_payout() unlike what we do in judge_suspended_member?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering if the correct pattern is the one in judge_suspended_member or the one in strike_member where we also don't call unreserve_payout...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re-reading the code... I believe not calling unreserve_payout is a bug both here and in strike_member.
In the end the scope of the PR is to give super powers to the founder to force-suspend a member so as I see it, kick_member = suspend_member(who) + judge_suspended_member(who, false)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it intentional that we don't call unreserve_payout() unlike what we do in judge_suspended_member?

Yeah good point. I read the code also again and it looks like slash_payout is actually broken.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, shouldn't unreserve_payout be coupled with slash_payout every time i.e. unreserve_payout should be called inside slash_payout, at the end?

Copy link
Copy Markdown
Contributor

@sigurpol sigurpol Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think so honestly - but it's up to you if you prefer a very punctual fix for the kick_member case only in this PR and have any other fix / refactor / improvement for later or not. I am fine with both approaches.

I would be fine with a very minimal change like

  let slashed = Self::slash_payout(&who, BalanceOf::<T, I>::max_value());
  Self::unreserve_payout(slashed);
  Self::suspend_member(&who).map(drop)

or with fixing slash payout as you suggest - or going for @bkchr' suggestion to go with remove_member - all works for me.

If I have to choose one, I think the cleaner is remove_member + unreserve_payout (+ KickedMember event)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a variant with remove_member here: cb6a9ff PTAL and let me know if it makes sense

/// - `who`: The member to be suspended.
#[pallet::call_index(21)]
#[pallet::weight(T::WeightInfo::kick_member())]
pub fn kick_member(origin: OriginFor<T>, who: AccountIdLookupOf<T>) -> DispatchResult {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we probably don't need to call suspend_member at all.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bkchr wdym? just call remove_member instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My rationale here was to treat kicking the same way as a regular suspension, adding the kicked member to the SuspendedMembers list, but in this case, I guess it makes sense to simply remove straight away

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can replace suspend_member with remove_member and add a MemberKicked event here, if it makes sense.

However, I think there are a few places where the events in this pallet can be improved. There's no event for claim_membership iirc, which is arguably the most important event. I plan to propose a set of improvements after we deal with this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can take care of backporting to 2512, merge there, ask rel team to publish a new crate and finally bump the crate version in the runtime PR for 2.1.0, don't worry. No need to open upgrade proposal, it will be part of 2.1.0 (cc @ggwpez )

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also westend doesn't have society pallet so my /cmd bench errored out 😓 it would make sense to generate benchmarks for kusama only there. Here only rococo seems to support it but no point in regenerate weights there so we are good to merge I believe.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can take care of backporting to 2512, merge there, ask rel team to publish a new crate and finally bump the crate version in the runtime PR for 2.1.0, don't worry. No need to open upgrade proposal, it will be part of 2.1.0 (cc @ggwpez )

Okay! Do you think 2.1.0 can be enacted in the next 7 days or so? The bad actor's payout will mature in block 32,716,826. We also need 1 or 2 days of buffer ideally, so the Founder can call the extrinsic

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @ggwpez - the plan would be if all planets are aligned (mostly CI, especially runtime CI) to make a referendum for Kusama by end of this week. Realistically I don't think we will have the PR for bumping crates and to rerun pallet-society crates ready before end of tomorrow (we need to wait for this PR to be merged, backported one to be merged, crate to be published, PR runtime to run benchmarks and be green and reviewed). I believe it's doable if we can make a very short referendum on Kusama.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

polkadot-fellows/runtimes#1080 has just been merged by @ggwpez and contains the fix for kick_member - once runtime is built there will be a referendum @laurogripa

@sigurpol
Copy link
Copy Markdown
Contributor

sigurpol commented Mar 4, 2026

I have some concerns about merging in the current state but it's also the 1st time I am looking at this code.
My 2c: I honestly don't like what this PR allows but I understand the urgency of the situation and that there is no time for a redesign of the mechanism.
Maybe we should evaluate some way to slash who vouched for the fraudulent member, or to use some collective governance instead of the founder kick or similar... but ok, nothing we can solve immediately.

@laurogripa
Copy link
Copy Markdown
Contributor Author

laurogripa commented Mar 5, 2026

I have some concerns about merging in the current state but it's also the 1st time I am looking at this code. My 2c: I honestly don't like what this PR allows but I understand the urgency of the situation and that there is no time for a redesign of the mechanism. Maybe we should evaluate some way to slash who vouched for the fraudulent member, or to use some collective governance instead of the founder kick or similar... but ok, nothing we can solve immediately.

Thanks for the thorough review, @sigurpol!

Agreed, it's not ideal, but it's also temporary. I plan to open an RFC right after this, so we can discuss a better solution (possibly with collective governance and a minimum quorum to avoid further collusions)

auto-merge was automatically disabled March 5, 2026 03:07

Head branch was pushed to by a user without write access

@laurogripa
Copy link
Copy Markdown
Contributor Author

@bkchr @sigurpol guys, thanks for the reviews and discussions!

I fixed the test and updated the benchmark with max payouts.
Regarding the other 2 issues, I left some comments, but not sure about the best approach.

It's night here, so I'll be back in 9 hours or so, but feel free to commit changes if you guys want.

kianenigma
kianenigma previously approved these changes Mar 5, 2026
@sigurpol
Copy link
Copy Markdown
Contributor

sigurpol commented Mar 5, 2026

/cmd bench --pallet pallet_society --runtime collectives-westend

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 5, 2026

Command "bench --pallet pallet_society --runtime collectives-westend" has started 🚀 See logs here

@sigurpol sigurpol added T2-pallets This PR/Issue is related to a particular pallet. A4-backport-stable2512 Pull request must be backported to the stable2512 release branch A4-backport-stable2603 Pull request must be backported to the stable2603 release branch labels Mar 5, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 5, 2026

Command "bench --pallet pallet_society --runtime collectives-westend" has failed ❌! See logs here

@bkchr
Copy link
Copy Markdown
Member

bkchr commented Mar 5, 2026

/cmd bench --pallet pallet_society --runtime kitchensink-runtime

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 5, 2026

Command "bench --pallet pallet_society --runtime kitchensink-runtime" has started 🚀 See logs here

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 5, 2026

Command "bench --pallet pallet_society --runtime kitchensink-runtime" has failed ❌! See logs here

@sigurpol sigurpol added this pull request to the merge queue Mar 5, 2026
Merged via the queue into paritytech:master with commit 695397f Mar 5, 2026
277 of 290 checks passed
paritytech-release-backport-bot bot pushed a commit that referenced this pull request Mar 5, 2026
Adds a kick_member extrinsic to pallet-society, callable by the Founder,
that removes a member,slashes its payout and returns funds to the
Society pot.

### Context
Recently, a collusion was discovered where a member managed to claim
membership without providing PoI. This change introduces a way for the
Founder to kick and slash the bad actors.

---------

Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: Paolo La Camera <paolo@parity.io>
(cherry picked from commit 695397f)
@paritytech-release-backport-bot
Copy link
Copy Markdown

Successfully created backport PR for stable2512:

paritytech-release-backport-bot bot pushed a commit that referenced this pull request Mar 5, 2026
Adds a kick_member extrinsic to pallet-society, callable by the Founder,
that removes a member,slashes its payout and returns funds to the
Society pot.

### Context
Recently, a collusion was discovered where a member managed to claim
membership without providing PoI. This change introduces a way for the
Founder to kick and slash the bad actors.

---------

Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: Paolo La Camera <paolo@parity.io>
(cherry picked from commit 695397f)
@paritytech-release-backport-bot
Copy link
Copy Markdown

Successfully created backport PR for stable2603:

sigurpol added a commit that referenced this pull request Mar 5, 2026
Backport #11154 into `stable2512` from laurogripa.

See the
[documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md)
on how to use this bot.

<!--
  # To be used by other automation, do not modify:
  original-pr-number: #${pull_number}
-->

---------

Co-authored-by: Lauro Gripa <laurogripa@gmail.com>
Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: Paolo La Camera <paolo@parity.io>
sigurpol added a commit that referenced this pull request Mar 5, 2026
Backport #11154 into `stable2603` from laurogripa.

See the
[documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md)
on how to use this bot.

<!--
  # To be used by other automation, do not modify:
  original-pr-number: #${pull_number}
-->

---------

Co-authored-by: Lauro Gripa <laurogripa@gmail.com>
Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: Paolo La Camera <paolo@parity.io>
@laurogripa laurogripa deleted the kick-member-society-extrinsic branch March 5, 2026 13:50
@sigurpol
Copy link
Copy Markdown
Contributor

sigurpol commented Mar 5, 2026

@laurogripa this is the PR in runtime that contains the fix: polkadot-fellows/runtimes#1101

@ggwpez
Copy link
Copy Markdown
Member

ggwpez commented Mar 13, 2026

Kicking happend here https://assethub-kusama.subscan.io/event/14290025-4

arturgontijo pushed a commit to moonbeam-foundation/polkadot-sdk that referenced this pull request Apr 1, 2026
Backport paritytech#11154 into `stable2512` from laurogripa.

See the
[documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md)
on how to use this bot.

<!--
  # To be used by other automation, do not modify:
  original-pr-number: #${pull_number}
-->

---------

Co-authored-by: Lauro Gripa <laurogripa@gmail.com>
Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: Paolo La Camera <paolo@parity.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A4-backport-stable2512 Pull request must be backported to the stable2512 release branch A4-backport-stable2603 Pull request must be backported to the stable2603 release branch T1-FRAME This PR/Issue is related to core FRAME, the framework. T2-pallets This PR/Issue is related to a particular pallet.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants