Skip to content
This repository has been archived by the owner on Nov 24, 2024. It is now read-only.

blackhole - The pool.lastRewardBlock should be updated in the setStartBlock function #142

Closed
sherlock-admin3 opened this issue May 24, 2024 · 2 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue Sponsor Disputed The sponsor disputed this issue's validity

Comments

@sherlock-admin3
Copy link
Contributor

sherlock-admin3 commented May 24, 2024

blackhole

medium

The pool.lastRewardBlock should be updated in the setStartBlock function

Summary

The admin can update the startBlock using the setStartBlock function.
However, during this update, pool.lastRewardBlock is not modified.
This can lead to incorrect pendingPoints calculations if the startBlock is set to an earlier block.
As a result, the pendingPoints will not be correctly distributed starting from the new startBlock.

Vulnerability Detail

File: contracts/farm/SophonFarming.sol#L279
    function setStartBlock(uint256 _startBlock) public onlyOwner {
        if (_startBlock == 0 || (endBlock != 0 && _startBlock >= endBlock)) {
            revert InvalidStartBlock();
        }
        if (getBlockNumber() > startBlock) {
            revert FarmingIsStarted();
        }
        startBlock = _startBlock; // @audit pool.lastRewardBlock should be updated...
    }
File: contracts/farm/SophonFarming.sol#L163
    function add(uint256 _allocPoint, address _lpToken, string memory _description, bool _withUpdate) public onlyOwner returns (uint256) {
        ...
        uint256 lastRewardBlock =
            getBlockNumber() > startBlock ? getBlockNumber() : startBlock;
        ...
    }
    

Impact

The pendingPoints will not be correctly distributed starting from the new startBlock.

Code Snippet

contracts/farm/SophonFarming.sol#L279

Tool used

Manual Review

Recommendation

It is recommended to update the poolInfo.lastRewardBlock in the setStartBlock function.

File: contracts/farm/SophonFarming.sol#L272
    function setStartBlock(uint256 _startBlock) public onlyOwner {
        if (_startBlock == 0 || (endBlock != 0 && _startBlock >= endBlock)) {
            revert InvalidStartBlock();
        }
        if (getBlockNumber() > startBlock) {
            revert FarmingIsStarted();
        }
        startBlock = _startBlock;

+        uint256 length = poolInfo.length;
+        for (uint256 pid = 0; pid < length; ++pid;) {
+            if (getBlockNumber() < poolInfo[pid].lastRewardBlock)
+                poolInfo[pid].lastRewardBlock = startBlock;
+        }
    }

Duplicate of #108

@github-actions github-actions bot added Medium A valid Medium severity issue Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels May 28, 2024
@sherlock-admin3
Copy link
Contributor Author

1 comment(s) were left on this issue during the judging contest.

0xmystery commented:

valid because lastRewardBlock for each pool should indeed sync with the latest startBlock

@sherlock-admin3 sherlock-admin3 added the Sponsor Disputed The sponsor disputed this issue's validity label May 31, 2024
@mystery0x
Copy link
Collaborator

This report should be valid as it described scenario 2 of #108.

@sherlock-admin3 sherlock-admin3 changed the title Fluffy Midnight Mallard - The pool.lastRewardBlock should be updated in the setStartBlock function blackhole - The pool.lastRewardBlock should be updated in the setStartBlock function Jun 1, 2024
@sherlock-admin3 sherlock-admin3 added the Reward A payout will be made for this issue label Jun 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue Sponsor Disputed The sponsor disputed this issue's validity
Projects
None yet
Development

No branches or pull requests

2 participants