Liquid Staking

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

Wrong parameter emitted in the `Transfer` event will give false information to owners

Summary

Wrong parameter is emitted in StakingRewardsPool::_transferShares()'s Transfer event, which will give provide false information to protocol owners.

Vulnerability Details

Here is the internal _transferShares():

function _transferShares(address _sender, address _recipient, uint256 _sharesAmount) internal {
require(_sender != address(0), "Transfer from the zero address");
require(_recipient != address(0), "Transfer to the zero address");
require(shares[_sender] >= _sharesAmount, "Transfer amount exceeds balance");
shares[_sender] -= _sharesAmount;
shares[_recipient] += _sharesAmount;
@> emit Transfer(_sender, _recipient, getStakeByShares(_sharesAmount));
}

if we look at the IERC20Upgradeable::Transfer() event:

/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);

It states that the value amount should be the transfered tokens. Notice that the in _transferShares() the shares amount is deducted from sender and added to recipient's account, so the moved amount is _sharesAmount. For example StakingRewardsPool::_transfer(), _mint(), _burn() are using this pattern:

function _transfer(address _sender, address _recipient, uint256 _amount) internal override {
uint256 sharesToTransfer = getSharesByStake(_amount);
...
shares[_sender] -= sharesToTransfer;
shares[_recipient] += sharesToTransfer;
!!!!!!!!
emit Transfer(_sender, _recipient, _amount);
}
function _mint(address _recipient, uint256 _amount) internal override {
uint256 sharesToMint = getSharesByStake(_amount);
_mintShares(_recipient, sharesToMint);
!!!!!!!!
emit Transfer(address(0), _recipient, _amount);
}
function _burn(address _account, uint256 _amount) internal override {
uint256 sharesToBurn = getSharesByStake(_amount);
...
totalShares -= sharesToBurn;
shares[_account] -= sharesToBurn;
!!!!!!!
emit Transfer(_account, address(0), _amount);
}

Tools Used

Manual Review

Recommendations

function _transferShares(address _sender, address _recipient, uint256 _sharesAmount) internal {
require(_sender != address(0), "Transfer from the zero address");
require(_recipient != address(0), "Transfer to the zero address");
require(shares[_sender] >= _sharesAmount, "Transfer amount exceeds balance");
shares[_sender] -= _sharesAmount;
shares[_recipient] += _sharesAmount;
- emit Transfer(_sender, _recipient, getStakeByShares(_sharesAmount));
+ emit Transfer(_sender, _recipient, _sharesAmount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Appeal created

dimah7 Submitter
about 1 year ago
dimah7 Submitter
about 1 year ago
inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope
Assigned finding tags:

[INVALID] Incorrect event data in `StakingPool::transferShares`

Support

FAQs

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