This article analyzes the events and consequences of the minor bug found in Idle protocol and the related fix.
14th Dec 2020:
- MRKWHG, an Idle user and community member, informed the Idle team about a misallocation of IDLE tokens in the dashboard, as the amount of the day before was slightly higher than the day after. He also provided some example transactions and more details about the odd behavior.
- Idle team started the inspection and immediately alerted Quantstamp about the inquiry.
- Both teams worked side-by-side to investigate the issue, identifying the vulnerability and working on the off-chain temporary mitigation patch.
- An off-chain patch has been applied to mitigate possible further misallocations.
15th Dec 2020:
- The patch has been developed and the new implementation contract has been deployed and verified on Etherscan
- Quantstamp published the IIP-1 in the Forum and the blog post to disclose the bug.
- Quantstamp initiated the on-chain proposal (with a 3-day voting window).
18th Dec 2020:
- The proposal successfully passed and then queued for execution.
20th Dec 2020:
- The proposal has been executed and the minor issue has been permanently solved.
The bug involved the accounting of governance tokens (COMP and IDLE) distributed by the contract to Idle liquidity providers.
Two types of indexes for each governance token are implemented in Idle protocol:
- a per-user index
- a global index
Those indexes calculate how many COMP and IDLE each user should receive.
Each time a user deposits, their per-user index is updated to match the current global index.
When a user redeems assets, the transaction claims COMP and IDLE tokens from the respective controllers using
claimIdle. This action updates the global index along with the per-user index.
During deposits, the global index was not updated and caused the misallocation.
For instance, let’s suppose that nobody redeemed tokens in a specific pool for 3 days. By depositing assets in that pool, the per-user index of the depositor is updated and set equal to the global index (which in turn was updated 3 days ago). This means that the user would be entitled to receive proportional governance tokens (and immediately redeem them) as if they had deposited 3 days before, instead of just a few minutes earlier.
The misallocation was noticeable only when depositing a large amount of assets into Idle protocol, and because mint and redeem are not allowed in the same transaction, flash-loans were ineffective in this case.
Off-chain and on-chain patch implementation
Idle protocol adopted decentralized governance on November 26th 2020, so there is no way to directly modify the contracts.
Idle Labs and Quantstamp temporary mitigated this bug by frequently calling (once per hour) the public
claimComp directly from Idle and Compound’s controllers. This represented the off-chain patch.
When the patch was live, the constant redeem of governance tokens caused the update of the global index, mitigating the misallocation of governance tokens during new deposits.
The on-chain patch was quite straightforward: by changing a flag (https://github.com/Idle-Labs/idle-contracts/commit/ad0f18fef670ea6a4030fe600f64ece3d3ac2202), the protocol can now allow to update both the global and the per-user index during deposits.
If you want to get more details about the fix, you can check:
As a side note, another minor fix has been made in the same commit (the
whenPaused modifier), in order to avoid the use of
redeemInterestBearingTokens to not pay protocol fees.
After the investigation, we estimate that the misallocation of funds affected 234.17 IDLE and 0.49 COMP.
We are thankful to the user who reported this and we awarded him a 1.5 ETH bug-bounty reward.