# Enzyme Finance Missing Privilege Check Bugfix Review

Enzyme's GSN paymaster skipped trusted-forwarder validation, letting an attacker supply a malicious forwarder to fake signatures and drain the Vault via inflated relay fees.

- Payout: $400,000
- Severity: critical
- Program: Enzyme Finance
- Credited: rootrescue
- Disclosed: 2023-05-19
- Write-up quality: 8/10
- Original: https://immunefi.com/blog/bug-fix-reviews/enzyme-finance-privilege-check/
- Library page: https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-enzyme-finance-privilege-check
- Tags: domain:web3 impact:funds-loss kind:bounty platform:blog platform:immunefi sev:critical tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:business-logic vuln:signature-replay

**Target:** GasRelayPaymasterLib paymaster contract on GSN RelayHub
**Root cause:** GasRelayPaymasterLib overrode the external function containing the trusted-forwarder validation, so preRelayedCall never verified the supplied forwarder address, allowing an attacker-controlled forwarder to bypass signature checks.
**Steps:**
1. Deploy a malicious forwarder contract that skips signature verification and returns the spoofed `from` address.
2. Craft `relayRequest` with `from` = VaultOwnerAddr, `to` = ComptrollerProxyAddr, `data` = `0x39bf70d1` (callOnExtension()), and `forwarder` = malicious forwarder.
3. Set `relayData.pctRelayFee` = 1000 (1000%), `baseRelayFee` = 0, `relayWorker` = attacker address, `paymaster` = Enzyme paymaster, `paymasterData` = true to auto-top-up from Vault.
4. Call `RelayHub.relayCall(defaultMaxAcceptance, {request, relayData}, requestSignature, approvalData, externalGasLimit)`.
5. Repeat relayCalls until the target fund's Vault is drained.
**How found:** Researcher reviewed Enzyme's GSN integration contracts (GasRelayPaymasterLib, GasRelayPaymasterFactory, GasRelayRecipientMixin) and noticed the external function containing the trusted-forwarder check was overridden in GasRelayPaymasterLib, meaning preRelayedCall never validated the forwarder address.
**Exploitation:** Attacker deploys a malicious forwarder, then submits relayCalls to RelayHub pointing at Enzyme's paymaster with the malicious forwarder and inflated pctRelayFee. The paymaster, lacking forwarder validation, reimburses the attacker's relayWorker far more than actual gas cost; with paymasterData=true it auto-tops-up from the Vault. Repeated calls drain the Vault that funds paymasters.
**Escalation:** Because Enzyme deploys many funds each holding only ~0.5 ETH, the attacker scales by issuing many relayCalls and leveraging automatic Vault top-up to drain each fund's Vault.
**Insight:** When auditing GSN/meta-tx integrations, check whether the paymaster's preRelayedCall actually validates the forwarder against a trusted allowlist; an overridden or inherited function that drops that check lets you supply your own forwarder and forge the `from` address, then abuse pctRelayFee/baseRelayFee and paymasterData auto-top-up to extract funds.
