Skip to content

Careful Corduroy Scorpion - Inability to Reallocate Tokens due to Allocation Start Time Not Reset Upon Removal of allocation #143

@sherlock-admin3

Description

@sherlock-admin3

Careful Corduroy Scorpion

Medium

Inability to Reallocate Tokens due to Allocation Start Time Not Reset Upon Removal of allocation

Summary

When a user's allocation is removed via the removeOriginalAllocation function, the contract resets the user's allocation but does not reset the user's allocation start time. Consequently, if there's ever a need to reallocate tokens back to this user, it becomes impossible due to the condition:

  if ($.allocationStartTmie[recipients[i]] == 0) {
                // Check that the allocation start time is not in the past
                if (allocationStartTimes[i] < block.timestamp) {
                    revert StartTimeInPast();
                }
                $.allocationStartTime[recipients[i]] = allocationStartTimes[i];
            }

future reallocations become impossible or incorrectly calculated, as the original (now obsolete) start time persists.

Root Cause

The root cause lies in the allocate function logic:

if ($.allocationStartTmie[recipients[i]] == 0) {
                // Check that the allocation start time is not in the past
                if (allocationStartTimes[i] < block.timestamp) {
                    revert StartTimeInPast();
                }
                $.allocationStartTime[recipients[i]] = allocationStartTimes[i];
            }

Because removeOriginalAllocation fails to reset the allocationStartTime to zero, the above check prevents assigning new, accurate start times to users upon reallocation.

https://github.com/sherlock-audit/2025-02-usual-labs/blob/main/pegasus/packages/solidity/src/token/UsualSP.sol#L370C17-L370C58

Internal Pre-conditions

The user's allocation has previously been set and then removed without resetting the allocationStartTime field.

The storage variable allocationStartTime remains set (non-zero) after removal.

External Pre-conditions

There is a future requirement or intent to reallocate tokens to a previously removed user.

Attack Path

Operator calls removeOriginalAllocation on a user.

The user's allocations are zeroed, but allocationStartTime remains unchanged.

Later, attempting to reallocate tokens to this user will not set a new allocation start time due to the non-zero value already stored.

As a result, the user's new vesting calculation incorrectly references the old allocation start time, reducing their entitled tokens or blocking allocation altogether.

Impact

User will loose allocation if there is need to reallocate after being removed.

PoC

No response

Mitigation

Update the removeOriginalAllocation function to reset the user's allocation start time:

$.allocationStartTime[recipients[i]] = 0;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions