Ammplify — disclosed vulnerability reports and payouts

Every publicly disclosed and closed bug bounty report we hold for Ammplify, with our own summary of each finding and a link to the original disclosure.

Reports indexed
33
Total paid
$0
Critical
0
Largest payout
$0

This page collects the 33 closed, publicly disclosed Ammplify reports indexed on CoinBuggie. Nothing here is active or unpatched — every entry was published by the programme or the researcher after remediation.

The findings concentrate in Reentrancy, Logic error, Price manipulation, Integer overflow / underflow, across EVM-Solidity. Reading a single protocol end to end is the fastest way to see which assumptions its codebase repeatedly gets wrong, which is usually a better predictor of where the next finding lives than the category alone.

Use the vulnerability class links below to compare these findings against the same bug class in other protocols.

What reviewers look for

  • Reentrancy findings disclosed against Ammplify
  • Logic error findings disclosed against Ammplify
  • Price manipulation findings disclosed against Ammplify
  • Integer overflow / underflow findings disclosed against Ammplify

Curated highlights

The largest disclosed payouts in this group, with our own summary of each. Every report links back to the original disclosure.

highReentrancyEVM-Solidity$0

Ammplify: All taker collateral and collected fees can be stolen by re-entering via `RFTLib.settle` to manipulate uniswap spot price when adding Maker liquidity

Ammplify's maker liquidity functions compute and charge a user token amounts for a new or adjusted Uniswap v3 position, but never verify the amounts the contract actually spends when the pool mints that liquidity. Because RFTLib.settle invokes a user-supplied callback before PoolWalker settles and mints the position, an attacker can re-enter and move the pool spot price mid-transaction, causing the subsequent mint to consume far more of the higher-value token from the contract than was charged. After restoring the price, the attacker pockets the difference from the contract's own balances, which include all taker collateral and unclaimed pool fees. The documented path drains 90-99% of the contract's token balances in a single transaction and nets roughly $8,889 after 0.3% Uniswap fees.

AmmplifysherlockSep 22, 2025Open
highLogic errorEVM-Solidity$0

Ammplify: Attackers can drain the protocol tokens

Ammplify's Maker.newMaker() accepts a caller-supplied pool address without verifying it is a genuine Uniswap V3 pool created by the official factory. Because every pool address is written into the POOL_GUARD_SLOT before its mint() is invoked, an attacker can substitute their own contract that returns arbitrary owed amounts from the mint callback. The legitimate uniswapV3MintCallback then transfers the maker's full token balances to the attacker on those amounts, draining collected fees, JIT penalties, and potentially principal liquidity not yet minted. The protocol team acknowledged the issue and fixed it in PR #43 by validating the pool against the Uniswap V3 factory.

AmmplifysherlockSep 22, 2025Open
highPrice manipulationEVM-Solidity$0

Ammplify: Accrued maker fees not yet compounded can be stolen by manipulating uniswap pool spot price to reduce fees equivalent liquidity and liquidity share price on maker liquidity deposit

Ammplify, a Uniswap V3-based AMM, computes an "equivalent liquidity" figure from accrued-but-uncompounded maker fees by dividing fee value by per-unit-liquidity value at the live pool spot price (slot0). Because slot0 is manipulable within a single transaction, an attacker can drive the price to a point that collapses the equivalent-liquidity denominator, deposit maker liquidity at a deflated share price to receive extra shares, then restore the price and withdraw at the true share price — siphoning a large share of other makers' unbundled fees. The report's worked example shows ~387 token0 net profit against 977 token0 of fees with only ~2% manipulation cost, and the attack is repeatable and scalable.

AmmplifysherlockSep 22, 2025Open
mediumLogic errorEVM-Solidity$0

Ammplify: `Maker.adjustMaker` always reverts when trying to reduce maker liquidity while current price is below position range

Ammplify's Maker.adjustMaker enforces that both computed token deltas share the same sign when reducing a maker position, but one legitimate combination (xBalance < 0 with yBalance == 0) is misrouted into a branch that requires yBalance < 0 and therefore reverts. This combination arises exactly when the current pool price sits below the position range, so the position holds only token x and zero token y. As a result the user cannot reduce the position and their funds stay trapped in the contract, potentially permanently if the price never recovers above the lower tick — or at a real cost, since forcing the price back into range to enable reduction is expensive. The protocol relaxed the require condition to yBalance <= 0 in a fix committed to the Ammplify repository.

AmmplifysherlockSep 22, 2025Open
mediumLogic errorEVM-Solidity$0

Ammplify: NFTManager `burnAsset` always triggers JIT penalty on removal

Ammplify's NFTManager.burnAsset() closes a maker position by first calling MakerFacet.collectFees(), which writes the current block timestamp into the asset's stored timestamp, and only then calls removeMaker(). Because removeMaker() computes the position's held duration from that just-reset timestamp, the duration always evaluates to zero. When the JIT mechanism is configured with a non-zero penalty, FeeLib.applyJITPenalties then applies an unjustified haircut to the closing user's withdrawn principal even for long-held positions. The fix applied by the team stops updating the timestamp inside collectFees() so removeMaker() sees the true original open time.

AmmplifysherlockSep 22, 2025Open
mediumLogic errorEVM-Solidity$0

Ammplify: transferVaultBalance function is unusable and mistransfers user's funds due to hardcoded asset ID

Ammplify's admin vault-migration function, AdminFacet.transferVaultBalance, hardcodes TAKER_VAULT_ID (80085) and forwards it to VaultLib.transfer as the userId for both the source withdrawal and destination deposit. Because taker and view balances are keyed by each position's own assetId rather than any fixed id, the migration almost always targets an empty account, so the withdraw finds no shares and the entire call reverts, leaving the admin rotation tool unusable. Since assetIds are assigned sequentially, a user position will eventually collide with value 80085, at which point the same administrative call would silently move that user's funds between vaults without consent. The finding was upheld as medium and fixed by the protocol team via PR #37, with remediation recommending removal of the function, reliance on VaultLib.hotSwap lazy migration, and reserving id 80085 so it can never be handed to a user.

AmmplifysherlockSep 22, 2025Open

All reports in this group

Vulnerability classes disclosed here

Related protocol pages