You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jan 12, 2025. It is now read-only.
BribeRewarder.deposit Will Always Revert, Blocking the Voting Mechanism
Summary
The BribeRewarder.deposit function will always revert when called by the Voter contract due to an incorrect token ownership check. This will lead to a Denial of Service (DOS) of the voting mechanism and subsequently block any rewards distribution.
Vulnerability Detail
Once a user stakes MLUM tokens, they receive an ERC721 token representing their staking position. This token allows them to vote by calling the Voter.vote function and providing the list of pools they want to vote on and their associated vote amounts.
The Voter.vote function, upon recording the user's vote, calls _notifyBribes to inform the BribeRewarder that the user has indeed voted on that specific pool. This makes the user eligible for additional reward distribution.
The issue arises at this step because _notifyBribes will invoke the BribeRewarder.deposit function to record the user's participation:
function deposit(uint256periodId, uint256tokenId, uint256deltaAmount) public onlyVoter {
_modify(periodId, tokenId, deltaAmount.toInt256(), false);
emitDeposited(periodId, tokenId, _pool(), deltaAmount);
}
As seen, this function calls BribeRewarder._modify, which contains a check to ensure that its caller (msg.sender) is always the ERC721 token owner, as highlighted below:
function _modify(uint256periodId, uint256tokenId, int256deltaAmount, boolisPayOutReward)
privatereturns (uint256rewardAmount)
{
//@audit will revert on deposit as msg.sender == Voter if (!IVoter(_caller).ownerOf(tokenId, msg.sender)) {
revertBribeRewarder__NotOwner();
}
...
}
This will cause the Voter's call to BribeRewarder.deposit to always revert because the function caller (msg.sender == address(Voter)) is not the real token owner. This will effectively DOS the voting mechanism for any pool that has implemented external bribes with BribeRewarder.
This issue will subsequently block all rewards distribution associated with pools that use external bribes (BribeRewarder).
Additionally, because the BribeRewarder.deposit function is only callable by the Voter contract (presence of the onlyVoter modifier), which is not the real token owner of the ERC721 tokens used during voting, the function will always revert and can never be called.
Impact
Complete DOS of the voting mechanism for pools that use BribeRewarder to include bribe rewards.
To address this issue, update the BribeRewarder._modify function to check that the original voter account (which called Voter.vote in the first place) is the real token owner. This can be done by checking the tx.origin address as follows (note that this change does not impact the claiming process):
sherlock-admin4
changed the title
Tall Porcelain Puppy - BribeRewarder.deposit Will Always Revert, Blocking the Voting Mechanism
Aymen0909 - BribeRewarder.deposit Will Always Revert, Blocking the Voting Mechanism
Jul 29, 2024
Aymen0909
High
BribeRewarder.deposit
Will Always Revert, Blocking the Voting MechanismSummary
The
BribeRewarder.deposit
function will always revert when called by the Voter contract due to an incorrect token ownership check. This will lead to a Denial of Service (DOS) of the voting mechanism and subsequently block any rewards distribution.Vulnerability Detail
Once a user stakes MLUM tokens, they receive an ERC721 token representing their staking position. This token allows them to vote by calling the
Voter.vote
function and providing the list of pools they want to vote on and their associated vote amounts.The
Voter.vote
function, upon recording the user's vote, calls_notifyBribes
to inform theBribeRewarder
that the user has indeed voted on that specific pool. This makes the user eligible for additional reward distribution.The issue arises at this step because
_notifyBribes
will invoke theBribeRewarder.deposit
function to record the user's participation:As seen, this function calls
BribeRewarder._modify
, which contains a check to ensure that its caller (msg.sender
) is always the ERC721 token owner, as highlighted below:This will cause the Voter's call to
BribeRewarder.deposit
to always revert because the function caller (msg.sender == address(Voter)
) is not the real token owner. This will effectively DOS the voting mechanism for any pool that has implemented external bribes withBribeRewarder
.This issue will subsequently block all rewards distribution associated with pools that use external bribes (
BribeRewarder
).Additionally, because the
BribeRewarder.deposit
function is only callable by the Voter contract (presence of theonlyVoter
modifier), which is not the real token owner of the ERC721 tokens used during voting, the function will always revert and can never be called.Impact
Complete DOS of the voting mechanism for pools that use
BribeRewarder
to include bribe rewards.Code Snippet
https://github.com/sherlock-audit/2024-06-magicsea/blob/main/magicsea-staking/src/rewarders/BribeRewarder.sol#L143-L147
https://github.com/sherlock-audit/2024-06-magicsea/blob/main/magicsea-staking/src/rewarders/BribeRewarder.sol#L260-L267
https://github.com/sherlock-audit/2024-06-magicsea/blob/main/magicsea-staking/src/Voter.sol#L221-L229
Tool used
Manual Review
Recommendation
To address this issue, update the
BribeRewarder._modify
function to check that the original voter account (which calledVoter.vote
in the first place) is the real token owner. This can be done by checking thetx.origin
address as follows (note that this change does not impact the claiming process):Duplicate of #39
The text was updated successfully, but these errors were encountered: