Full Report
ENS is a naming service for wallets, websites and more. In March of 2022, there was a vote to replace the existing price oracle. The original interface returned 1 value but the new interface returned 2. These were the registration fee and premium instead of just the total. The price oracle was updated to return two. However, the calling code was only expected to return 1. So, the registration fee was the only value being used, making the domains cheaper than they should have been. The issue was discovered shortly after the proposal was made. While testing slightly different code, the issue was discovered and the voters were made aware of the issue. Overall, it's weird this wasn't caught during initial testing. I'm surprised we don't see more migration issues like this.
Analysis Summary
# Incident Report: ENS Price Oracle Update Incompatibility Leading to Underrated Domain Pricing
## Executive Summary
A governance vote in March 2022 resulted in updating the ENS price oracle contract to return two values (registration fee and premium) instead of the expected single value (total price). The existing calling code was only designed to process the first returned value (the registration fee), causing domain registration fees to be significantly undervalued. The issue was identified during subsequent internal testing shortly after the proposal passed and before wide deployment, preventing a wider financial impact.
## Incident Details
- Discovery Date: Shortly after the proposal was made (March 2022)
- Incident Date: March 2022 (Date of the proposal/contract update)
- Affected Organization: ENS (Ethereum Name Service)
- Sector: Decentralized Infrastructure / Naming Service
- Geography: Not applicable (Blockchain Protocol Incident)
## Timeline of Events
### Initial Access
- Date/Time: March 2022 (Timing of the governance vote/update deployment)
- Vector: Flawed Software Deployment/Protocol Change Implementation
- Details: A governance proposal was executed to update the price oracle. The new oracle contract was modified to return two distinct values: `registration fee` and `premium`.
### Lateral Movement
- Not applicable. This was a systemic code logic error, not a typical network intrusion.
### Data Exfiltration/Impact
- Potential Impact: Domains were being registered at a price significantly lower than intended (only the base registration fee was being processed, excluding the intended premium).
- Actual Impact: The issue was discovered before the faulty mechanism was widely adopted or caused extensive financial loss.
### Detection & Response
- Detection: The issue was discovered during internal testing of slightly different code *after* the proposal was made public/voted on, but before widespread utilization of the corrupted logic.
- Response Actions: Voters and relevant parties were immediately made aware of the impending incompatibility issue.
## Attack Methodology
This incident was caused by a **coding error/version incompatibility** rather than a malicious external attack.
- Initial Access: N/A (Internal deployment issue)
- Persistence: N/A
- Privilege Escalation: N/A
- Defense Evasion: N/A
- Credential Access: N/A
- Discovery: Internal testing of slightly modified code uncovered the logic error.
- Lateral Movement: N/A
- Collection: N/A
- Exfiltration: N/A
- Impact: Incorrect data processing leading to mispricing of services.
## Impact Assessment
- Financial: Minimal to none, as the issue was caught during testing phases before mass exploitation or deployment.
- Data Breach: None.
- Operational: Minor delay in the intended feature rollout pending a fix for the oracle incompatibility.
- Reputational: Minor, noted as an issue that "should have been caught during initial testing."
## Indicators of Compromise
- Behavioral indicators: The calling contract logic only accepted/utilized the first of two expected return values from the updated price oracle contract.
## Response Actions
- Containment measures: Informing governance/voters immediately upon discovery.
- Eradication steps: Fixing the calling code to correctly parse the two return values from the updated oracle.
- Recovery actions: Presumably, re-testing and deploying the corrected interpretation logic.
## Lessons Learned
- **Thorough Testing of Interface Changes:** Significant protocol migrations, especially those involving existing contracts calling newly deployed logic, must rigorously test parameter returns and data structures (e.g., ensuring array/tuple return handling matches expectations).
- **Cross-Contract Compatibility Awareness:** Changes in return signatures between versions of critical infrastructure (like price oracles) require auditing of *all* dependent contracts expected to interact with that interface.
## Recommendations
- Implement mandatory, independent audits specifically focused on data structure and return value compatibility when deploying updates to core infrastructure contracts that have multiple, dependent callers.
- Increase the scope of pre-deployment testing to cover regression testing against near-future state changes (i.e., testing existing callers against the *proposed* data structure change).