[Temp Check] Protocol Fee Expansion: Eight More Chains and Remaining Mainnet v3 Pools

This is the first proposal to use the new governance process approved in UNIfication. The new process only applies to fee parameter updates, where proposals can bypass the RFC stage and go directly to a five-day Snapshot followed by an onchain vote. This allows for faster updates to protocol fees, while retaining the security of onchain governance.

Snapshot vote here: https://snapshot.org/#/s:uniswapgovernance.eth/proposal/0x0242a914c60945d25873d2a98c6abd9f69cb889c6616e27f3c0ab759f9e8d783

Since UNIfication went live in late December we have been monitoring protocol fees, which were rolled out gradually to ensure protocol health. This started with v2 and select v3 pools on Ethereum mainnet. This rollout has gone well, with market-adjusted TVL up on Ethereum mainnet since December. The burn system is working as expected, permissionlessly converting fees in many different tokens into UNI burns.

Now, we propose to:

  • Expand protocol fees on v2 and v3 to Arbitrum, Base, Celo, OP Mainnet, Soneium, X Layer, Worldchain, and Zora
  • Enable protocol fees on all v3 pools via a new tier-based v3OpenFeeAdapter on mainnet and the above L2s

Implementation Details

Expand protocol fees to L2s and burn UNI on mainnet

This proposal introduces v2 and v3 protocol fees on eight chains. Fees on each chain will be routed to the TokenJar on that respective chain.

UNI burned on L2s doesn’t stay on L2s - it is bridged back to mainnet and sent to 0xdead. This uses the same infrastructure used for burning Unichain sequencer fees (OptimismBridgedResourceFirepit for OP Stack chains, and ArbitrumBridgedResourceFirepit for Arbitrum).

Enable fees on all v3 pools

The current v3FeeAdapter manages protocol fees pool by pool and governance maintains a list of individual pools and their fee levels. Today, those pools account for a significant majority of v3 volume on Ethereum mainnet.

v3OpenFeeAdapter replaces this with a tier-based system. Protocol fees are set uniformly across all pools sharing the same LP fee tier. For example, all 1bps LP fee pools could have protocol fees set to 25%. Any pool automatically gets the default protocol fee for its tier, no governance action is needed. This means if this proposal passes, protocol fees will be active on every v3 pool. Governance retains the ability to override fees on individual pools.

Proposal Spec

Pre-proposal - complete before onchain vote:

/// For each L2:

/// Deploy the TokenJar

TokenJar tokenJar = new TokenJar{salt: SALT_TOKEN_JAR}();

/// Deploy the chain-specific Releaser

/// OP Stack (Optimism, Base, Zora, Worldchain, etc.):

OptimismBridgedResourceFirepit releaser = new OptimismBridgedResourceFirepit{salt: SALT_RELEASER}(RESOURCE, THRESHOLD, address(tokenJar));

/// Arbitrum:

ArbitrumBridgedResourceFirepit releaser = new ArbitrumBridgedResourceFirepit{salt: SALT_RELEASER}(RESOURCE, L1_RESOURCE, THRESHOLD, address(tokenJar));

/// Set the releaser on the TokenJar (must be before ownership transfer)

tokenJar.setReleaser(address(releaser));

/// Set the thresholdSetter on the Releaser (must be before ownership transfer)

releaser.setThresholdSetter(TIMELOCK_ALIAS);

/// Transfer ownership of the TokenJar and Releaser to governance

tokenJar.transferOwnership(TIMELOCK_ALIAS);

releaser.transferOwnership(TIMELOCK_ALIAS);

/// For each L2 and Mainnet:

/// Deploy the V3OpenFeeAdapter

V3OpenFeeAdapter v3OpenFeeAdapter = new V3OpenFeeAdapter{salt: SALT_FEE_ADAPTER}(address(V3_FACTORY), address(tokenJar));

/// Set the feeSetter (must be before ownership transfer)

v3OpenFeeAdapter.setFeeSetter(TIMELOCK_ALIAS); // L2

v3OpenFeeAdapter.setFeeSetter(TIMELOCK); // Mainnet

/// Transfer ownership to governance

v3OpenFeeAdapter.transferOwnership(TIMELOCK_ALIAS); // L2

