88mph Incident: Root Cause Analysis
Started at 08:26:52 PM +UTC, Nov-17–2020, 88mph was attacked by exploiting a business logic error in the DInterest
smart contract. The hack results in maliciously minting approximately $100K worth of MPH tokens. Later, the hacker transferred the funds to the MPH-ETH UniswapV2 pool. With the help of the legendary whitehat, samczsun, the dev team exploited another bug in the MPHMinter
contract to drain the Uniswap pool for rescuring existing funds and getting the hacked funds back. Here we elaborate the technical details of these two bugs in this blog post.
Summary
88mph is a fixed-rate yield-generation protocol on Ethereum that allows users to deposit assets, earn fixed-rate interests, and farm for MPH tokens. However, it has a flaw in the deposit, funding, early withdrawal
process which fails to burn the MPH tokens minted to the funder. By repeating this flow for many times, the hacker successfully minted $100K worth of MPH from nothing.
Details
The MPH mint Hack Walk-through
We started the analysis from three transactions behind the hack ( 0xde89…7772, 0x64a3…f418, 0x404f….e32f) which are initiated from an EOA address (located at 0x7675…b0Ae).
- Step 1: Deposit
stablecoin
into the pool by calling theDInterest::deposit()
function. With those deposited assets collected, two things happen in theDInterest
smart contract. 1) A newdepositID
is allocated and assigned to the depositor (msg.sender
) as an NFT token; 2) TheMPHMinter
contract mints MPH tokens to the depositor based on the interest rate model.
- Step 2: Fund previous deposits by
fundAll()
. With the fundingstablecoin
collected: 1) A newfundingID
is allocated and assigned to the funder (msg.sender
) as an NFT token; 2) MPH tokens are minted to the funder.
- Step 3: Withdraw the funded deposit in Step 1 with the newly created
fundingID
Step 2. As shown in Figure 3, thestablecoin
are refunded to the depositer and funder. However, theMPHMinter
only takes back depositor’s MPH tokens but the funder keeps the MPH tokens with all fundingstablecoin
returned. This enables the bad actor to mint MPH tokens from nothing. By repeating this 3-step flow, the hacker minted $100K worth of MPH tokens.
Drain the MPH-ETH UniswapV2 Pool
For rescuring existing funds and recovering the hacked funds, the MPH-ETH UniswapV2 pool was drained by this tx ( 0xe2e0…72e0 ) by exploiting a bug is in the MPHMinter
contract.
- Step 1: Withdraw the MPH in MPH-ETH UniswapV2 pool to
govTreasury
by calling theMPHMinter::takeBackDepositorReward()
(Figure 5). Since there is no restriction on this function, anyone can call this function to send anyone’s MPH token togovTreasury
.
- Step 2: Drain the pool with just a few MPH tokens. Since many of the MPH tokens are transferred to
govTreasury
, the MPH tokens in Uniswap are very valuable. Therefore, the dev team successfully swap the ether out from the pool with just a few MPH tokens.
Aftermath
Since the hacker put all the tokens back to the MPH-ETH pool and the dev team drained the pool with another bug, there is no loss after the rescue.
About Us
PeckShield Inc. is an industry leading blockchain security company with the goal of elevating the security, privacy, and usability of the current blockchain ecosystem. For any business or media inquiries (including the need for smart contract auditing), please contact us at telegram, twitter, or email.