Submitted by ronnyx2017
https://github.com/Tapioca-DAO/tap-token/blob/20a83b1d2d5577653610a6c3879dff9df4968345/contracts/governance/twTAP.sol#L315
https://github.com/Tapioca-DAO/tap-token/blob/20a83b1d2d5577653610a6c3879dff9df4968345/contracts/options/TapiocaOptionBroker.sol#L261
There is a max magnitude lock check in the twTAP.participate function, it cant be greater than 4x the cumulative:
Because the param _duration cant be less than EPOCH_DURATION = 7 days = 604800, lets assume pool.cumulative is x, and solve for its minimum value without DoS:
Solution derived: the x, pool.cumulative, must be >= 123455.
The main issue is that, when a user participates the lock with divergenceForce = false, his participation will decrease pool.cumulative. Meanwhile, if there are positions previously entered with divergenceForce = true that are now exiting, then pool.cumulative will be reduced to below 123455.
TAP cannot be staked until pool.cumulative rises to 123455, and the system will remain under the DoS for even months until positions with divergenceForce = false can exit (arrive at the unlocking time). During this DoS period, the attacker has the potential to monopolize gov.
The same issue is also in the TapiocaOptionBroker. The following PoC uses the twTap as the exploit case.
Flow of attack:
So the twTAP will be DoS until the user2 (attacker) unlocks, which has to wait about 13.5 days. During this DoS period, the attacker is the only voter of the gov, the attack could have complete control of gov.
The above py script simulates the math process of the attack, print log:
Set the minimum threshold for the check, such as 7 days; if the duration meets EPOCH_DURATION <= duration <= minimum threshold || magnitude < pool.cumulative * 4, then lock-in is permitted.
Context
0xWeiss (Tapioca) acknowledged
Note: For full discussion, see here.
