Perfect Currant Cow
Medium
An usualS blacklisted address cannot claim their originalAllocation
balance, but still can enjoy the rewards harvesting from it
No response
In UsualSP.sol, a user typically earn Usual reward tokens through two primary methods,
- via holding onto their
usualS
originalAllocation(by not claiming) - or via staking
usualS
tokens
If users are currently in state (1) and get blacklisted by the UsualS
token (possibly due to engaging in illicit activities), any transactions involving the transfer of UsualS
tokens "to" or "from" their address are likely to fail, as shown below
https://github.com/sherlock-audit/2024-10-usual-labs-v1/blob/4fb4a64a479e0b9b8f93934220e891c29d54df33/pegasus/packages/solidity/src/token/UsualSP.sol#L254 https://github.com/sherlock-audit/2024-10-usual-labs-v1/blob/4fb4a64a479e0b9b8f93934220e891c29d54df33/pegasus/packages/solidity/src/token/UsualS.sol#L240
The problem is that even after being blacklisted, such accounts can still harvest their Usual
token rewards by calling the claimReward()
function. This is due to fact the unclaimed originalAllocation
counted towards the user shares balance, which is directly used to calculate the accrued rewards.
function balanceOf(address account) public view override returns (uint256) {
UsualSPStorageV0 storage $ = _usualSPStorageV0();
return
$.liquidAllocation[account] + $.originalAllocation[account] - $.originalClaimed[account]; // @audit
}
function _earned(address account) internal view virtual returns (uint256 earned) {
RewardAccrualBaseStorageV0 storage $ = _getRewardAccrualBaseDataStorage();
uint256 accountBalance = balanceOf(account); // @audit
uint256 rewardDelta = $.rewardPerTokenStored - $.lastRewardPerTokenUsed[account];
earned = accountBalance.mulDiv(rewardDelta, 1e24, Math.Rounding.Floor) + $.rewards[account]; // 1e24 for precision loss
}
The blacklisted address by usualS contract are indirectly utilizing usualS balance(because its unclaimed yet) to earn usual token rewards.
No response
function claimReward() external nonReentrant whenNotPaused returns (uint256) {
UsualSPStorageV0 storage $ = _usualSPStorageV0();
+ if ($.usualS.isBlacklisted(msg.sender) revert Blacklisted();
if (block.timestamp < $.startDate + ONE_MONTH) {
revert NotClaimableYet();
}
return _claimRewards();
}