Enzyme Finance Missing Privilege Check Bugfix Review

Immunefi
Immunefi
Published in
5 min readMay 19, 2023

Summary

On Mar 28, 2023, whitehat rootrescue submitted a critical bug in Enzyme Finance via Immunefi, which the Enzyme team quickly confirmed and fixed. This critical bug could have led to the draining of Enzyme’s Vault which funds paymasters and enables Enzyme’s contracts to utilize the Gas Station Network.

The Enzyme team paid rootrescue $400,000 for his bug find.

Enzyme Finance

Enzyme Finance is a decentralized asset management platform built on Ethereum. It enables anyone to create, manage, and invest in custom investment strategies using a variety of different assets, including cryptocurrencies and other digital assets. The platform also offers a range of tools and features designed to make it easy for investors to track their investments and manage their portfolios.

Before exploring the vulnerability, it is important to understand some of the key components involved. Enzyme makes use of the Gas Station Network (GSN) to allow gasless clients to interact with Ethereum smart contracts without users needing ETH for transaction fees.

An introduction to GSN

The GSN is a decentralized network of relayers which allows dApps to pay the costs of transactions instead of individual users. This can lower the barrier of entry for users and increase user experience by allowing users to make gasless transactions. The GSN makes use of meta-transactions. Meta-transactions are a design pattern in which users sign messages containing information about a transaction they would like to execute, but relayers are responsible for signing the Ethereum transaction, sending them to the network, and paying the gas cost. The general flow of the meta TX works as mentioned in the following figure. Have a quick look at it before we dive into the nitty-gritty of how it actually works.

Let’s break the above graphic down and describe the different components.

Paymaster Contract

A payment management contract, often referred to as a paymaster, maintains an Ethereum balance within RelayHub. It can implement diverse business logic to determine whether to approve or deny a meta transaction. Examples of such logic include: accepting transactions exclusively from whitelisted users and allowing transactions that incorporate token repayment to the payment management contract.

Trusted Forwarder

A trusted forwarder contract is remarkably straightforward, serving primarily one function — verifying user signatures.

Relay Hub

The RelayHub is a vital smart contract that facilitates and oversees interactions among various components in the system. These components include users, relay servers (also called relayers), paymaster contracts, and recipient contracts.

Relay Server

A relay server, also known as a relayer, is a vital component in the context of meta-transactions and gasless transactions on the blockchain. Its primary role is to facilitate the process of executing transactions on behalf of users without requiring them to pay for the associated gas fees upfront. Instead, relay servers pay the gas fees and may later receive reimbursement or compensation in the form of tokens or other means, as defined by the system.

We can now comprehend the flow of meta-transactions as follows:

1. The user sends a signed message to the relay server containing transaction details.

2. The relay server verifies the transaction and ensures that there are sufficient fees to cover the costs.

3. The relay server generates a new transaction that uses the user’s signed message, trusted forwarder’s address, and paymaster’s address to call the relay hub.

4. The relay server signs the new transaction and sends it to the Ethereum network, paying the necessary gas fees in advance.

5. After receiving the transaction, the relay hub calls the trusted forwarder contract with the user’s signed message and then calls the recipient contract.

6. The trusted forwarder validates the user’s signature, recovers the user’s address, and transmits the transaction to the recipient contract.

7. The transaction is executed and the blockchain state is updated by the recipient contract.

8. Following the completion of the transaction, the relay hub requests reimbursement from the paymaster contract for the relay server’s gas fees.

9. The paymaster contract validates the transaction and sends funds (in tokens or ETH) to the relay server to cover the gas fees and any additional service fees.

Vulnerability Analysis

Enzyme has a set of contracts which support use of the GSN. This consists of GasRelayPaymasterLib, GasRelayPaymasterFactory, and GasRelayRecipientMixin. The GasRelayPaymasterFactory helps create instances of paymasters, and the GasRelayRecipientMixin has shared logic that is inherited for relayable transactions. The GasRelayPaymasterLib is responsible for providing the logic for paymasters, and importantly, the rules for calls that can be relayed. The paymaster is intended to validate the forwarder is approved by the paymaster as well as by the recipient contract in preRelayedCall.

However, within Enzyme’s GasRelayPaymasterLib contract, the external function which contained the check for a valid forwarder was overridden.

When a relayed transaction is sent via GSN in a typical flow, the trusted forwarder is being relied on to perform an important security check, verifying the user’s signature when a transaction is relayed. Since a malicious trusted forwarder can be provided due to missing verification of the provided forwarder’s address in the paymaster, the signature verification can be bypassed, and a relay call can be crafted in such a way that the paymaster returns much more fees than expected since the from address is believed to be the address which matches the signature provided. An attacker would craft the following parameters of relayCall to exploit the missing validation after deploying a malicious forwarder:

The most relevant changes to the relay data are the forwarder, which is set to the malicious forwarder deployed by the attacker, and the pctRelayFee and baseRelayFee which can be used to manipulate the amount of funds returned to the relayWorker by the paymaster. Since Enzyme mitigates risk by deploying multiple funds with small amounts of ether (0.5) which are utilized to repay relayers, an attacker would have to submit many exploit transactions to drain the Vault. However, the paymaster automatically tops up funds with assets from the Vault if the paymasterData is set to true.

To exploit this, an attacker would make many relayCalls to the RelayHub until the target fund’s Vault is drained.

Vulnerability Fix

To address this issue, Enzyme introduced the following commit to add the required check within the GasRelayPaymasterLib, which verifies if the passed address is a trusted forwarder and reverts otherwise.

Acknowledgments

We would like to thank rootrescue for doing an amazing job and responsibly disclosing such an important bug. Big props also to the Enzyme team who responded quickly and patched the vulnerable contract.

Thanks also to Rudra and Alejandro of Immunefi for writing this bugfix review.

If you’re a Web2 or Web3 developer who is finally thinking about a bug-hunting career in Web3, we got you. Check out our Web3 Security Library, and start taking home some of the $140m in rewards available on Immunefi — the leading bug bounty platform for Web3.

And if you’re feeling good about your skillset and want to see if you will find bugs in the code, check out the bug bounty program from Enzyme Finance.

--

--

Immunefi
Immunefi

Immunefi is the premier bug bounty platform for smart contracts, where hackers review code, disclose vulnerabilities, get paid, and make crypto safer.