Ether Drain
Make sure that ether is not drained from a contract
Use Case
Protecting protocols from rapid ETH draining is a critical security measure. Malicious actors often attempt to extract all available ETH from a contract in a single transaction after discovering an exploit, leading to catastrophic loss of funds. This assertion prevents sudden large withdrawals of ETH, giving protocols time to respond to potential exploits.
Real-world example: In February 2025, Bybit suffered one of the largest hacks in crypto history, losing approximately $1.4 billion USD when attackers compromised Safe Wallet’s UI and changed the implementation address of their proxy contract. This allowed the attackers to drain all assets without requiring additional approvals from the original owners. ETH drain assertions, especially with whitelist functionality, could have prevented or significantly limited the impact of this attack. See the Bybit Safe UI attack for more details.
This assertion is particularly important for:
- Detecting and limiting the impact of flash loan attacks targeting ETH reserves
- Preventing complete draining of protocol treasury funds in a single transaction
- Buying time for protocol teams to activate circuit breakers or emergency pauses
- Limiting the economic damage from zero-day exploits by enforcing withdrawal rate limits
- Ensuring larger ETH transfers only occur to trusted, whitelisted addresses
Applicable Protocols
- DeFi lending platforms that use ETH as collateral
- Cross-chain bridges holding large ETH reserves
- DAOs and protocol treasuries with significant ETH holdings
- Staking protocols managing ETH deposits
- Yield aggregators and vaults holding ETH
- Centralized exchanges holding large ETH reserves
These protocols need this assertion because:
- Lending platforms need to maintain adequate ETH collateral reserves
- Cross-chain bridges are frequent targets of large-scale ETH draining attacks
- Treasury contracts often lack rate-limiting on withdrawals
- Staking protocols need to protect depositor funds from sudden drains
- Yield-generating protocols need to detect abnormal ETH outflows
- Centralized exchanges need to protect their large ETH reserves
Explanation
The assertion implements a straightforward yet effective approach to detect rapid ETH draining with a tiered protection strategy:
-
Pre-transaction Analysis:
- Uses
forkPreState()
to capture the contract’s ETH balance before the transaction - Records the balances of all whitelisted addresses before the transaction
- Establishes the baseline for detecting significant withdrawals
- Uses
-
Post-transaction Verification with Dual Security Paths:
- Uses
forkPostState()
to check the contract’s ETH balance after the transaction - For small withdrawals (below threshold): Allows the transaction regardless of destination
- For large withdrawals (above threshold): Requires the destination to be a whitelisted address
- If no whitelist is defined, blocks all large withdrawals as a safety measure
- Uses
The assertion uses the following cheatcodes:
forkPreState()
: Captures the contract’s ETH balance and whitelist balances before executionforkPostState()
: Captures the contract’s ETH balance and whitelist balances after executionregisterBalanceChangeTrigger()
: Triggers the assertion when ETH balances change
This tiered approach ensures that:
- Normal operations with small withdrawals continue uninterrupted
- Large withdrawals are restricted to trusted, whitelisted addresses
- Protocols can define their own risk thresholds for withdrawal sizes
- Smart contracts maintain secure yet flexible ETH management
For more information about cheatcodes, see the Cheatcodes Documentation.
Code Example
Note: This code example is maintained in the Phylax Assertion Examples Repository. For a full examples with mock protocol code and tests please refer to the repository.
Testing
To test this assertion:
- Deploy a test contract with ETH balance
- Attempt various ETH withdrawal scenarios:
- Small withdrawals below the threshold
- Large withdrawals that exceed the threshold
- Multiple withdrawals in sequence
- Verify the assertion correctly:
- Allows withdrawals below the maximum percentage
- Blocks withdrawals that exceed the maximum percentage
- Properly handles edge cases like zero balance
- Permits large withdrawals only to whitelisted addresses
Assertion Best Practices
- Combine with time-based monitoring to limit withdrawal frequency
- Adjust the maximum percentage based on the protocol’s specific risk profile
- Consider implementing a tiered system where larger withdrawals require longer timeouts
- Define a comprehensive whitelist of trusted addresses at deployment time (deploy new assertion to update whitelist)
- Use alongside other assertions like Ownership Change or Implementation Address Change for comprehensive protection
When implementing this assertion:
- Consider protocol user patterns to set appropriate drain limits
- Be careful not to set limits too low, which could impair normal protocol functionality
- Remember that attackers can still drain funds incrementally if no time-based limits are added
- For critical systems, combine with automated alerting to notify the team of any large withdrawals