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.
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.
The share minting logic depends on the relationship between totalStaked
and totalShares
. Specifically:
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.
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.
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.
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
.
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.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.