code-423n4 / 2023-06-lybra-findings

8 stars 7 forks source link

flashloan stealing staking reward #990

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-06-lybra/blob/7b73ef2fbb542b569e182d9abf79be643ca883ee/contracts/lybra/miner/stakerewardV2pool.sol#L107

Vulnerability details

Impact

The report reveals a vulnerability where a flashloan can be used to steal staking rewards. The provided proof of concept demonstrates the issue, where a user can take advantage of the earned rewards calculation using the spot balance. By flashloaning a large amount of tokens, staking them, and immediately withdrawing, the user can unfairly claim a significant portion of the staking rewards.

Proof of Concept

function stake(uint256 _amount) external updateReward(msg.sender) {
    require(_amount > 0, "amount = 0");
    bool success = stakingToken.transferFrom(msg.sender, address(this), _amount);
    require(success, "TF");
    balanceOf[msg.sender] += _amount;
    totalSupply += _amount;
    emit StakeToken(msg.sender, _amount, block.timestamp);
}

function withdraw(uint256 _amount) external updateReward(msg.sender) {
    require(_amount > 0, "amount = 0");
    balanceOf[msg.sender] -= _amount;
    totalSupply -= _amount;
    stakingToken.transfer(msg.sender, _amount);
    emit WithdrawToken(msg.sender, _amount, block.timestamp);
}

modifier updateReward(address _account) {
    rewardPerTokenStored = rewardPerToken();
    updatedAt = lastTimeRewardApplicable();

    if (_account != address(0)) {
        rewards[_account] = earned(_account);
        userRewardPerTokenPaid[_account] = rewardPerTokenStored;
        userUpdatedAt[_account] = block.timestamp;
    }
    _;
}

function earned(address _account) public view returns (uint256) {
    return ((balanceOf[_account] * getBoost(_account) * (rewardPerToken() - userRewardPerTokenPaid[_account])) / 1e38) + rewards[_account];
}

The vulnerability stems from the fact that the earned function calculates rewards based on the user's balance (balanceOf). By flashloaning a significant amount of tokens, staking them, and immediately withdrawing, users can manipulate the balance and claim a higher portion of the staking rewards than they should be entitled to.

Tools Used

Manual Review

Recommended Mitigation Steps

To address this vulnerability, it is recommended to avoid using the spot balance (balanceOf) to calculate rewards. Instead, consider using a different approach that mitigates the risk of flashloan-based manipulation. By employing alternative methods to calculate rewards that are not affected by flashloaned tokens, the vulnerability can be effectively mitigated.

Assessed type

Token-Transfer

JeffCX commented 1 year ago

Insufficient proof, recommend provide POC

c4-pre-sort commented 1 year ago

JeffCX marked the issue as primary issue

c4-pre-sort commented 1 year ago

JeffCX marked the issue as low quality report

c4-judge commented 1 year ago

0xean marked the issue as unsatisfactory: Insufficient proof