69964 sc low users cannot revoke migration permission after migrator role revocation

Submitted on Mar 17th 2026 at 14:53:34 UTC by @psb01 for Audit Comp | Folks Finance: Staking Contracts

  • Report ID: #69964

  • Report Type: Smart Contract

  • Report severity: Low

  • Target: https://github.com/Folks-Finance/folks-staking-contracts/blob/main/src/Staking.sol

  • Impacts:

    • Contract fails to deliver promised returns, but doesn't lose value

Description

Brief/Intro

The setMigrationPermit function enforces that the _migrator must currently hold MIGRATOR_ROLE for both granting and revoking permissions.

As a result, if a migrator’s role is revoked, users are unable to revoke previously granted migration permissions, since any attempt to call:

setMigrationPermit(migrator, false)

will revert.

This creates a scenario where user approvals become non-revocable, leading to a loss of control over previously granted permissions.

Vulnerability Details

This check applies universally, regardless of whether the user is:

  • granting permission (true), or

  • revoking permission (false)

Thus, revocation is blocked when the migrator does not currently hold the role.

Additionally, migration permissions are not cleared after migration, meaning approvals persist even after a user’s positions have already been migrated. Combined with the inability to revoke permissions when the role is revoked, this leads to long-lived and user-uncontrollable approvals.

Impact Details

  • Users cannot revoke previously granted migration permissions once a migrator loses its role

  • Migration permissions may persist indefinitely, including after migration is completed

  • Users lose the ability to manage or invalidate their approvals

  • If the same migrator address later regains MIGRATOR_ROLE, previously granted permissions may still be active without any opportunity for the user to revoke them beforehand

This results in persistent, user-uncontrollable approvals, which can lead to unexpected migration behavior in the future.

References

Code: https://github.com/Folks-Finance/folks-staking-contracts/blob/main/src/Staking.sol?utm_source=immunefi#L77-L82

Proof of Concept

  1. Admin grants MIGRATOR_ROLE to a migrator.

  2. User stakes and opts in: setMigrationPermit(migrator, true)

  3. Admin revokes MIGRATOR_ROLE from migrator.

  4. User attempts to revoke: setMigrationPermit(migrator, false) → Transaction reverts.

Below is coded POC:

Was this helpful?