88mph Incident: Root Cause Analysis

PeckShield
4 min readNov 20, 2020

--

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 the DInterest::deposit() function. With those deposited assets collected, two things happen in the DInterest smart contract. 1) A new depositID is allocated and assigned to the depositor (msg.sender) as an NFT token; 2) The MPHMinter contract mints MPH tokens to the depositor based on the interest rate model.
Figure 1: Deposit Assets
  • Step 2: Fund previous deposits by fundAll(). With the funding stablecoin collected: 1) A new fundingID is allocated and assigned to the funder (msg.sender) as an NFT token; 2) MPH tokens are minted to the funder.
Figure 2: Funding Previous Deposits
  • Step 3: Withdraw the funded deposit in Step 1 with the newly created fundingID Step 2. As shown in Figure 3, the stablecoin are refunded to the depositer and funder. However, the MPHMinter only takes back depositor’s MPH tokens but the funder keeps the MPH tokens with all funding stablecoin 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.
Figure 3: Early Withdraw the Funded Deposit

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.

Figure 4: Rescue Transaction
  • Step 1: Withdraw the MPH in MPH-ETH UniswapV2 pool to govTreasury by calling the MPHMinter::takeBackDepositorReward() (Figure 5). Since there is no restriction on this function, anyone can call this function to send anyone’s MPH token to govTreasury.
Figure 5: takeBackDepositorReward()
  • 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.

--

--