v3OpenFeeAdapter.transferOwnership(TIMELOCK); // Mainnet

/// For Mainnet only:

/// Deploy the Firepit (mainnet-only releaser, burns directly)

Firepit releaser = new Firepit{salt: SALT_RELEASER}(RESOURCE, THRESHOLD, address(tokenJar));

/// Set the releaser on the TokenJar (must be before ownership transfer)

tokenJar.setReleaser(address(releaser));

/// Set the thresholdSetter on the Releaser (must be before ownership transfer)

releaser.setThresholdSetter(TIMELOCK);

/// Transfer ownership of the TokenJar and Releaser to governance

tokenJar.transferOwnership(TIMELOCK);

releaser.transferOwnership(TIMELOCK);

In this proposal, if passed:

/// For each L2:

/// Set the owner of the V3 Factory to the V3OpenFeeAdapter

V3_FACTORY.setOwner(address(v3OpenFeeAdapter));

/// Set the recipient of V2 protocol fees to the TokenJar

V2_FACTORY.setFeeTo(address(tokenJar));

/// For Mainnet:

/// Transfer V3 Factory ownership through the V3OpenFeeAdapter

v3OpenFeeAdapter.setFactoryOwner(address(v3OpenFeeAdapter));

Governance Process

Please note that because of GovernorBravo’s limit of 10 actions per proposal, there will be two separate onchain votes posted in parallel. One proposal will include the change to mainnet’s fee controller and turn on fees on Base, OP Mainnet, and Arbitrum, the other will turn on fees on Celo, Soneium, Worldchain, X Layer, and Zora.

6 Likes

The following reflects the views of L2BEAT’s governance team, composed of @kaereste and @Manugotsuka, and it’s based on their combined research, fact-checking, and ideation.

We voted FOR.

We view it as a natural continuation of the UNIfication framework approved in December, extending the existing fee collection and UNI burn architecture to additional chains and replacing the curated v3 allowlist with a universal adapter. Fee parameters remain unchanged. Before voting, we asked our research team to validate the full implementation, including contract behavior and burn mechanics.

For a detailed technical breakdown of what was verified, what remains unpublished, and the associated risks, please see the full analysis below. This review was conducted by the L2BEAT Research Team as part of the independent technical due diligence we require before voting on proposals of this scope.


What happened in December

Proposal #93 “UNIfication” passed in December 2025. It burned 100M UNI, turned on protocol fees for V2 and V3 on Ethereum mainnet, and approved a 40M UNI growth budget for Uniswap Labs over two years. In return, Labs eliminated all interface, wallet, and API fees.

UNIfication deployed three new contracts:

  • TokenJar - an immutable sink that collects fee tokens from pools. Only a designated releaser can withdraw.
  • Firepit - the releaser on mainnet. A searcher pays a fixed UNI amount (4,000 UNI), receives the accumulated fee tokens, and the UNI paid gets burnt, transferred to 0xdead .
  • V3FeeAdapter - a Merkle-proof-based adapter that acts as the V3 Factory owner and sets protocol fees only on pools included in a curated allowlist (roughly 80-95% of mainnet volume).

What’s being proposed now

The Temp Check - authored by Hayden Adams - does two things:

1. Expand protocol fees to eight L2s: Arbitrum, Base, Celo, OP Mainnet, Soneium, Worldchain, X Layer, and Zora. Both V2 and V3 pools are on each chain.

2. Replace the curated Merkle adapter with an open one. The new V3OpenFeeAdapter drops the allowlist entirely. Every V3 pool inherits a protocol fee by default. Governance can exempt individual pools, but the default is fees on.

Due to GovernorBravo’s 10-action limit, execution splits into two parallel proposals:

  • Proposal A: Mainnet V3OpenFeeAdapter + Base, OP Mainnet, Arbitrum
  • Proposal B: Celo, Soneium, Worldchain, X Layer, Zora

How the money flows (and burns)

The fee collection and burn architecture extends the mainnet system to L2s with chain-specific bridging:

Pools (v2/v3) on each chain
    │
    â–Ľ
TokenJar ─── Immutable fee sink. Holds all collected tokens.
    │
    â–Ľ
Releaser ─── Searcher pays UNI threshold, receives fee tokens.
    │
    ├─ Ethereum: Firepit ─── UNI sent to 0xdead directly
    ├─ OP Stack: OptimismBridgedResourceFirepit ─── bridges UNI to L1 0xdead
    └─ Arbitrum: ArbitrumBridgedResourceFirepit ─── bridges UNI to L1 0xdead

The protocol never converts fee tokens into UNI. Instead, it relies on a searcher auction: fee tokens accumulate in the TokenJar until a searcher decides the pot is worth more than the fixed UNI cost. The searcher pays 4,000 UNI (mainnet) or 2,000 UNI (L2s), receives all accumulated tokens, and the UNI is burned. The design avoids DEX routing, slippage management, and oracle dependency - burn frequency depends entirely on searcher competition and accumulated value.

On L2s, UNI doesn’t burn locally. It bridges to Ethereum L1 first, via L2StandardBridge on OP Stack chains, via L2GatewayRouter on Arbitrum - and once the withdrawal finalises, it is burnt by transfer to the 0xdead address.

The V3OpenFeeAdapter: from allowlist to all pools

The old adapter required a Merkle proof to set fees on a pool - governance curated the list, targeting pools where Uniswap held 90%+ market share to minimize LP attrition risk. The new adapter inverts the default:

Merkle-based (current) Open adapter (proposed)
New pools No fee unless added to Merkle tree Fee on - inherits tier default
Opt-out Not in the tree = no fee Only via governance poolOverride to zero
Coverage ~80-95% of volume 100% of V3 pools

The adapter resolves fees through a three-level waterfall: pool-specific override, then fee-tier default, then global default. A ZERO_FEE_SENTINEL (value 255) distinguishes “not configured” from “explicitly exempt.” Anyone can call triggerFeeUpdate() to apply the current fee to any pool - no governance action required.

Fee parameters are identical to December’s UNIfication. No increase:

LP Fee Tier Protocol Take Effective Protocol Fee
0.01% 1/4 of LP fees ~0.0025%
0.05% 1/4 of LP fees ~0.0125%
0.30% 1/6 of LP fees ~0.05%
1.00% 1/6 of LP fees ~0.167%

Risks

The shift from allowlist to universal bets that Uniswap’s network effects hold across the full pool spectrum - not just popular pairs. The risk is economic and reversible (governance can exempt pools), not a security concern.

What we verified

We reviewed the source code on the protocol-fees repository (main branch, no pinned commit hash provided)

  • TokenJar: Immutable fee sink, onlyReleaser withdrawal - confirmed.
  • Firepit: Constructor hardcodes RESOURCE_RECIPIENT = address(0xdead) - confirmed.
  • OptimismBridgedResourceFirepit: Two-stage collect-then-bridge via L2StandardBridge.withdrawTo() to L1 0xdead - confirmed. Covers Base, OP Mainnet, Soneium, Worldchain, Zora.
  • ArbitrumBridgedResourceFirepit: Same pattern via L2GatewayRouter.outboundTransfer() - confirmed.
  • V3OpenFeeAdapter: Permissionless waterfall fee resolution with sentinel for explicit zero - confirmed.
  • Fee parameters: Packed values (0x44, 0x66) match original UNIfication deployer - confirmed.
  • Ownership: All contracts transfer ownership to UNI Timelock (L1) or its L2 alias (0x2BAD...46CD) - confirmed for OP Stack and Arbitrum.

Contracts are immutable (no proxy pattern), but governance retains control: it can swap the releaser on any TokenJar (redirecting fee flow), adjust release thresholds, set per-pool fee overrides, and transfer V3 Factory ownership to a future adapter.

What we could not verify

Several elements remain unpublished ahead of the on-chain vote:

Celo and X Layer have no public implementation. No custom releasers, no deployment scripts, and no bridge contracts were found in the public repo. We cannot assess how UNI gets burned on these chains.

No on-chain proposal scripts are published. The Snapshot body contains pseudocode for Proposals A and B, but the actual FeeExpansionProposal scripts couldn’t be found in the repo. Exact calldata cannot be independently verified.

