Full Report
LeetSwap is a decentralized token exchange. It's a fork of Solidly. In Solidity, private and internal functions are started with an _ (underscore) by convention. In practice, the visibility is the important part. In the case of this protocol, the function _transferFeesSupportingTaxToken() was set to public, even though it had an underscore at the beginning. Although the name says taxTokens, the functionality takes in a token address and amount then sends it to the fees contract owner. So, what's the big deal? The attacker does not get sent the money. How do we exploit this? Since this is an automated market maker (AMM), the prices are dedicated by the amount of the assets in the protocol. Since we can arbitrarily move assets out of the protocol, we can manipulate the trading rates. Here's a step by step for hitting a single pool if we were attacking a WETH-SOMETOKEN pool: Swap WETH for SOMETOKEN at the market rate. Call _transferFeesSupportingTokenTax() to transfer out the SOMETOKEN from the protocol. This will make the exchange rate for trading SOMETOKEN to WETH favorable. Call the sync() function to fix the pool amounts used for calculations. Swap back SOMETOKEN for WETH at the favorable rate to drain the protocol of most of its WETH. Get audits people! Security is hard. A junior auditor would have trivial caught this bug.
Analysis Summary
# Incident Report: LeetSwap Price Oracle Manipulation Exploit
## Executive Summary
LeetSwap, a decentralized exchange on the Base network, suffered a smart contract exploit resulting in the loss of over 340 ETH. The attacker exploited a visibility misconfiguration in a core function, allowing them to arbitrarily remove tokens from liquidity pools to manipulate exchange rates. By draining pool reserves and syncing the state, the attacker was able to swap tokens back for WETH at inflated rates, effectively draining the protocol’s liquidity.
## Incident Details
- **Discovery Date:** August 1, 2023 (via BlockSec)
- **Incident Date:** August 1, 2023
- **Affected Organization:** LeetSwap (DEX)
- **Sector:** Decentralized Finance (DeFi)
- **Geography:** Global / Base Layer 2 Network
## Timeline of Events
### Initial Access
- **Date/Time:** August 1, 2023
- **Vector:** Exploitation of broken access control in Smart Contract.
- **Details:** The attacker identified that the function `_transferFeesSupportingTaxToken()` was set to `public` visibility despite the underscore prefix convention suggesting it should be `internal` or `private`.
### Lateral Movement
- **Details:** Not applicable in the traditional network sense; the attacker moved "laterally" across multiple liquidity pools (WETH-SOMETOKEN) using the same exploit pattern to maximize gains.
### Data Exfiltration/Impact
- **Details:** The attacker drained over 340 ETH from various LeetSwap liquidity pools.
- **Wallet Addresses:** Initial attacker address `0x705f...`; Profit collection address `0x5b03...`.
### Detection & Response
- **Detection:** Identified by blockchain security firm BlockSec via on-chain monitoring.
- **Response:** Public disclosure by security researchers; the protocol team was alerted to the vulnerability to halt further trading or migrate funds where possible.
## Attack Methodology
- **Initial Access:** Exploited a misconfigured Smart Contract function visibility.
- **Persistence:** Not required; the attack was executed via atomic transactions.
- **Privilege Escalation:** The attacker gained "Owner-like" privileges to move tokens out of the pool by calling a function that should have been restricted.
- **Defense Evasion:** None; all transactions were public on the Base blockchain.
- **Discovery:** Reconnaissance of LeetSwap’s smart contract code (Fork of Solidly).
- **Impact:** Used `_transferFeesSupportingTaxToken()` to remove assets, followed by `sync()` to force the pool to recalculate a massively inflated price for the remaining assets.
## Impact Assessment
- **Financial:** Loss of approximately 340 ETH (approx. $630,000 USD at the time of the incident).
- **Data Breach:** None (non-custodial protocol).
- **Operational:** Trading on the platform was compromised as liquidity pools were drained.
- **Reputational:** Significant damage to the protocol's credibility due to a "trivial" coding error that would have been caught during a basic audit.
## Indicators of Compromise
- **Attacker Address 1:** `0x705f[REDACTED]` (Primary Exploiter)
- **Attacker Address 2:** `0x5b03[REDACTED]` (Profit Receiver)
- **Behavioral Indicators:** Multiple calls to `_transferFeesSupportingTaxToken()` followed immediately by `sync()` and large `swap()` transactions within a single block.
## Response Actions
- **Containment:** Community alerts and security firm notifications to warn users.
- **Recovery:** Analysis of remaining liquidity and potential migration paths for affected users.
## Lessons Learned
- **Visibility Convention vs. Enforcement:** Solidity developers must remember that an underscore prefix (`_`) is merely a naming convention and does not enforce `private` or `internal` visibility.
- **Audit Necessity:** As noted by researchers, a junior auditor would have identified this bug. Launching a DeFi protocol without a professional security audit significantly increases the risk of total loss.
- **Fork Risks:** LeetSwap was a fork of Solidly; developers often introduce vulnerabilities when modifying or porting existing codebases without fully understanding the underlying logic.
## Recommendations
- **Strict Access Control:** Audit all function visibilities. Ensure any function that moves funds is restricted to `onlyOwner` or set to `internal`.
- **Automated Scanning:** Implement Static Analysis tools (like Slither or Mythril) in the CI/CD pipeline to catch public functions with underscore prefixes.
- **Formal Audit:** Engage a reputable third-party security firm to conduct a comprehensive audit before deploying any smart contracts to mainnet.