Full Report
Seneca did virtually everything wrong and then got hacked. So, sort of a funny setup. Seneca was supposed to do an audit with Sherlock but was suddenly closed for code licensing issues. They decided to launch with only an audit from Halborn (which reported a similar bug but not the terrible one that was used). In the Post Mortem, Seneca details the vulnerability. The function PerformOperations contained a mechanism for making an arbitrary call to an arbitrary contract from the context of their contract at here. There is a denylist here but probably not a great one. With an arbitrary call from the context of the Seneca smart contract, there are many paths to go. However, the easiest one is abusing allowances from other users. By making calls to tokens that had approvals from other users, a malicious actor can trick the contract to send them funds. To me, this is a pretty clear sink within the smart contract. Arbitrary calls are catastrophic like this. This would have been quickly found by lots of people on Sherlock; it's weird that this wasn't found by Halborn tbh. Overall, the takeaway is take security seriously! If you don't you'll get hit hard. As security folks, it's okay to call things out as insecure in order to protect users.
Analysis Summary
# Incident Report: Seneca Protocol Approval Exploit
## Executive Summary
On February 28, 2024, the Seneca Protocol was compromised via a critical vulnerability in its "Chamber" smart contract, specifically within the `PerformOperations` function. The attacker leveraged an arbitrary call vulnerability to drain approximately $6.4 million in assets from users who had granted token approvals to the protocol. Following a negotiation with the attacker (acting as a "whitehat"), roughly 80% of the stolen funds were returned in exchange for a 20% bounty.
## Incident Details
- **Discovery Date:** February 28, 2024
- **Incident Date:** February 28, 2024
- **Affected Organization:** Seneca Protocol
- **Sector:** Decentralized Finance (DeFi)
- **Geography:** Global / Decentralized
## Timeline of Events
### Initial Access
- **Date/Time:** February 28, 2024
- **Vector:** Smart Contract Vulnerability (Arbitrary Call)
- **Details:** The attacker exploited the `PerformOperations` function, which allowed for arbitrary calls to arbitrary contracts. By bypassing an insufficient denylist, the attacker made calls to various token contracts to trigger `transferFrom` operations against users who had active approvals to Seneca.
### Lateral Movement
- **Details:** Not applicable in a traditional network sense. The attacker moved across different Liquid Staking Tokens (LSTs) on both the Ethereum and Arbitrum networks that were approved for use with Seneca's contracts.
### Data Exfiltration/Impact
- **Details:** The attacker drained over 1,900 ETH worth of various assets, including PT-ezETH, apxETH, PT-weETH, and stEUR. Even Seneca’s own team address was drained of 50k senUSD due to an unused, active approval.
### Detection & Response
- **Detection:** Detected via on-chain activity monitoring and community alerts on X (formerly Twitter).
- **Response actions taken:** Seneca issued a public warning for users to revoke approvals. A 20% bounty was offered on-chain to the exploiter.
## Attack Methodology
- **Initial Access:** Exploitation of a logic flaw in the `PerformOperations` function.
- **Persistence:** Not required; the attack was executed via atomic transactions.
- **Privilege Escalation:** Abusing the "context" of the Seneca contract to act as an authorized spender of user funds.
- **Impact:** Financial theft through the unauthorized transfer of user-approved tokens.
## Impact Assessment
- **Financial:** Total initial loss of ~$6.4M. Net loss of ~$1.28M (20%) after the return of funds.
- **Data Breach:** None (on-chain transaction data is public).
- **Operational:** Protocol functionality compromised; "Pause" and "Unpause" functions were found to be non-functional (broken code), preventing immediate containment.
- **Reputational:** Severe; the protocol had previously canceled a Sherlock audit and ignored community reports regarding the specific bug.
## Indicators of Compromise
- **Exploiter Address 1:** 0x94641c01a4937f2c8ef930580cf396142a2942dc
- **Exploiter Address 2:** 0x5217c6923a4efc5bcf53d9a30ec4b0089f080ed0
- **Exploiter Address 3:** 0xe83b072433f025ef06b73e0caa3095133e7c5bd0
- **Example Attack TX:** 0x9f3712672be7a120757d42fbe15ceefe9578914946bacbd0f3531e7fb7305576
## Response Actions
- **Containment:** Messaging users to manually revoke approvals; attempted (but failed) to pause the contract due to buggy pause implementation.
- **Recovery:** Negotiation with the attacker resulted in the return of 1,537 ETH to a Gnosis Safe address (0xb7aF0Aa318706D94469d8d851015F9Aa12D9c53a).
- **Eradication:** Post-mortem publication and (pending) contract redeployment/patching.
## Lessons Learned
- **Audit Rigor:** A single audit (Halborn) missed a critical arbitrary call sink that community members and other audit platforms (Sherlock) identified or would have likely identified.
- **Emergency Measures:** The failure of the "Pause" function highlights the need for rigorous testing of emergency administrative functions.
- **Community Feedback:** Seneca allegedly ignored or "trashed" community members who warned of the bug prior to the exploit.
- **Approval Risks:** Users and protocols must minimize the duration and scope of token approvals.
## Recommendations
- **Implement Robust Access Control:** Avoid arbitrary call mechanisms that transfer the contract's "authority" to external inputs.
- **Redundant Auditing:** Utilize multiple audit firms or competitive audit platforms for complex DeFi logic.
- **Functional Circuit Breakers:** Ensure the "Pause" mechanism is part of the core test suite and is verified both on-chain and in staging.
- **Automated Revocation:** Consider implementing "pull" patterns or time-bound approvals rather than indefinite approvals.