Puffer
PufferDetails
Scope
My Submission
Puffer Bug Bounty Program
Severity and Rewards
Vulnerabilities are classified using two factors: Impact and Conditions. The combination of these factors determines the severity and guides the reward amount.
Severity Levels
Vulnerabilities will be classified according to the following severity levels:
- Critical
- Direct theft of any user funds (or assets), whether at-rest or in-motion, other than yield or rewards, without limitations of external conditions. The loss must exceed 20% of the protocol's TVL.
- Permanent freezing of user funds
- Protocol insolvency due to accounting errors
- High
- Direct theft of user funds, including yield and rewards, with moderate conditions. The loss must exceed 5% of the protocol's TVL
- Temporary freezing of user funds (>7 days)
- Permanent freezing of unclaimed yield
- Medium
- Causes a loss of funds requiring extensive limitations. The loss must exceed 0.01% of the protocol's TVL.
- Smart contracts are inoperable due to a lock of funds
- Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
- Block stuffing
Impact Assessment
The severity level of a vulnerability will be determined based on both its impact and conditions:
- Impact Factors
- Amount of funds at risk
- Number of users affected
- Duration of the vulnerability's effect
- Complexity of exploitation
- Requirement for privileged access
- Conditional Factors
- Technical complexity of the exploit
- Required preconditions for exploitation
- Opportunity window for exploitation
Reward Structure
Reward Amounts
Rewards will be paid in USDC according to the following structure:
| Severity Level | Reward Range |
|---|---|
| Critical | 25,000 USD - 100,000 USD |
| High | 10,000 USD - 25,000 USD |
| Medium | 1,000 USD - 3,000 USD |
- Reward Calculation for Critical Vulnerabilities
- For critical vulnerabilities, the reward amount will be calculated as 10% of the funds directly affected, up to a maximum of 100,000 USD. The calculation of the amount of funds at risk will be based on the time and date the bug report is submitted.
- A minimum reward of 25,000 USD will be awarded for critical vulnerabilities to incentivize security researchers against withholding bug reports.
- Reward Calculation for High Severity Vulnerabilities
- For high-severity vulnerabilities, rewards will be capped at up to 100% of the funds affected, with a maximum of 25,000 USD.
- A minimum reward of 10,000 USD will be awarded for high-severity vulnerabilities to incentivize security researchers against withholding bug reports.
- Reward Calculation for Medium Severity Vulnerabilities
- For medium-severity vulnerabilities, rewards will be capped at up to 100% of the funds affected, with a maximum of 3,000 USD.
- A minimum reward of 1,000 USD will be awarded for medium-severity vulnerabilities to incentivize security researchers against withholding bug reports.
General Notes
- Sherlock's Criteria for Issue Validity guide can be a helpful resource for more context on out-of-scope issues, etc. but nothing in the guide should overrule the definitions above
- A coded Proof of Concept (POC) with instructions to run the POC is required
- If the protocol team has the ability to take measures (upgrade the contract, pause the contract, etc.) against an exploit, the potential damage is limited to a 1-hour exploit period before it is assumed that the protocol team takes measures to prevent further damage
Platform Rules
Please review the Sherlock Bug Bounty Platform Rules before submitting any vulnerability.
Scope
Out of scope
- External oracles are assumed to operate correctly, remain available, and not deviate from expected behaviour. Incorrect data or pricing information supplied by third-party oracles is out of scope.
- Vulnerabilities that have already been reported or are known to the protocol team
- Issues that have been identified in previous audits and are pending fixes
- Vulnerabilities in the blockchain itself
- Issues in third-party libraries or dependencies not developed by the protocol team
- Theoretical vulnerabilities without a working proof of concept
- Issues requiring privileged access (e.g., governance or admin keys)
- Economic or tokenomic vulnerabilities that do not result in direct loss of funds
- Centralization risks inherent to the protocol design
- UI/UX issues that do not impact security
- Documentation errors or inconsistencies
- Spelling or grammar mistakes
- Issues caused by attacks requiring access to leaked keys/credentials
- A one-block DOS — where the attacker causes a transaction to revert in a single block, but it can be successfully re-executed in the next block — is evaluated based on that single occurrence only, even if the attack is theoretically repeatable. Such an issue is presumed not to repeat. It qualifies as valid only if the affected functionality is clearly time-sensitive.
Disclosure Policy
All vulnerabilities must be reported exclusively through the Sherlock platform and must not be disclosed publicly until:
- The vulnerability has been verified by the protocol team
- A fix has been implemented and deployed
- The protocol team has granted explicit permission for public disclosure
Premature public disclosure can result in disqualification from the reward.
Testing
When testing for vulnerabilities:
- Do not test on public mainnet deployments
- Use local test environments or testnets for all testing
- Do not attempt to access or modify other users' data
- Do not perform any actions that could disrupt the normal operation of the protocol
- Do not use automated scanning tools without manual verification
Prohibited actions
The following actions are strictly prohibited:
- Attempting to access private user data
- Social engineering or phishing attacks
- Denial of service attacks
- Physical or electronic attempts to access protocol's infrastructure
- Any testing that violates applicable laws or regulations
- Threatening or harassing behavior
Additional Context
Chains in scope
Primary — Ethereum Mainnet (chainId 1). All core protocol contracts live here: PufferVaultV5 (pufETH), PufferProtocol, PufferWithdrawalManager, PufferModuleManager / PufferModule / RestakingOperator / RestakingOperatorController, PufferOracleV2, ValidatorTicket + ValidatorTicketPricer, GuardianModule + EnclaveVerifier, PufferRevenueDepositor, L1RewardManager, PufferDepositorV2, PufferL2Depositor / PufToken / PufLocker, AVSContractsRegistry, AccessManager, Timelock, PUFFER, CARROT, CarrotVesting.
Secondary — chains hosting bridged pufETH / PUFFER representations (bridge-side token + pool contracts only; no core protocol logic is deployed there):
| Chain | Chain ID | What is deployed |
|---|---|---|
| Arbitrum | 42161 | pufETH (CCIP BurnMint token + pool) |
| Base | 8453 | pufETH (LayerZero OFT), PUFFER (LayerZero OFT), xPufETH (xERC20) + CCIP pool, L2RewardManager, AccessManager, Timelock |
| BNB Chain | 56 | PUFFER (LayerZero OFT), xPufETH + CCIP pool, AccessManager, Timelock |
| Berachain | 80094 | pufETH (CCIP BurnMint token + pool) |
| Linea | 59144 | pufETH (LayerZero OFT) |
Ethereum Mainnet is the hub for every lane; there are no spoke-to-spoke lanes.
Explicitly out of scope, chain-wise:
- All testnets (Holesky/Hoodi/Sepolia and any testnet deployment).
- Third-party bridge infrastructure itself: Chainlink CCIP routers/RMN/on-ramps/off-ramps, LayerZero Endpoints/DVNs/executors, and canonical/native chain bridges (Scroll, Manta, zkLink Nova). Puffer-owned configuration of those systems (peers, pools, rate limits, lane wiring) is in scope.
- The deprecated Connext / Everclear
xPufETHbridge path, which is non-functional and being retired. - Third-party integrations Puffer depends on but does not control: EigenLayer core contracts, Lido (stETH / wstETH / withdrawal queue), the beacon chain deposit contract.
Trusted protocol roles
Access control on Ethereum Mainnet is OpenZeppelin AccessManager-based (0x8c1686069474410E6243425f4a10177a94EBEE11). The table below reflects the live on-chain state, verified at mainnet block 25,747,098. Role labels are the on-chain RoleLabel values. Note that the Roles.sol constants file in the repository is not fully in sync with the deployment — the on-chain ACL is authoritative.
Trust model in one line: findings that require a trusted role to act maliciously or to sign a bad transaction are out of scope. Findings where (a) an unprivileged actor obtains a privileged role or reaches a restricted function, (b) a semi-trusted automated key can cause loss beyond its intended permission set, or (c) a role's own action can be exploited/front-run by a third party, are in scope.
Fully trusted (out of scope as attackers)
| Role (on-chain label) | ID | Current holder(s) | Powers |
|---|---|---|---|
ADMIN_ROLE | 0 | Timelock 0x3C28B7c7Ba1A1f55c9Ce66b263B33B204f2126eA | AccessManager admin: grant/revoke roles, open/close targets, all UUPS upgrades |
Puffer DAO | 77 | Operations Multisig 0xC0896ab1A8cae8c2C1d27d011eb955Cca955580d | Protocol parameters: exit fee & treasury exit fee, VT penalty, protocol/guardian fee rates, module weights, per-module validator limits, max withdrawal amount, reward mint amount/frequency & destination EID, module creation, claimer/operator config, VT pricer discount rate |
Operations Multisig | 22 | Operations Multisig 0xC0896ab1… | returnExcessETHToVault, PufferRevenueDepositor.callTargets, VT-pricer tolerance bounds, vault ops. Also the Ownable owner of every bridge contract (LayerZero OFTs/adapters, Chainlink CCIP token pools) on all chains |
Withdrawal Finalizer | 25 | Operations Multisig 0xC0896ab1… (sole holder) | PufferWithdrawalManager.finalizeWithdrawals, PufferVaultV5.initiateETHWithdrawalsFromLido, PufferVaultV5.claimWithdrawalsFromLido |
Operations Paymaster | 23 | Operations Multisig 0xC0896ab1… (sole holder) | PufferProtocol.skipProvisioning, batchHandleWithdrawals, EigenLayer module operations via PufferModuleManager |
Revenue Depositor | 26 | Operations Multisig 0xC0896ab1… | PufferRevenueDepositor.depositRevenue |
| Community Multisig | — | 0x446d4d6b26815f9bA78B5D454E303315D586Cb2a | Timelock.executeTransaction with 0 delay; also still holds legacy role 1 |
| Pauser Multisig | — | 0x1ba8e3aA853F73ae8093E26B7B8F2520c3620Df4 | Timelock.pause / pauseSelectors — instant pause of AccessManager-governed targets. Un-pausing goes through the normal delayed queue |
All UUPS upgrades (_authorizeUpgrade is restricted) are gated by this set, behind a Timelock with a 7-day MINIMUM_DELAY for the Operations Multisig.
Semi-trusted — automated keys (assumed honest, but not assumed to be secure; escalation beyond their permission set is in scope)
| Role (on-chain label) | ID | Current holder(s) | Powers |
|---|---|---|---|
VT_PRICER | 125 | 0xf9DfbF71f2D9c8a4E565E1346AEB2c3e1Dc765dE (automated executor contract) | ValidatorTicketPricer.setDailyMevPayouts, setDailyConsensusRewards, setDailyRewardsAndPostMintPrice — posts the VT mint price, bounded by DAO-set tolerance bps |
Operations Coordinator | 24 | ValidatorTicketPricer 0x9830aD1b…, Operations Multisig, 0x3fEE9276…, 0xE6D79816… | Pushes the resulting VT mint price into PufferOracleV2 |
REWARDS_MINTER | 28 | 0xb886a435d07C3731Bdd71A49Ac7bd3629b0Df9d5 (EOA) | L1RewardManager.mintAndBridgeRewards — mints rewards pufETH and bridges to L2, capped by the DAO-set amount and frequency |
ROLE_ID_AVS_COORDINATOR_ALLOWLISTER | 5 | Operations Multisig | Allowlists AVS calls in AVSContractsRegistry |
| Guardians | — (enforced in GuardianModule, not the AccessManager) | Guardian EOAs, m-of-n, SGX-attested | Co-sign validator provisioning, skipping and ejection |
Guardian collusion (m-of-n signing something malicious) is out of scope; bypassing or forging guardian signatures / enclave attestation is in scope.
Contract-held roles (held by protocol contracts, not EOAs — any path letting an external actor reach these is in scope)
| Role | ID | Holder(s) |
|---|---|---|
Puffer Protocol | 1234 | PufferProtocol 0xf7b6B324… |
Puffer Vault Withdrawer | 1235 | PufferProtocol, PufferModuleManager 0x9E1E4fCb…, PufferWithdrawalManager 0xDdA04831… |
pufETH Burner | 1236 | PufferProtocol, PufferWithdrawalManager, ValidatorTicket 0x7D26AD6F… |
ROLE_ID_L1_REWARD_MANAGER | 20 | L1RewardManager 0x157788cC…, Operations Multisig — gates PufferVaultV5.mintRewards / revertMintRewards |
ROLE_ID_BRIDGE | 8 | LayerZero EndpointV2 0x1a440760…, 0x8898b472…, Operations Multisig — gates L1RewardManager.lzCompose |
PUBLIC_ROLE (type(uint64).max) marks the permissionless entrypoints, including PufferVaultV5.deposit/mint/withdraw/redeem/depositETH, PufferWithdrawalManager.requestWithdrawal / requestWithdrawalWithPermit / completeQueuedWithdrawal, ValidatorTicket.purchaseValidatorTicket* and burn, and ValidatorTicketPricer.postMintPrice.
Ownable-style owners outside AccessManager (all trusted multisigs)
PUFFER token owner (pause + from/to allowlist) · CarrotVesting owner (pause/unpause, recoverPuffer, vesting re-initialization) · all LayerZero OFT/OFTAdapter and Chainlink CCIP token pool owners (chain Operations Multisig) · on the xERC20 chains, xPufETH mint/burn is gated by that chain's AccessManager, with per-bridge caps set via setLimits.
Tokens
Puffer-issued tokens (in scope)
| Token | Contract | Notes |
|---|---|---|
| pufETH | PufferVaultV5 (0xD9A442856C234a39a81a089C06451EBAa4306a72) | ERC4626 + ERC20Permit reward-bearing LRT; the protocol's core accounting token |
| pufETH (bridged) | LayerZero OFT / CCIP BurnMintERC677 representations | Base, HyperEVM, Linea, MegaETH, Monad, TAC (LZ); Arbitrum, Berachain, Soneium (CCIP) |
| xPufETH | xPufETH xERC20 (upgradeable, AccessManaged) | Mainnet, Base, BSC, Zircuit, Ape. Mint/burn is restricted and additionally capped by per-bridge setLimits mint/burn limits |
| PUFFER | PUFFER (0x4d1C297d39C5c1277964D0E3f8Aa901493664530) | ERC20Votes + ERC20Permit; pausable with an owner-managed from/to transfer allowlist. Bridged to Base and BSC via LayerZero OFT |
| VT (Validator Ticket) | ValidatorTicket | Upgradeable ERC20Permit, mint by ETH or pufETH purchase, burned on validator provisioning; protocol/guardian/treasury fee split |
| CARROT | CARROT | Fixed 100M supply ERC20Permit |
| Vesting positions | CarrotVesting | Burns CARROT for linearly vested PUFFER (55M PUFFER against 100M CARROT, 0.55 exchange rate) |
External tokens the protocol integrates with (issuer bugs out of scope; Puffer's handling of them in scope)
ETH (native), WETH (withdrawal payouts are made in WETH), stETH and wstETH (Lido — including the Lido withdrawal-queue ERC721 request NFTs held by the vault), EigenLayer strategy shares held via PufferModule, and every ERC20 allowlisted into the L2 staking PufToken wrappers.
Assumptions: all Puffer-issued tokens are standard 18-decimal ERC20s with no fee-on-transfer and no rebasing (pufETH is share-based, not rebasing; stETH's rebasing behaviour is handled explicitly). Issues that depend on a non-standard token being added to an allowlist by a trusted role are out of scope.
Design choices
The following are intentional and accepted; reports that merely describe them will be closed as informational.
- Privileged upgradeability & centralization. Every core contract is UUPS-upgradeable and every
restrictedfunction is gated by the AccessManager. The DAO/Operations Multisig behind a 7-day Timelock (and the Community Multisig with 0 delay) can upgrade implementations and change parameters. This is a deliberate operational trade-off. - Instant pause, delayed un-pause. The Pauser Multisig can close targets or individual selectors through the Timelock with no delay; re-opening must be queued through the normal delayed flow (or the Community Multisig with 0 delay). Griefing scenarios that assume a malicious Pauser are out of scope.
- Exit fee on redemptions. pufETH redemptions carry an exit fee, DAO-settable and hard-capped at 2.5% (
_MAX_EXIT_FEE_BASIS_POINTS). The fee accrues to remaining holders by design. - Same-block deposit/withdraw is blocked. The vault marks deposits and rejects a withdrawal in the same block from the same actor, as an anti-sandwich/flash-loan measure. The resulting UX restriction is intended.
- Smoothed reward accrual.
PufferRevenueDepositordrips deposited revenue into the exchange rate over a rewards-distribution window rather than in one jump, specifically to make exchange-rate sandwiching unprofitable. Residual, economically-insignificant MEV around this window is accepted. - Two-step, batched withdrawals. Users
requestWithdrawal, batches are filled toBATCH_SIZEand finalized by the Withdrawal Finalizer, and the payout usesmin(exchange rate at request, exchange rate at batch settlement)— a user never profits from a rate increase after requesting, and absorbs a decrease. Payout is in WETH. Batch dust is returned to the vault viareturnExcessETHToVault. Withdrawals are not instant and depend on available exit liquidity: this is by design. - Off-chain-driven validator lifecycle. Provisioning, skipping and ejection require m-of-n guardian signatures produced inside SGX enclaves; the Paymaster drives sequencing. Liveness depends on these off-chain actors, and that dependency is accepted.
- Oracle-reported backing.
PufferOracleV2reports beacon-chain ETH backing and sets the VT mint price; the exchange rate is only as accurate as those reports. Oracle-liveness and oracle-honesty issues are out of scope; issues where a third party can manipulate or front-run an oracle update are in scope. - PUFFER transfer restrictions. The PUFFER token is pausable with an owner-managed sender/receiver allowlist, an intentional distribution-phase control.
- CarrotVesting owner controls. The vesting duration/steps have been re-initialized on purpose (old and new positions coexist), and the owner can pause and recover unclaimed PUFFER. This is intended.
- Bridging is provider-delegated. pufETH/PUFFER move only via Chainlink CCIP and LayerZero, always through Ethereum Mainnet as the hub. Chainlink CCIP pool rate limiters are currently disabled; the xERC20
setLimitslayer onxPufETHis the active throttle. LayerZero OFTs have no rate limiter — bounded only by DVN configuration (required DVNs: P2P + Horizen, 15 confirmations). These configuration choices are deliberate. - Deterministic CREATE2 addresses. The same address intentionally hosts different contracts on different chains. Address collisions across chains are expected and not a finding on their own.
- Known role-ID overlap.
ROLE_ID_WITHDRAWAL_FINALIZERandROLE_ID_VT_PRICERshare numeric ID 25 inRoles.sol; this does not reflect the live deployment and will be updated in the next code update. - Rounding. Standard ERC4626 share/asset rounding always favours the vault (i.e. existing holders). Wei-level rounding dust is not a valid finding absent a concrete, materially profitable exploit path.
Protocol Resources
- Documentation: https://docs.puffer.fi/
- Contracts monorepo: https://github.com/PufferFinance/puffer-contracts
- Deployment addresses & full access-control list (all chains): https://github.com/PufferFinance/Deployments-and-ACL/tree/main/docs/deployments
- Audit reports: https://github.com/PufferFinance/puffer-contracts/tree/master/audits (index in the repo README) — Cantina/Spearbit, BlockSec, SlowMist, Nethermind, Trail of Bits, Creed, Quantstamp, Immunefi Boost
- Website: https://www.puffer.fi
- Security contact: security@puffer.fi (also declared as
@custom:security-contactin every contract) - Community: https://discord.gg/pufferfi · https://twitter.com/puffer_finance
Recently audited code — prior findings out of scope
A significant portion of the codebase has been reworked and improved since the previous public releases. This new code was audited by Nethermind (report: https://github.com/PufferFinance/puffer-contracts/blob/audit/combined-2026-05/audits/NM_0985_Puffer_Contracts_FINAL_2026.pdf).
Any issue that was already reported, identified, or acknowledged in that Nethermind audit — including issues already fixed, and issues accepted as risks with a documented rationale — is out of scope for this bounty. The same applies to findings from the other published audits linked above.
Duplicate submissions of known findings will be closed without reward. Researchers are expected to review the published audit reports before submitting. A report is only eligible if it identifies a genuinely novel issue, or a new, materially different exploitation path for a previously known issue that the applied fix does not cover.
Max Rewards
100,000 USDCStatus
Live since
Last updated
LIVE
Aug 17, 2026, 2:44 PM
Aug 17, 2026, 2:44 PM