Full Report
PalmSwap is a decentralized leveraged trading platform. The calculations for betting on the price going up or down must be done properly. There are two tokens at play: USD Palm (USDP) and Palm Liquidity Provider (PLP). When removing liquidity, the price is calculated using the getAum() function. This multiplies the pool amount by the price of the token from an external oracle to get the amount of received tokens. When calling buyUSDP(), there is a function to increase the price of USDP and increase the pool amount. Within the removal process, there is no decrease price though. The flaw is that the calculations are not 1 to 1 between adding and removing assets. The call gives a 1 to 1.9 ratio, which is way to easy to make money from. How was this attack performed? Flash loan for 3 Million USD. Purchase a large amount of PLP with purchasePLP(); about 1 Million from the original amount. Under the hood, this will buy USDP and mint PLP with a 1 to 1 ratio. Finally, it stakes this for the user. Purchase USDP directly by calling buyUSDP() with the rest of the funds. The problem is that the exchange rate has gone up between USDP and PLP, even though nothing has really changed. Unstake the amount from step 2 ino rder to get USDP at the inflated rate. Call sellUSDP() to sell all of the staked amount. Another report can be found here from BlockSec as well. Overall, a bad functional bug led to a major exploit. It's weird that this was not caught in testing.
Analysis Summary
Based on the context provided, the summary focuses *only* on the description of the PalmSwap incident, as the main body of the provided text is a directory of links and blog titles from QuillAudits, not the detailed post-mortem for PalmSwap itself.
# Incident Report: PalmSwap Decentralized Trading Platform Exploit via Pricing Mismatch
## Executive Summary
The PalmSwap platform, a decentralized leveraged trading protocol, suffered a major exploit due to a functional bug where the calculation logic for adding and removing leveraged assets (USDP and PLP) was asymmetric. An attacker utilized a flash loan to borrow 3 million USD to manipulate asset ratios, resulting in an inflated price for withdrawal, leading to significant, though unspecified, financial loss.
## Incident Details
- Discovery Date: Not disclosed in provided text.
- Incident Date: Not disclosed in provided text (Implied recent event).
- Affected Organization: PalmSwap
- Sector: Decentralized Finance (DeFi), Leveraged Trading Platform
- Geography: Not disclosed (Assumed blockchain environment).
## Timeline of Events
### Initial Access
- Date/Time: Not specified.
- Vector: Flash Loan execution.
- Details: Attacker initiated an atomic transaction using a 3 Million USD flash loan.
### Lateral Movement
- Not applicable to this smart contract exploit model; actions were sequential contract calls within one transaction.
### Data Exfiltration/Impact
- **Impact:** Exploitation of the pricing flaw to withdraw more valuable tokens (USDP) than were deposited/earned during the manipulation phase. The specific amount stolen is not detailed.
### Detection & Response
- Detection: Implied external reporting suggests detection occurred after the attack concluded (references external BlockSec report).
- Response Actions: Not disclosed, other than the creation of external security analysis reports.
## Attack Methodology
- **Initial Access:** Flash Loan (3 Million USD).
- **Persistence:** Not applicable.
- **Privilege Escalation:** Not applicable (leveraging a functional logic flaw).
- **Defense Evasion:** Not applicable to Evasion; the attack relied on the code functioning as written, despite being logically flawed.
- **Credential Access:** Not applicable.
- **Discovery:** Attacker identified a critical logic error where the price update mechanism during asset addition (`buyUSDP()`) was not mirrored or reversed correctly during removal (`getAum()`).
- **Lateral Movement:** Not applicable.
- **Collection:** N/A (The goal was manipulation and extraction, not data collection).
- **Exfiltration:** Selling newly acquired USDP for profit after manipulation.
- **Impact:** Directly profiting from a 1 to 1.9 ratio discrepancy between staking/unstaking PLP and USDP.
**Specific Attack Flow:**
1. Flash Loan of $3M USD initiated.
2. Call `purchasePLP()` to buy a large amount of PLP (approx. $1M worth of collateral initially), which implicitly buys USDP and mints PLP at a 1:1 ratio, then attempts to stake it.
3. Call `buyUSDP()` with remaining loan funds, increasing the underlying USDP/PLP exchange rate due to the bug.
4. Unstake the PLP acquired in Step 2, withdrawing USDP at the newly inflated rate.
5. Call `sellUSDP()` to clear the fraudulently obtained USDP for profit.
## Impact Assessment
- Financial: Significant, implied multi-million dollar loss leveraged from the platform's liquidity through misuse of the lending mechanism. (Specific amount not provided).
- Data Breach: None (This was a protocol/economic exploit).
- Operational: Severe, resulting in loss of platform funds/liquidity.
- Reputational: Significant, necessitating external reports (e.g., BlockSec).
## Indicators of Compromise
- **Network Indicators:** Transaction involving large sums borrowed via flash loan followed immediately by complex interactions with `purchasePLP()`, `buyUSDP()`, and subsequent asset liquidation/sale functions within a single block.
- **File Indicators:** None (Smart Contract vulnerability).
- **Behavioral Indicators:** Unusual, rapid manipulation of asset pool ratios resulting in immediate mass withdrawal calls.
## Response Actions
- Containment: Not disclosed.
- Eradication: Not disclosed.
- Recovery: Not disclosed.
## Lessons Learned
- **Critical Invariant Failure:** The core lesson is the failure to maintain 1:1 reciprocity between addition and removal operations involving core pool assets (PLP/USDP).
- **Insufficient Validation:** The vulnerability was a "bad functional bug" that should have been caught during testing, highlighting deficiencies in pre-deployment auditing or internal testing frameworks regarding complex state transitions (e.g., checking if price adjustments during *addition* are reversed correctly during *removal*).
## Recommendations
- Implement rigorous invariant testing that specifically checks that the state after a sequence of additive functions is perfectly reversible by a corresponding sequence of subtractive functions, even across multiple helper calls.
- Ensure comprehensive testing covers edge cases where externalities (like oracle price feeds affecting the `buyUSDP` function) influence the calculation path.