Liquid Staking

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

Uncontrolled Token Donations Lead to Zero Share Minting Vulnerability in StakingPool Contract

Summary

The StakingPool contract has a critical vulnerability related to the donateTokens function, which lacks proper access control. This allows any user to donate tokens to the pool, inflating the totalStaked value without minting corresponding shares. Additionally, due to the flawed share minting logic, users depositing small amounts of tokens after malicious donations are made will also fail to receive any shares, effectively locking them out of receiving staking rewards.

Vulnerability Details

1. Lack of Access Control in donateTokens()

  • The donateTokens() function allows any external user to transfer tokens to the pool and increase totalStaked. However, no corresponding shares are minted for these tokens, and totalShares remains unchanged.

  • This creates a scenario where the totalStaked value can grow due to token donations, but totalShares remains the same (or zero), leading to a discrepancy in the share allocation logic.

2. Share Minting Issue for Small Stake Deposits

  • The share minting logic depends on the relationship between totalStaked and totalShares. Specifically:

    function getSharesByStake(uint256 _amount) public view returns (uint256) {
    uint256 totalStaked = _totalStaked();
    if (totalStaked == 0) {
    return _amount;
    } else {
    return (_amount * totalShares) / totalStaked;
    }
    }
  • When a user deposits a small amount of tokens after malicious donations have inflated totalStaked but left totalShares low or at zero, the calculation in getSharesByStake() results in zero shares being minted for the depositor.

*Especially, before start of stake - if totalShares is zero but totalStaked is not zero because of attacker's donate, nobody can mint share tokens.

3. Exploit Scenario

  • Step 1: An attacker donates a large amount of tokens via the donateTokens() function, significantly inflating totalStaked.

  • Step 2: Because the donation does not mint any shares, totalShares remains zero or significantly lower than totalStaked.

  • Step 3: A legitimate user deposits a small amount of tokens. The calculation for minting shares results in zero due to the large totalStaked value and low totalShares.
    (If totalShare is 0 and totalStaked is not 0 because of attacker's donate, minting shares results will be always Zero)

  • Step 4: The legitimate user receives no shares in return for their deposit, effectively locking them out of rewards and pool participation.

Impact

The vulnerability has a significant impact on the pool's fairness and functionality:

  • Attackers can manipulate the totalStaked value without increasing totalShares, leading to future deposits receiving no shares.

  • Legitimate users making small stake deposits after a donation exploit will not receive any share tokens, preventing them from earning rewards or participating in the staking pool.

Tools Used

Recommendations

1. Add Access Control to donateTokens()

  • Restrict access to the donateTokens() function to only trusted parties, such as the contract owner or another designated role. This ensures that only authorized entities can donate tokens and prevents external users from manipulating totalStaked.

    function donateTokens(uint256 _amount) external onlyOwner {
    token.safeTransferFrom(msg.sender, address(this), _amount);
    totalStaked += _amount;
    emit DonateTokens(msg.sender, _amount);
    }

2. Adjust Share Minting Logic for Small Deposits

  • If share token amount is zero, it can be reverted.

  • Or make preview function for deposit. Users can see the amount of shares after deposit.

Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

donateTokens() allows a malicious user to manipulate the system in such a way that users may receive 0 shares.

Appeal created

inallhonesty Lead Judge
9 months ago
inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

[INVALID] Donation Attack

Support

FAQs

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