Mirror Protocol allows users to take long or short positions on tech stocks. To bet on a stock, you must lock collateral for a minimum of 14 days. After the trade concludes, they can unlock the collateral to release the funds back to their wallet.
What keeps track of this betting? A simple contract generated ID number that is returned to the user. The code takes in a list of IDs to use when withdrawing the collateral.
The Mirror Protocol does not check the duplication of a position ID within this list. As a result, an attacker can unlock the collateral of a position over and over again. In the real attack, the position 43186 was duplicated 437 times.
I would bet there was code to remove the usage of a particular ID from being withdrawn after this. However, the issue appears to be in the passing of the list.
To fix the bug, a for loop checks to ensure that no duplicate IDs are included to be unlocked. Interesting! Even code written in Rust can have security issues.