user.rewardSettled become always zero due to the way user.rewardDebt is being calculated and deducted from user.rewardSettled.
Summary
The SophonFarming.sol contract has an issue in both the _deposit() and withdraw() functions where the user.rewardSettled calculation can become inaccurate due to the way user.rewardDebt is being calculated. The current implementation deducts the total user.rewardDebt based on the entire user.amount, potentially leading to incorrect reward calculations.
Vulnerability Detail
In the _deposit() and withdraw() function, the current user.rewardSettled is calculate by user.amount and reducing the user.rewardDebt calculated previously. So the user.rewardSettled and user.rewardDebt are always same. This can lead to inaccuracies in reward calculations the user.rewardSettled become always zero.
Impact
The impact of this issue is that users may not receive the correct amount of rewards when they deposit funds to the contract.
Code Snippet
function _deposit(uint256 _pid, uint256 _depositAmount, uint256 _boostAmount) internal {
if (isFarmingEnded()) {
revert FarmingIsEnded();
}
if (_depositAmount == 0) {
revert InvalidDeposit();
}
if (_boostAmount > _depositAmount) {
revert BoostTooHigh(_depositAmount);
}
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
updatePool(_pid);
uint256 userAmount = user.amount;
@--> user.rewardSettled =
userAmount *
pool.accPointsPerShare /
1e18 +
user.rewardSettled -
user.rewardDebt;
}
userAmount * pool.accPointsPerShare / 1e18 is used to calculate the users points and user.rewardDebt also uses the same calculation, so that user.rewardSettled always become zer0.
Tool used
Manual Review
Recommendation
Both the _deposit() and withdraw() functions should be updated to calculate the user.rewardDebt based on the actual amount being deposited or withdrawn rather than the whole user.amount. This will ensure that users receive the correct amount of rewards when they interact with the contract.
0xAadi
high
user.rewardSettled
become always zero due to the wayuser.rewardDebt
is being calculated and deducted fromuser.rewardSettled
.Summary
The
SophonFarming.sol
contract has an issue in both the_deposit()
andwithdraw()
functions where theuser.rewardSettled
calculation can become inaccurate due to the wayuser.rewardDebt
is being calculated. The current implementation deducts the totaluser.rewardDebt
based on the entireuser.amount
, potentially leading to incorrect reward calculations.Vulnerability Detail
In the
_deposit()
andwithdraw()
function, the currentuser.rewardSettled
is calculate byuser.amount
and reducing theuser.rewardDebt
calculated previously. So theuser.rewardSettled
anduser.rewardDebt
are always same. This can lead to inaccuracies in reward calculations theuser.rewardSettled
become always zero.Impact
The impact of this issue is that users may not receive the correct amount of rewards when they deposit funds to the contract.
Code Snippet
https://github.com/sherlock-audit/2024-05-sophon/blob/05059e53755f24ae9e3a3bb2996de15df0289a6c/farming-contracts/contracts/farm/SophonFarming.sol#L574C1-L595C29 https://github.com/sherlock-audit/2024-05-sophon/blob/05059e53755f24ae9e3a3bb2996de15df0289a6c/farming-contracts/contracts/farm/SophonFarming.sol#L699C1-L725C29
userAmount * pool.accPointsPerShare / 1e18
is used to calculate the users points anduser.rewardDebt
also uses the same calculation, so thatuser.rewardSettled
always become zer0.Tool used
Manual Review
Recommendation
Both the
_deposit()
andwithdraw()
functions should be updated to calculate theuser.rewardDebt
based on the actual amount being deposited or withdrawn rather than the wholeuser.amount
. This will ensure that users receive the correct amount of rewards when they interact with the contract.