On April 21st 2023 an exploiter was able to abuse the UDT reward system from the Unlock contract.
The Unlock contract distributes UDT governance tokens for transactions that purchase NFT memberships (check our docs for more details on the mechanism). In a nutshell, each PublicLock contract calls the recordKeyPurchase
on the Unlock contract with a referrer
address, as well as the value
of the transaction. Then, the Unlock contract computes the amount of UDT tokens to be transferred to the referrer as a reward.
recordKeyPurchase
is critical and does include a mechanism to verify that its caller is indeed a PublicLock contract.postLockUpgrade
which lock contracts are calling when they are completing their upgrade.A malicious actor was able to trick the Unlock
contract to distribute UDT rewards held by it. The attack happened in 2 phases.
Unlock
contract’s postLockUpgrade
in order to register themselves as a deployed lock: https://etherscan.io/tx/0x4ac413c3c6edd445d1f09cd770d6aafab19b0b58fde7d0cefc74e17265033ef6
recordKeyPurchase
from their “fake lock contract” in order to transfer small amounts of UDT tokens out of the contract. They repeated that 17,760 times, through multiple transactions like these ones one:
Each of these transaction calls recordKeyPurchase
multiple times in order to accrue as much UDT as possible.
We estimate that a total of 21,147.32 UDT were transferred from the Unlock contract.
recordKeyPurchase
, 20% of the stolen tokens were transmitted to an Unlock owned multisig (0x9168eabe624e9515f3836ba1716ec1ddd4c461d4
) which now owns 4,229.46 UDT (exactly 20%).These tokens were immediately swapped using Uniswap as part of the transactions on which they are rewarded.
First, the team submitted an emergency upgrade to the Unlock contract that includes the following:
We have also: