Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent Checkpoint Updates in VirtualRewarderCheckpoints.writeCheckpoint() #56

Open
hats-bug-reporter bot opened this issue Jul 15, 2024 · 1 comment
Labels
bug Something isn't working duplicate This issue or pull request already exists

Comments

@hats-bug-reporter
Copy link

Github username: --
Twitter username: --
Submission hash (on-chain): 0x414a5ff840357199b971057ea08e9ec4b2a8a0de477fbc8fb7d9d67cf3d8625e
Severity: medium

Description:
Description
The VirtualRewarderCheckpoints.writeCheckpoint() function in the SingelTokenVirtualRewarderUpgradeable contract may not correctly handle multiple updates within the same block. This can lead to inconsistencies in the recorded checkpoints, potentially causing incorrect state representation for token balances and total supply. The function uses an in-memory read of the last checkpoint and updates it if the timestamp matches the current block's timestamp. This approach can lead to issues when multiple updates occur within the same block, as only the last update will be recorded, potentially overwriting previous updates within the same block.

Attack Scenario\

Initial State:

User A has a balance of 100 tokens.
The total supply is 1000 tokens.

Multiple Updates in the Same Block:

User A deposits 50 tokens(using deposit function).
User A withdraws 30 tokens(using withdraw function).

Expected Behavior:

Two separate checkpoints should be recorded, one for the deposit and one for the withdrawal.

Actual Behavior:

Only one checkpoint is recorded, reflecting the final state after both operations, potentially missing intermediate state changes.

Attachments

  1. Proof of Concept (PoC) File
  • writeCheckpoint Function:
function writeCheckpoint(
    mapping(uint256 index => Checkpoint checkpoint) storage self_,
    uint256 lastIndex_,
    uint256 timestamp_,
    uint256 amount_
) internal returns (uint256 newIndex) {
    Checkpoint memory last = self_[lastIndex_];//@audit-using memory

    newIndex = last.timestamp == timestamp_ ? lastIndex_ : lastIndex_ + 1;

    self_[newIndex] = Checkpoint({timestamp: timestamp_, amount: amount_});
}

  1. Revised Code File (Optional)
@hats-bug-reporter hats-bug-reporter bot added the bug Something isn't working label Jul 15, 2024
@0xmahdirostami
Copy link
Collaborator

I think this issue is similar to #43 as it explains the same consequences of writing checkpoint multiple times inside a block /
Lack of POC + further explanations

@0xmahdirostami 0xmahdirostami added the duplicate This issue or pull request already exists label Jul 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

1 participant