Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: high
Invalid

`donateTokens` can be called by anyone

Summary

The donateTokens function in the Staking Pool contract lacks access control, allowing any external account to donate tokens and directly modify the totalStaked variable. This contradicts the function's intended use by protocol owners only for handling large slashing events.

Vulnerability details

function donateTokens(uint256 _amount) external { // @audit missing access control
token.safeTransferFrom(msg.sender, address(this), _amount);
totalStaked += _amount;
emit DonateTokens(msg.sender, _amount);
}

According to sponsor this function is designed for use by protocol owners, specifically in the event of a large slashing incident. And it should be restricted however currently there is no access control and anyone can call it.

Impact

  1. Artificial inflation of totalStaked can disrupt reward calculations and token economics.

  2. Repeated small or large donations could force users to deposit/withdraw less than they need, because it inflate totalStakedand this is used by canDeposit and canWithdraw

  3. Potential exploitation of dependent functions: canDeposit, canWithdraw, and _updateStrategyRewards may behave unexpectedly due to manipulated totalStaked.

Severity: High

Root cause and likelihood

Root cause: Mismatch between intended function use (protocol owners only) and implemented access control (public function).

Likelihood: High

  • The function is easily accessible in a core contract.

  • No barriers to exploit (e.g., high costs or complex prerequisites).

  • Potential for unintended consequences even without malicious intent.

Recommendations

First of all add access control to this function, and the implement the below suggestions also.

  1. Implement access control:

    function donateTokens(uint256 _amount) external onlyOwner {
    // existing implementation
    }
  2. Add donation limits:

    require(_amount >= MIN_DONATION && _amount <= MAX_DONATION, "Invalid donation amount");
  3. Implement a cool-down period:

    require(block.timestamp >= lastDonationTime + COOLDOWN_PERIOD, "Donation cooldown active");
    lastDonationTime = block.timestamp;
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Appeal created

0xtheblackpanther Submitter
about 1 year ago
inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.