-
Notifications
You must be signed in to change notification settings - Fork 6
ChinmayF - Voting and bribe rewards can be hijacked during emergency unlock by already existing positions #290
Comments
During emergency unlock, adding to existing positions can increase voting power and manipulate the voting process. This can unfairly affect voting outcomes and rewards. |
These issues all focus on how the system can be abused during emergency unlocking, which can have negative consequences for users and the contract. The main goal is to ensure that only safe and fair transactions are made during emergency unlocking, and to prevent malicious users from exploiting system vulnerabilities to gain unfair advantage. |
The protocol team fixed this issue in the following PRs/commits: |
Escalate There are many duplication errors here, out of which most issues are invalid in reality. These are listed below:
Apart from these listed, other issues seem to be valid duplicates of #290. |
You've created a valid escalation! To remove the escalation from consideration: Delete your comment. You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final. |
Hey @chinmay-farkya @0xSmartContract , #15 clearly describes precisely the issue of the main submission. Being able to add liquidity on a paused contract is by itself already a medium impact. While the main issue described another medium impact (that leverages this), #15 should stay a valid dup. |
I think this issue should be grouped with #138 or low. Both have the same root cause of: addToPosition allowing to higher voting power. I would also want to point out that this issue describes an extreme edge case Szenario:
Hench I would consider the impact of this issue to be low. |
Your issue 15 does not identify any valid attack path. Simply stating that liquidity can be added while paused cannot be considered as a medium impact unless it can be shown to have second order effects or a loss/manipulation of some kind. This issue 290 describes such an impact of misuse of the voting power while 15 does not identify it. |
@0xSmartContract |
The assertion that this issue is same as #138 is incorrect because #138 is talking about how you can keep the position active with the same multiplier(and thus gain unfair share of rewards) under "normal operations of the system" due to the use of initialLockDuration, while this issue 290 talks about how during "only an emergencyUnlock" (and not under normal operations like #138) the positions can be gamed to immediately gain extra voting power and manipulate the voting data. Both have separate root causes : core issue of 138 is that initialLockDuration is used for assigning multiplier "under normal operation" Both have separate fixes : These are clearly two separate issues. |
I agree with @J4X-98 regarding the validity of issues based simply on the possibility to add liquidity to a paused contract. Also, issue #131 describes this impact which can be mitigated in the same way as the main issue. Your report - #290 is indeed presenting a valid attack vector that is possible based on the impact described by #131. I simply did not state what the malicious could do with the additional voting power. It is not a valid argument for invalidating an issue, rather a justification for the main issue to be chosen for the report. |
Well we are governed by sherlock's rules for valid duplications. Its not a justification for an issue getting chosen for the report, but for what counts as a valid duplicate and what does not.
|
You're right. I should reiterate my reply. Adding liquidity to a paused contract is an attack vector - it's very straight forward because the bug is quite simple. What you have presented is additional impact of the attack vector. With this in mind, we may go through the requirements for a valid duplicate from the rules you have cited for issue #131: My #131 finding is therefore a valid duplicate according to the rules. What you provided is additional impact based on the root cause and primary impact, as @J4X-98 commented. Note that I'm referring to my issue #131, I did not review other escalated findings. |
Pausing is a security feature (like for example blacklisting) which is clearly bypassed and that's also described in our issue. This is medium on any platform. Just because you found another medium impact it doesn't mean that all other medium impacts resulting out of the same root cause are invalid. |
Well @J4X-98 now I'm curious to know when did "adding liquidity while paused" become a medium impact in itself. I disagree because if the liquidity they are adding during a paused state can be withdrawn later, and as long as it does not affect anything else in the system (like rewards etc.), it is not a medium impact but a low one. |
Pausing means the protocol is paused e.g. no one can add or withdraw liquidity. The same way it is in any other DEX, vault etc. that's the whole reasoning behind it. This is broken by the implementation. I don't think discussing with you makes any sense if this is not clearly a medium to you. I've already added my info for the judge and will wait for his judging. |
This issue can be grouped with #138 |
This and #138 are completely different issues #138 :
#290 :
|
This issue can be grouped with #138 They have similar root causes: Both issues are related to the position update logic in the MlumStaking contract. Issue 138 is related to incorrect multiplier calculation when adding to positions, while issue 290 is related to adding to positions during emergency locks. They have interrelated effects: Both issues can affect users’ voting power and rewards. 138 allows users to get higher multipliers, while 290 allows voting manipulation during emergency locks. Overlapping of solutions: To solve both issues, it is necessary to change the behavior of the addToPosition() function. These changes can be considered together to provide a more comprehensive solution. Both issues are related to the position management and locking logic in the MlumStaking contract. For these reasons, combining issues 138 and 290 can provide a more holistic and efficient solution, and it is a nice duplicate of these two to improve the overall code quality. We are hearing from only @chinmay-farkya about grouped with 138 , this is not healthy, I would like to get comments from many valid Watsons on this issue |
I think grouping these issues is not the right way ahead. Our issue #15 describes that pausing does not correctly work which is in no way related to #138. Grouping should be done based on the root cause not based on which issues affect a similar part of the code. Just because there are separate issues in the same function, they can not just be grouped into one. |
As stated before this group of issues and #138 are completely different issues. They just occur in a similar part of the code but have different root causes, different scenarios and different mitigations. |
@0xSmartContract I don't know why you are saying that this is similar to #138 . These are two completely different issues with different fixes, root causes, and affecting different mechanisms. One is about lockDuration and multipliers, the other (this #290) is about manipulating the vote amount via addPOsition instead. It is not even remotely related to that as pointed in my comment here. Bugs manifest in completely different situations (the multiplier issue #138 will not even happen in case of emergency Unlocks but the lock amount s can only be manipulated in case of emergencyUnlock).
While the protocol team may need to comprehensively look at all bugs together, that doesn't mean that the issues are duplicates. While fixing any issue, the team will always need to look at the fix's effects on the whole system, does that make all the issues of a contract under one duplicate ? |
Here I agree with @chinmay-farkya regarding the differences between both issues. While both stem from a malfunction in the same function, they can be considered independent of each other. Issue #138 involves incorrect staking logic, whereas issue #290 pertains to unrestricted access control. The solution for the former involves changing the multiplier calculation logic, while the latter requires implementing a proper access control mechanism. The consequences of the malfunction and the solutions for each issue are not interconnected. Unless both solutions can be addressed with a single approach, I wouldn’t consider them related. |
About issues mentioned in the escalation comment:
I agree it's not a duplicate of #138 based on this, this and this comments. Let me know if you want a deeper analysis of these 2 issues, but I don't see a point in me repeating the same arguments another time. Planning to accept the escalation, invalidate 8 issues above and keep this a separate high severity family. |
Result: |
Escalations have been resolved successfully! Escalation status:
|
Hey @WangSecurity did you intend to keep this as high severity ? Your previous comment says this :
|
Yes, you’re correct, excuse me for the typo, I meant to keep this as medium as it was initially. But if you have arguments disputing the severity, please share them. |
I think it is medium, so we'll settle it down. |
The Lead Senior Watson signed off on the fix. |
ChinmayF
High
Voting and bribe rewards can be hijacked during emergency unlock by already existing positions
Summary
There are many ways of modifying an already existing staking position : but they exhibit different behavior when an emergency unlock is made active.
renewLock()
andextendLock()
are straight away disallowed.withdrawFromPosition()
andemergencyWithdraw()
are allowed but it can only pull out assets and not do anything else.addToPosition()
is a different case, it has no restrictions even when the emergency unlock is active. This can be used by an attacker to modify pre-existing position to vote with a new amount in Voter.This is a big problem because all other ways of starting, or renewing a staking position are blocked.
Vulnerability Detail
If a position already exists before the emergency unlock started, the owner of such positions can add amounts to them, and use this new amount for voting in the current voting period.
All other existing positions can also vote, but no new amount of assets can enter the voting circle because :
Now because no new assets can enter the voting amount circulation during this period, this creates a monopoly for already existing positions to control the voting outcome with lesser participants on board.
This can be particularly used by an attacker to hijack the voting process in the following steps :
addToPosition()
, they can plan in advance and open many many 1 wei staking positions with long lock duration (such that they are eligible for voting based on minimumLockTime etc. in Voter.sol) and wait for the emergency unlock.In this way, an attacker can gain monopoly over the votes during an emergencyUnlock, which ultimately influences the LUM emissions directed to certain pools.
Impact
Voting process can be manipulated during an emergencyUnlock using pre-existing positions. This also leads to a hijack of the bribe rewards if any bribe rewarders are set for those pools.
High severity because this can be used to unfairly influence the voting outcome and misdirect LUM rewards, which is the most critical property of the system. Also this is unfair to all other voters as they lose out on bribe rewards, and the attacker can get a very high share of it.
Code Snippet
https://github.com/sherlock-audit/2024-06-magicsea/blob/42e799446595c542eff9519353d3becc50cdba63/magicsea-staking/src/MlumStaking.sol#L397
Tool used
Manual Review
Recommendation
This can be solved by simply disallowing any activity apart from emregencyWithdraw during the time when emergencyUnlock is active. Apply the check used in _lockPosition() to addToPosition() too.
The text was updated successfully, but these errors were encountered: