69890 sc low users won t be able to revoke migration permits from revoked migrators

Submitted on Mar 17th 2026 at 09:40:57 UTC by @AasifUsmani for Audit Comp | Folks Finance: Staking Contracts

  • Report ID: #69890

  • 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 before setting the migration flag checks if the migrator being used by caller is a valid migrator, if not, then the function reverts. So if a user permits a migrator, and later the migrator is revoked from the migrator role by the admin (maybe because of malicious behaviour or account takeover), then the user won't be able to revoke the permit because the setMigrationPermit() function will require the provided address to be a migrator.

Vulnerability Details

The setMigrationPermit function in Staking.sol allows users to approve an address to migrate their positions. However, it enforces that the _migrator address must currently hold the MIGRATOR_ROLE.

function setMigrationPermit(address _migrator, bool _isMigrationPermitted) external {
    if (!hasRole(MIGRATOR_ROLE, _migrator)) revert MigratorNotFound(_migrator); // @audit-issue Check prevents revocation if role is removed

    migrationPermits[_migrator][msg.sender] = _isMigrationPermitted;
    emit MigrationPermitUpdated(_migrator, msg.sender, _isMigrationPermitted);
}

If a migrator is compromised or acts maliciously, the admin would revoke their MIGRATOR_ROLE. Once this happens, the check if (!hasRole(MIGRATOR_ROLE, _migrator)) will cause any call to setMigrationPermit to revert.

This prevents users who had previously approved this migrator from revoking their approval. Their approval remains pending true in the migrationPermits mapping forever, unless the role is granted back.

Impact Details

If the MIGRATOR_ROLE is ever re-granted to the removed address (e.g., accidental admin action, or operational oversight), the previously removed actor would immediately regain the ability to migrate user positions without obtaining new consent. Users are essentially denied the ability to "clean up" their approvals and proactively secure their positions against a specific address.

Recommendations

Modify setMigrationPermit to allow users to set _isMigrationPermitted to false even if the _migrator does not have the role. The check should only be enforced when granting permission (setting it to true).

References

https://github.com/Folks-Finance/folks-staking-contracts/blob/3131a2d46b5afa76f606bf08adfd85452a47e2d8/src/Staking.sol#L77

Proof of Concept

  • To run the PoC, create a new file named MigrationPermit.t.sol in test/ folder.

  • copy/paste the given test suite in the newly created file.

  • Run the PoC with command forge test --mt test_CannotRevokePermitAfterMigratorRemoved -vvvv.

LOGS

Was this helpful?