Audit scope is unclear. OpenZeppelin and Spearbit audited the original UNIfication contracts. Whether the new V3OpenFeeAdapter and L2-specific deployments fall within that audit scope - or require a separate review - has not been confirmed (?).

Bridged UNI addresses for three chains are TBD. Soneium, Worldchain, and Zora don’t yet have confirmed UNI token addresses in the deployment parameters.

Takeaway

Proposal A extends existing rates to new chains without increasing them. The universal fee adapter is a policy shift - from opt-in to opt-out - it’s an economic risk, not a security one.

Proposal B (Celo, Soneium, Worldchain, X Layer, Zora) covers chains whose bridge and burn path cannot be verified from public sources. Until the Celo and X Layer releaser contracts are published, delegates cannot confirm how - or whether - UNI gets burned on those chains.

My recommendation: The direction is sound for both proposals: extending proven fee infrastructure to new chains at unchanged rates.

  • Proposal A (Mainnet V3OpenFeeAdapter + Base, OP Mainnet, Arbitrum) - supportable at Temp Check. Implementation is verifiable from public source code.
  • Proposal B (Celo, Soneium, Worldchain, X Layer, Zora) - supportable at Temp Check, but the on-chain vote should be conditional on the missing pieces being published first.

Before the on-chain vote, delegates should require the proposer to publish:

  1. On-chain proposal calldata for both Proposals A and B
  2. Celo and X Layer bridge/releaser contracts
  3. Deployment scripts with a pinned commit hash
  4. Confirmation of audit coverage for the new contracts
2 Likes

Hey @Manugotsuka nice analysis, thank you! Proposal 95 was just posted with links to the deployed fee infra contracts. There’s an outstanding PR on the fee contract repo that notes them as well, I’ll get that merged.

1 Like

Clarification on V3OpenFeeAdapter Address in Onchain Execution

While reviewing the calldata for Function 4 in the onchain proposal, I noticed that the address being passed to:

V3FeeAdapter.setFactoryOwner(address)

is:

0xf2371551Fe3937Db7c750f4DfABe5c2fFFdcBf5A

However, in the proposal description and documentation, the mainnet V3OpenFeeAdapter is listed as:

0x3e40DB80450f025b01E45c58b0aF763C7A29a8bd

Could the team clarify why a different address is being used in the execution payload compared to the one referenced in the proposal specification?

Thanks in advance for the clarification.

1 Like

The correct address is 0xf2371551Fe3937Db7c750f4DfABe5c2fFFdcBf5A. The only difference between the contracts is a global default fee setting. There’s a getter function for that parameter (defaultFee()) so you can confirm on Etherscan. More info on fee resolution can be found here. Thanks for your diligence!

Thanks for clarification.

Am I correct in assuming this is a typo in the text? Was this an accident or was the address changed for some reason?

And there is a second question already connected with the second vote - why is the part on the execution of Sela included in both the first and the second part?

yeah typo in the text. in prepping for the proposal, the first contract deployment went out without the default fee configured. that deployment was added to docs and description. the default fee being set to 0 was discovered on review and a new contract was deployed. the testing scripts were update with the new address, the description was not.

Assuming your second question is about Celo:

  • celo started as an alt L1 and we used wormhole as the messaging bridge for governance
  • celo transitioned to a op-stack L2, and per recs from Bridge Evaluation Committee we should use native bridges for L2s (see appendix 4 here)
  • vote 1 migrates celo’s contract ownership from wormhole to a CrossChainAccount; future messages will be passed through the op-stack’s canonical messaging bridge
  • vote 2 passes a message through that bridge to turn on v2 and v3 fees

LMK if you have any more questions.

The following reflects the views of L2BEAT’s governance team, composed of @kaereste and @Manugotsuka, and it’s based on their combined research, fact-checking, and ideation.

We voted FOR the fee expansion in Votes 1 and 2.

Following our previous support at the Temperature Check stage, we are extending that position to the on-chain stage as well. These votes implement the UNIfication framework without changing fee parameters and represent execution of previously approved direction.

Ahead of the Temperature Check, we requested a full technical review from the L2BEAT Research Team. That analysis, which informed our initial position, is available here, and our vote today remains consistent with those findings.

1 Like