Security Audit Report: Reentrancy & Access Control Review: Gemini A senior DeFi security researcher at OpenAI Security Labs published an audit of the Gemini protocol, which holds roughly $5.37 billion in total value locked across Ethereum and several L2 rollups, flagging reentrancy and access-control weaknesses in its core contracts. The review rates the overall risk 8.7 out of 10, citing external calls made before state updates in GeminiVault.withdraw, GeminiLending.repay and GeminiRouter.swapExactTokensForTokens, a 1-of-3 multisig owner threshold, and an upgradeable PAUSER_ROLE contract without a timelock. The report warns that a combined reentrancy and pauser compromise could freeze the vault and drain funds before the community could respond. Target Protocol : Gemini TVL: $5369.8M Security Audit Report – Reentrancy & Access‑Control Review Protocol: Gemini TVL ≈ $5.37 B across Ethereum & L2s Date: 23 Oct 2026 Auditor: Senior DeFi Security Researcher – OpenAI Security Labs Gemini is a high‑value, cross‑chain liquidity hub that aggregates deposits, executes swaps, and provides lending/borrowing services on Ethereum mainnet and several L2 roll‑ups Optimism, Arbitrum, zkSync . The platform’s total value locked TVL of ~$5.37 B makes it a prime target for sophisticated adversaries. Our focused audit examined reentrancy and access‑control mechanisms across the core contracts: | Component | Primary Function | Criticality 1‑5 | |---|---|---| | GeminiVault | Custody of user deposits, ERC‑4626 share logic | 5 | | GeminiRouter | Cross‑chain swap routing, fee distribution | 4 | | GeminiLending | Collateral management, loan issuance | 5 | | GeminiAdmin | Governance & emergency pause | 5 | | GeminiBridge L2 adapters | Asset lock/unlock across roll‑ups | 4 | | Category | Findings | Severity | |---|---|---| | Reentrancy | • Several external‑call patterns e.g., transfer , call , delegatecall are performed before state updates in GeminiVault.withdraw , GeminiLending.repay , and GeminiRouter.swapExactTokensForTokens .• L2 bridge contracts use a pull‑based unlock that can be re‑entered via malicious token callbacks. | High 8/10 | | Access‑Control | • onlyOwner is used on many functions, but the owner is a multisig with a single‑signer threshold 1‑of‑3 – insufficient for a $5 B protocol.• GeminiAdmin.pause can be called by any address flagged as PAUSER ROLE which is granted to a single external contract that is upgradeable without a timelock.• Missing role revocation checks on grantRole / revokeRole allow an attacker who compromises a role admin to permanently seize admin rights. | Critical 9/10 | | Combined | A reentrancy exploit on withdraw combined with a compromised PAUSER ROLE could freeze the vault, drain funds, and prevent the community from reacting. | Critical 9/10 | Overall risk score: 8.7 / 10 rounded to 9 . The protocol’s size and the presence of high‑severity reentrancy and governance weaknesses warrant immediate remediation. | | Contract / Function | Vulnerability Description | Exploit Scenario | |---|---|---|---| | 1 | GeminiVault.withdraw uint256 shares | Calls IERC20 token .transfer msg.sender, amount before updating totalShares and the user’s shareBalance . | An attacker deploys a malicious ERC‑20 token that re‑enters withdraw via the ERC‑777 tokensReceived hook, repeatedly pulling out more shares than owned. | | 2 | GeminiLending.repay uint256 loanId, uint256 amount | Performs token.transferFrom msg.sender, address this , amount then updates loan.principal . | A malicious token’s transferFrom triggers a callback to repay again, allowing the attacker to repay a loan multiple times while only paying once, creating a negative debt that can be withdrawn later. | | 3 | GeminiRouter.swapExactTokensForTokens uint256 amountIn, … | Executes tokenIn.transferFrom msg.sender, address this , amountIn → router.swap ... → tokenOut.transfer msg.sender, amountOut before updating internal fee accounting. | An attacker’s token implements transferFrom that calls back into swapExactTokensForTokens , inflating the amountOut received while the fee state remains unchanged, resulting in fee theft. | | 4 | GeminiBridge.unlock address token, uint256 amount, address to L2 adapters | Uses a pull‑based unlock token.transfer to, amount after emitting a UnlockRequested event but before marking the request as completed . | A malicious token’s transfer callback re‑enters unlock , causing the same request to be processed multiple times, effectively minting assets on the L2 side. | | 5 | GeminiAdmin.upgradeTo address newImplementation UUPS proxy | Calls newImplementation.initialize after setting the implementation pointer. | If the new implementation contains a re‑entrancy‑prone initialize , an attacker can re‑enter the upgrade process and replace the implementation with a malicious contract before the upgrade finishes. | | | Contract / Function | Weakness | Potential Impact | |---|---|---|---| | A | GeminiAdmin.pause / unpause | PAUSER ROLE granted to GeminiBridgeAdapter upgradeable via proxyAdmin without timelock . | Compromise of the adapter e.g., via a malicious upgrade lets an attacker pause the entire protocol, freezing withdrawals and swaps. | | B | onlyOwner on critical functions setFee , setInterestRate , addSupportedToken | Owner is a 1‑of‑3 multisig; no time‑delay or secondary confirmation. | Single key compromise leads to immediate fee manipulation, token whitelist changes, or arbitrary fund transfers. | | C | grantRole / revokeRole in GeminiAccessControl | No renounceRole restriction for DEFAULT ADMIN ROLE ; any admin can grant itself admin rights. | An attacker who gains any role can elevate to admin and seize governance. | | D | GeminiLending.setCollateralFactor address token, uint256 factor | No on‑chain verification that token is a price‑feed‑supported asset. | Malicious token can be set with a 100 % collateral factor, enabling under‑collateralized borrowing. | | E | GeminiRouter.setRouter address newRouter | No onlyOwner check; uses onlyGovernor which is a role that can be granted by any existing governor. | Governance takeover via role escalation leads to routing to a malicious contract that siphons fees. | PAUSER ROLE via a malicious upgrade of the bridge adapter. GeminiVault.withdraw using a malicious ERC‑777 token to repeatedly call withdraw while the contract is paused the pause flag is checked The synergy of a pause‑bypass and reentrancy makes this a high‑impact, low‑complexity attack vector. | Priority | Recommendation | Rationale | Implementation Sketch | |---|---|---|---| | P1 | Apply the Checks‑Effects‑Interactions CEI pattern to every external call in GeminiVault , GeminiLending , GeminiRouter , and bridge contracts. | Eliminates classic reentrancy windows. | | solidity