Full Report
Feminist Metaverse (FM) is a DAO for women's rights. The contract had its own token - FM. The smart contracts _transfer function had code for figuring out the dividends for the stakers of the token. This is done with two lines of code: _balances[uniswapV2Pair] = \ _balanceOf[uniswapV2Pair].add(contractTokenBalance); _balances[address(this)] = \ _balanceOf[uniswapV2Pair].sub(contractTokenBalance); The key thing to note is that the amount of funds going to the uniswapV2Pair is done via setting the balance manually and not by an actual transfer. Why is this a problem? The normal logic and considerations for money does not apply to this! The if statement to trigger this functionality is trivial to trigger every time. So, an attacker can send very little FM to increase the amount owned by the uniswapV2Pair contract. This is NOT the intended functionality. The skim function is for making the balances match the reserves. Without the bug above, this wouldn't matter. But, since we can desync these trivially, an attacker can call this function to get the difference between the contracts. The bug seems like something that should have been caught in testing. Additionally, the skim function being callable by anyone is very strange. Overall, an interesting exploit.
Analysis Summary
# Incident Report: Feminist Metaverse (FM) Price Manipulation & Skim Exploit
## Executive Summary
On May 18, 2022, the Feminist Metaverse (FM) DAO smart contract was exploited on the Binance Smart Chain (BSC), resulting in a loss of approximately $550,000 (1,838.3 BNB). The attacker leveraged a logical flaw in the `_transfer` function that incorrectly updated the Uniswap/SakeSwap pair balance without an actual token transfer, followed by the use of the `skim` function to extract the resulting surplus.
## Incident Details
- **Discovery Date:** May 18, 2022
- **Incident Date:** May 18, 2022
- **Affected Organization:** Feminist Metaverse (FM) DAO
- **Sector:** Decentralized Finance (DeFi) / DAO
- **Geography:** Global / Distributed (Binance Smart Chain)
## Timeline of Events
### Initial Access
- **Date/Time:** May 18, 2022
- **Vector:** Exploitation of logic error in FM Token smart contract.
- **Details:** The attacker funded a wallet with 1 BNB via Tornado Cash and deployed an attack contract at `0x0b8d752252694623766dfb161e1944f233bca10f`.
### Lateral Movement
- **Step 1:** Attacker sent 10 FM tokens to the attack contract to initiate the exploit.
- **Step 2:** The attacker granted maximum FM token allowance to the PancakeSwap Router.
- **Step 3:** The attack contract performed 8,000 micro-transfers (0.00000000000001 FM each). Each transfer incorrectly inflated the balance of the `uniswapV2Pair` stored in the FM contract’s internal state.
### Data Exfiltration/Impact
- **Exploitation:** By desyncing the contract's internal balance from the actual reserves held in the liquidity pair, the attacker created a "surplus" of tokens.
- **Extraction:** The attacker called the `skim` function on the SakeSwapPair contract to transfer the excess 1.1 billion FM tokens to their own wallet.
- **Conversion:** The stolen FM tokens were swapped for BNB and USD.
### Detection & Response
- **Detection:** Post-incident on-chain analysis by security researchers (Lunaray).
- **Response Actions:** Not explicitly disclosed in the text, but the funds were successfully moved to Tornado Cash by the attacker before intervention.
## Attack Methodology
- **Initial Access:** Smart contract vulnerability exploitation.
- **Persistence:** Not applicable (Atomic transaction-based exploit).
- **Privilege Escalation:** Exploited the `skim` function, which was incorrectly left callable by any user.
- **Defense Evasion:** Used Tornado Cash to obfuscate the source and destination of funds.
- **Discovery:** Identified that the FM `_transfer` function manually set `_balances[uniswapV2Pair]` rather than using standard transfer logic.
- **Impact:** Financial theft via price manipulation and liquidity draining.
## Impact Assessment
- **Financial:** Over $550,000 USD (1,838.3 BNB) lost.
- **Data Breach:** N/A (Financial/Smart Contract exploit).
- **Operational:** Significant depletion of the FM/BNB liquidity pool.
- **Reputational:** Loss of trust in the FM DAO’s security audit and contract integrity.
## Indicators of Compromise
- **Attacker Wallet:** `0xaaA1634D669dd8aa275BAD6FdF19c7E3B2f1eF50`
- **Attacker Contract:** `0x0b8d752252694623766dfb161e1944f233bca10f`
- **Exploit Transaction:** `0xecde3c3742615852abdbd6ec5d75ae982b5c29f810e140e5cd822667d6f7b848`
- **Behavioral:** High-frequency small-value transfers followed by a large `skim` call.
## Response Actions
- **Containment:** None reported during the event (automated exploit).
- **Eradication:** Analysis of the `FmToken` contract identified the flawed `_transfer` logic.
- **Recovery:** Attacker successfully laundered 1838.3 BNB via Tornado Cash.
## Lessons Learned
- **Manual Balance Management:** Manually setting balances in a `_transfer` function instead of using arithmetic operations or standard `Transfer` events is highly dangerous and prone to desynchronization.
- **Access Control:** The `skim` function in liquidity pairs often requires careful monitoring or access restrictions if the underlying token has non-standard transfer logic.
- **Testing:** This specific logic flaw (trivial to trigger the `if` statement) should have been caught during a comprehensive security audit or unit testing.
## Recommendations
- **Audit Requirement:** Ensure all smart contract updates undergo a rigorous third-party audit, specifically focusing on tokenomics and liquidity functions.
- **Standard Implementation:** Utilize OpenZeppelin’s standard ERC-20 implementations to avoid "re-inventing" the transfer logic.
- **Price Oracles:** Implement robust price oracles and slippage protections to mitigate the impact of sudden liquidity shifts.
- **Emergency Pause:** Implement a `Pausable` mechanism to freeze transfers in the event of detected anomalous activity.