Platypus Finance Hack Analysis

Apr 15, 2024
Gul Hameed
5 min
DeFi, hack analysis
Platypus Hack Analysis

Platypus Finance is a decentralized finance (DeFi) platform. On February 17, 2023, the platform was hacked, resulting in a loss of approximately $8.5 million worth of assets. In this hack analysis, we will delve into the details of the attack, the vulnerability that was exploited, and the impact it had on the platform and its users.

Hack Impact

The financial implications of this exploit are substantial, with the attacker managing to siphon off a significant amount of funds. By exploiting the vulnerability in the emergencyWithdraw function of the MasterPlatypusV4 contract in Platypus Finance. This enable the attacker to create “bad debt” in the system, allowing them to acquire the debt’s upside.

As a result, the attack significantly impacted the Platypus Finance ecosystem and its users. The attack led to a loss of about $8.5 million in tokens. It caused a sharp decline in USP’s price. USP’s price dropped over 66% from its $1 peg. The project’s PTP token lost 25% of its value in one day. The attacker minted 40 million USP tokens using the MasterPlatypusV4 contract. They used 44 million Platypus LP-USDC tokens as collateral. The team recovered about $2.4 million USDC from the attacker’s contract. This recovery reduced the hack’s overall impact.

Vulnerable Functions Overview

The emergencyWithdraw Function (Picture credit)

Platypus Finance - EmergencyWithdraw Function

The emergencyWithdraw function allows users to withdraw their funds from the pool without accounting for rewards. This function is for emergencies, allowing quick pool exits without waiting for rewards. It requires a pool ID. The function fetches pool and user data. It then sets the rewarder to zero. Next, it transfers LP tokens to the user. It updates the sumOfFactors. Finally, it resets the user’s amount, factor, and rewardDebt to zero.

The isSolvent function (Picture Credit)

Platypus Finance - _isSolvent function

The Platypus Finance contract uses the isSolvent function to assess whether a user’s collateral position is solvent. This means the collateral value exceeds or matches the outstanding debt. It requires the user’s address, the token address, and a boolean to indicate whether the position is opening or closing.

The isSolvent function first retrieves the user’s debtShare and checks if it is zero. If it is, it returns true, indicating that the position is solvent. If the debtShare is non-zero, it calculates the debtAmount by multiplying the debtShare with the totalDebtAmount and interest since the last accrual, and dividing the result by the totalDebtShare. It then checks whether the debtAmount is less than or equal to the borrow limit for opening positions or the liquidate limit for closing positions.

Security Flaw in the Functions

The vulnerability in the emergencyWithdraw() and _isSolvent() functions is due to an improper solvency check that allows an attacker to withdraw their collateral without fully paying back their debt. Specifically, the solvency check only considers whether the user’s debt amount exceeds the borrowing limit, but does not take into account the actual debt owed by the user.

So, this means that an attacker can deposit collateral to borrow USP tokens, but then withdraw their collateral without paying back the full amount of USP borrowed. Since the solvency check only considers the borrowing limit, the attacker can appear solvent and pass the check even if they owe a significant amount of debt.

The vulnerability is caused by a logical flaw in the code, as the solvency check should also consider the actual debt owed by the user, not just the borrowing limit. The code should be updated to accurately calculate the amount of debt owed and ensure that it is fully paid back before allowing a user to withdraw their collateral.

The Devious Hack: A Step-by-Step Explanation

Taking a Flash Loan

The attacker borrowed a massive 44 million USDC from a lending protocol, just like taking out a huge loan from a bank.

Depositing USDC

The attacker deposited the 44 million USDC into a platform called Platypus USDC Asset (LP-USDC) and received 44 million LP-USDC tokens similar to a person depositing money in a bank and receiving a line of credit.

Borrowing More Money (USP Tokens) with Collateral

Using the 44 million LP-USDC tokens as collateral, the attacker borrowed 41.79 million USP tokens from the system, similar to taking out a second loan by leveraging the line of credit received earlier.

Exploiting a Loophole in the System

The attacker found a vulnerability in the system’s solvency check (emergencyWithdraw and isSolvent functions) , which didn’t properly account for the debt amount. This loophole allowed the attacker to withdraw the initial collateral without repaying the borrowed USP tokens, as the debt was within the 95% borrowing limit cap.

Withdrawing the Initial Collateral

The attacker used the loophole to withdraw their initial collateral (44 million LP-USDC tokens), equivalent to taking back their initial deposit from the bank without repaying the second loan.

Cashing Out the Collateral

The attacker withdrew the 44 million USDC from the LP-USDC Asset, converting the collateral back into cash.

Profiting by Swapping USP Tokens for Other Assets

The attacker swapped the 41.79 million USP tokens for various stablecoins across multiple platforms, making a total profit of approximately $8.5 million, similar to exchanging the second loan for valuable assets.

Repaying the Flash Loan

Finally, the attacker repaid the initial 44 million USDC flash loan, keeping the $8.5 million profit.

Recommendations for Enhanced Security

To mitigate the vulnerability in Platypus Finance’s emergencyWithdraw() and _isSolvent() functions, update the solvency check to consider the user’s actual debt rather than just the debt limit. Implement a check that validates the user’s current debt amount against their collateral value.

This will ensure that users cannot withdraw their collateral without fully paying back their debt, thereby preventing the creation of “bad debt” in the system. It is also recommended to perform thorough testing and auditing of the updated solvency check to ensure its effectiveness in preventing such attacks. Additionally, implementing a time-delayed withdrawal feature can provide an additional layer of security and prevent attackers from instantly withdrawing their collateral in case of a vulnerability ex