Full Report
Enzyme Fiance is an on-chain asset management protocol. Users can create access rules, trading limits and other various rules. Within this, there are three main roles: asset manager, end users and the protocols being interacted with. The manager handles the funds in order to create a secure yield generating platform, which the users will benefit from. However, who should have to pay for the gas on a rebalancing? To solve this problem, there is a gas station network relayer for handling exactly this case. This works by having the users pay the expected gas charges up front then executing the transaction via a network of relayers. Within this architecture, there are a few different roles. First, the relay server is a web server that takes in a request for a transaction. The paymaster is the contract setup by the application using the GSN to pay for the gas prior to executing the call. The relayhub is the entrypoint for the relayer itself. Finally, the forwarder is the contract on the network for the GSN that is trusted to execute the call, where the application should implement a caller interface for this. We have an anonymous user from the GSN network making calls to the contract on behalf of another user. So, access control is complicated to do with this setup. One job of the forwarder is to call the function preRelayedCall() to ensure that the recipient matches the forwarder in the relay request. When overriding the original implementation of this function from GSN, they removed this check. For integration into the network, the relayer is trusted and must be allow listed by the network. Since the check was removed, an malicious forwarder can abuse this to profit from it. Remember, the forwarder is the entity actually performing the transaction and getting paid out in gas for their troubles. Since the forwarder isn't validated, an attacker can send a fake message then receive payment for it! How much payment? According to the GSN docs, the gas information should be validated within the paymasters preRelayedCall() as well. But, there is no verification of the gas parameters for this. As a result, a malicious relayer can set very high gas values then get paid out a lot by the paymaster. To make matters worse, since the paymaster is replenished with 0.5ETH magically, this can be done on repeat to steal more and more ETH. To fix this, there are two bugs that should be remediated. First, checking the forwarder address. Second, checking that the gas parameters are sane. The author leaves us with a few takeaways. First, small features can still have big impacts. Second, more misconfigurations can lead to the amplification of impact, such as with the missing gas price check. Finally, design is key. GSN rewrote some of their code to do this verification themselves instead of putting the blame on the developers. Overall, a very in depth read onto a GSN integration vulnerability. It's interesting how a small access control issue turned into the stealing of money from the protocol. Great find and write up!
Analysis Summary
# Vulnerability: Enzyme Finance GSN Integration Fund Drain
## CVE Details
- **CVE ID**: N/A (Web3/Smart Contract vulnerability reported via Immunefi)
- **CVSS Score**: 9.1 (Calculated: Critical)
- **CWE**: CWE-284: Improper Access Control; CWE-682: Incorrect Calculation
## Affected Systems
- **Products**: Enzyme Finance (On-chain asset management protocol)
- **Versions**: Deployments involving the Gas Station Network (GSN) integration prior to the security patch (circa 2023).
- **Configurations**: Protocol contracts utilizing a custom `preRelayedCall()` implementation within the GSN Paymaster architecture.
## Vulnerability Description
The vulnerability stems from a two-fold flaw in the integration of the Gas Station Network (GSN). Enzyme Finance implemented a Gas Station to allow relayers to execute rebalancing transactions without the protocol manager paying gas directly.
1. **Missing Forwarder Validation**: In Enzyme's custom override of the `preRelayedCall()` function, the protocol failed to verify that the `forwarder` address (the entity passing the message) was a trusted GSN forwarder. This allowed any arbitrary address to submit a "relayed" request.
2. **Unchecked Gas Parameters**: The Paymaster contract did not validate the gas price or gas limit parameters provided in the relayed request. In a standard GSN flow, the Paymaster is responsible for paying the relayer. Because these parameters were not "sane-checked," a malicious relayer could submit a transaction with an artificially inflated gas price.
## Exploitation
- **Status**: Discovered via bug bounty (RootRescue); PoC available in research circles. No public evidence of large-scale exploitation in the wild prior to the report.
- **Complexity**: Medium (Requires understanding of GSN architecture and relayed call flows).
- **Attack Vector**: Network (Remote execution via Ethereum/Smart Contract interaction).
## Impact
- **Confidentiality**: None
- **Integrity**: High (Unauthorized logic execution context).
- **Availability**: High (Protocol treasury/Paymaster funds can be drained, disabling gas-less features).
- **Financial**: High (Direct theft of ETH from the Paymaster contract).
## Remediation
### Patches
- The protocol updated their GSN integration to include a strict check on the `forwarder` address within the `preRelayedCall` logic.
- Logic was added to validate that gas parameters (gasPrice) align with current network averages to prevent overpayment.
### Workarounds
- De-funding the Paymaster contract or pausing GSN-relay capabilities until the code update was deployed.
## Detection
- **Indicators of Compromise**: Multiple transactions from unknown relayers with abnormally high `gasPrice` values. Paymaster balance depleting at an unexpected rate.
- **Detection Methods**: Monitor the `RelayHub` events for `TransactionRelayed` emitted by the Enzyme Paymaster, specifically filtering for high gas costs or untrusted relayer addresses.
## References
- **Vendor Advisory**: Enzyme Finance Security Updates
- **Write-up**: hxxps://medium[.]com/@0kage/0kage-diaries-chapter-1-enzyme-finance-90f4d85c067e
- **GSN Documentation**: hxxps://docs[.]opengsn[.]org/
- **Original Researcher**: rootrescue via Immunefi