Skip to content

Robinhood Chain·Scanned 05 Nov 2026, 01:40 UTC

PonsV2LauncherToken $ZHOOK

0x4a4fc33a4bf80d7bab0e1bab6d82af1e2942e917

Verdict

Caution

53/100 safety

Token has no owner, mint or blacklist; sells work with 0% token tax plus a 3% pool fee; launch heavily bundled.

The ZHOOK token contract is a clean launchpad template: nobody can mint, freeze or tax it, and test buys and sells worked, with only the pool's frozen 3% trading fee. The main concerns sit around it. Large bundled buys captured much of the supply at launch, and a single Pons protocol owner controls the hook, factory and LP locker, including rescue functions we could not fully review. The website also sells private trading features that the team's own docs and the dApp test show are not live yet. On the positive side, pool liquidity is locked, the deployer holds nothing and has burned about 8% of supply.

Score breakdown

  • Contract
    60
  • Token
    50
  • Social / X
    45
  • Website
    38

Higher is safer · 0 = worst · 100 = best

Yes
0%
None (no owner role)
0% / 100%
MC at check
$17.8K
MC now
no live price
Since check
—
Liquidity
$12.7K

Key findings

  • HighDApp requests an unlimited token approval to a contract we did not review
  • MediumOne protocol owner controls hook, factory, vault and LP locker
  • MediumBundled wallets bought a large share of supply at launch
  • MediumSite advertises private trading that docs and dApp test show isn't live
  • GoodOngoing token burns verified on-chain: 8.0% of supply burned

What would change the verdict

  • Raises safety:Pons protocol owner is shown to be a multisig or timelock, or the factory and locker source confirms no rescue or withdraw path → up
  • Lowers safety:Owner uses factory rescue functions to move funds from this launch, or the locker releases the LP → down
  • Lowers safety:Launch bundle wallets turn out to still hold a large share and start selling → down
Post on XView on explorer ↗

Findings

15 findings

Risks (7)

  • HighDApp requests an unlimited token approval to a contract we did not reviewotherDeterministic

    During the "Swap USDG to ETH" flow the dApp asks for an unlimited token approval in favour of an unknown spender, which is not among the contracts we analysed. Prefer approving only the exact amount.

    Evidence

    • forkdApp test "Swap USDG to ETH" on a local fork (https://dapp.zerohook.trade/)
      Show source
      wallet no balance change; 1 tx (approve ok). No successful transaction was made for this goal (timeout). | driver: timeout — goal time cap reached
    • forkapprove(address,uint256) → 0x5fc5360d0400a0fd4f2af552add042d716f1d168 (spender=0x0000…8BA3 (Permit2), value=MAX_UINT256 (unlimited))
    • forkdappTests: Swap USDG to ETH step approve
      Show source
      unlimited approval (unlimited) to 0x0000…8BA3 (Permit2) — known infra: Permit2

    Confirmed by: facts, claude-opus-5.5, grok-4.7, gpt-5.6-sol

  • MediumOne protocol owner controls hook, factory, vault and LP lockerownershipAI

    The same address, 0x263e…19Dd, owns the PonsV2MemeHook, PonsV2LaunchFactory, PonsV2BuybackVault and PonsV2LaunchLocker. The hook owner cannot renounce. On the hook, the owner can: - set the fee sweep operator; - call rescuePoolFees, which pays this pool's pending fees straight to the snapshotted protocol recipient and creator instead of through the escrow; - change global fee settings, which apply to future launches only. On the factory, the owner has rescueCurveFees and rescueSweptGraduation (the latter sends tokens/ETH out), forceSweptGraduation and per-launch overrides. The factory and locker source code was not provided, so the exact limits of these powers cannot be confirmed. Nothing seen lets this owner mint ZHOOK, block transfers or change this pool's fee rates. The main trust point is protocol-level fee handling and the unverified rescue paths. It is unknown whether this address is a multisig.

    Evidence

    • on-chainPonsV2MemeHook owner = 0x263ed295dAFaE1d9AAdD6E56c4B6F9f38eE019Dd; PonsV2LaunchFactory owner = 0x263ed295dAFaE1d9AAdD6E56c4B6F9f38eE019Dd; PonsV2BuybackVault owner = 0x263ed295dAFaE1d9AAdD6E56c4B6F9f38eE019Dd; PonsV2LaunchLocker owner = 0x263ed295dAFaE1d9AAdD6E56c4B6F9f38eE019Dd
    • codePonsV2MemeHook.sol:L235-L237
      Show source
      function renounceOwnership() public pure override {
              revert OwnershipCannotBeRenounced();
          }
    • codePonsV2MemeHook.sol:L555-L603
      Show source
      function rescuePoolFees(PoolId poolId)
              external
              onlyOwner
              nonReentrant
              returns (uint256 protocolAmount, uint256 creatorAmount)
          {
              LaunchInfo memory info = launches[poolId];
              if (!info.registered) revert UnknownPool();
              address quoteToken = info.quoteToken;
      
              if (quoteToken != address(0)) {
                  (protocolAmount, creatorAmount) = _rescueCurrency(poolId, info, quoteToken);
              }
              (uint256 memecoinProtocol, uint256 memecoinCreator) = _rescueCurrency(poolId, info, info.memecoin);
              if (protocolAmount == 0 && creatorAmount == 0 && memecoinProtocol == 0 && memecoinCreator == 0) {
    • staticfactory fn rescueSweptGraduation(address,address) [owner] @PonsV2LaunchFactory.sol:L1254-L1286 — sends tokens out, sends ETH

    Confirmed by: claude-opus-5.5, grok-4.7, gpt-5.6-sol

  • MediumBundled wallets bought a large share of supply at launchsnipersAI

    Same-block bundles bought large shares of supply on the curve right after launch, for example 21.30% in block 98528044 and 12.01% in block 98528043. Wallet 0x9247…528b appears in five bundles. Two funding clusters were identified, and both hold 0% now. None of the bundle wallets appear among the current top 20 holders, which suggests this early supply has mostly been sold. Sniper checks are paused, so current bundle holdings are not fully measured.

    Evidence

    • on-chaintoken.bundles block 98528044 pctSupply=21.2984; block 98528043 pctSupply=12.0061; block 98528029 pctSupply=8.7675
    • on-chaintoken.clusters pctSupplyHeldNow=0 (funders 0x53091256ebd2d8aa37b45536a5fd864ca764f32f, 0xf70da97812cb96acdf810712aa562db8dfa3dbef)
    • on-chaintoken.notes
      Show source
      Sniper checks are paused in this version.

    Confirmed by: claude-opus-5.5, grok-4.7, gpt-5.6-sol

  • MediumSite advertises private trading that docs and dApp test show isn't liveclaims-mismatchAI

    The marketing site tells buyers every swap already runs through a shielded pool, a single-use stealth wallet, amount splitting, timing jitter and private RPC. The project's own docs mark the shielded balance Pending and say anything Pending or Roadmap is not shipped. A later team post lists stealth wallets, private swap and those anti-tracking tools as coming next, not live. Someone buying $ZHOOK for the privacy product may be paying for features the team has not shipped. This is a product-claim gap, not a token-contract power.

    Evidence

    • Show source
      Default mode Private Every swap runs through the shielded flow.
    • Show source
      A new wallet for every trade. Balances sit in a shielded pool. Each swap leaves from a single-use stealth wallet
    • Show source
      Shielded balance Pending
    • Show source
      anything marked Pending or Roadmap is not shipped yet.
    • Show source
      Live: best-price swap, stock tokens, Swap API. Beta: shielded balance, private send, pay links. Next: private swap, stealth wallets, stealth orders, private payouts.
    • Show source
      Coming to Zerohook: the amount splitter.
    • forkdappTests: Swap ETH to USDG (passed=false)
      Show source
      wallet -0.01 ETH, +24.1965 USDG; 1 tx (execute ok)
    • forkdappTests: Swap USDG to ETH (passed=false)
      Show source
      No successful transaction was made for this goal (timeout).
    • forkdapp test: Swap ETH to USDG — transaction target and function
      Show source
      toRole=Uniswap Universal Router; function=execute(bytes,bytes[],uint256)
    • forkdapp test: Swap ETH to USDG — effects
      Show source
      wallet +24.1965 USDG ← 0x8876…0904 (Uniswap Universal Router)
    • forkdapp test: Swap ETH to USDG — observed
      Show source
      wallet -0.01 ETH, +24.1965 USDG; 1 tx (execute ok)

    Confirmed by: grok-4.7, gpt-5.6-sol, claude-opus-5.5

  • LowOwner-picked operator sets slippage on fee conversion swapsfeesAI

    Fees collected in ZHOOK are sold back into the pool, and buyback legs buy ZHOOK. Both happen in sweepPoolFees, which only the fee sweep operator may run when such a swap is needed. The owner sets this operator; it is currently 0xa101…cA83. The operator chooses the minimum-output limits. A careless or malicious operator could accept a poor price (for example in a sandwich), which would mostly cost fee recipients. Each internal swap's price movement is still capped by the pool's snapshotted maxInternalPriceImpactBps of 3%. These fee sells are a normal, ongoing source of selling pressure on ZHOOK.

    Evidence

    • codePonsV2MemeHook.sol:L500-L531
      Show source
      function sweepPoolFees(PoolId poolId, uint256 minConversionQuoteOut, uint256 minBuybackTokensOut)
              external
              nonReentrant
          {
              LaunchInfo memory info = launches[poolId];
              if (!info.registered) revert UnknownPool();
              bool isOperator = msg.sender == feeSweepOperator;
              if (!isOperator && msg.sender != info.creator) revert NotFeeSweepOperator();
              if (!isOperator && _requiresTrustedOperator(poolId, info)) revert InternalSwapRequiresOperator();
      
              (uint256 convertedFeeQuote, uint256 convertedTaxQuote, uint256 convertedBuybackQuote, bool converted) =
                  _convertPendingMemecoin(poolId, info, minConversionQuoteOut);
              // Only a conversion that actually executed is subject to the caller's
              // minimum. Enforcing it when there was nothing to convert, or when the
              // swap filled nothing and the pending amount was restored for a later
    • codePonsV2MemeHook.sol:L274-L278
      Show source
      function setFeeSweepOperator(address operator) external onlyOwner {
              if (operator == address(0)) revert ZeroAddress();
              feeSweepOperator = operator;
              emit FeeSweepOperatorUpdated(operator);
          }
    • codePonsV2MemeHook.sol:L766-L804
      Show source
      function _executeInternalSwap(PoolId poolId, SwapDirection direction, uint256 amountIn)
              private
              returns (uint256 amountInConsumed, uint256 amountOut)
          {
              bytes memory result = poolManager.unlock(abi.encode(poolId, direction, amountIn));
              (amountInConsumed, amountOut) = abi.decode(result, (uint256, uint256));
          }
      
          function unlockCallback(bytes calldata data) external returns (bytes memory) {
              if (msg.sender != address(poolManager)) revert NotPoolManager();
              (PoolId poolId, SwapDirection direction, uint256 amountIn) = abi.decode(data, (PoolId, SwapDirection, uint256));
      
              LaunchInfo memory info = launches[poolId];
              PoolKey memory key = _poolKeys[poolId];
              bool zeroForOne =
    • on-chainfeeSweepOperator = 0xa1018c1D9655292A2dE0F7dEa9a0F848EaA8cA83

    Confirmed by: claude-opus-5.5, gpt-5.6-sol

  • LowTeam posts contradict each other on shielded balance statusclaims-mismatchAI

    On 2 Nov the account said a zk-shielded ETH and USDG balance was live on mainnet. Docs still list Shielded balance as Pending, and the 4 Nov status post calls that same feature beta. Holders cannot tell from the team's own posts which privacy pieces actually work.

    Evidence

    Confirmed by: grok-4.7, gpt-5.6-sol

  • LowWebsite domain registered one day before token launchwebsiteAI

    The zerohook.trade domain was created on 2026-10-25, one day before the token was deployed on 2026-10-26. The Wayback Machine has no snapshots of it. This is a very new project with no track record.

    Evidence

    • on-chainsite.domainCreatedAt = 2026-10-25T06:18:55.000Z; contract.deployedAt = 2026-10-26T15:45:54.000Z; waybackSnapshots = []

    Confirmed by: claude-opus-5.5, grok-4.7, gpt-5.6-sol

Positive signals (5)

  • PositiveOngoing token burns verified on-chain: 8.0% of supply burnedburnDeterministic

    8.0% of the supply ever minted is burned, in 11 burn transfer(s), last 2026-11-04. Burned by: the deployer 0x80e7…7cdf (7.9%, 8 burns); holder 0x5d75…305e (0.02%, 3 burns). Burned tokens are gone for good, which reduces the supply over time.

    Evidence

    • on-chainTransfer events to 0x0 / 0x…dEaD and balanceOf(burn addresses) of 0x4a4fc33a4bf80d7bab0e1bab6d82af1e2942e917

    Confirmed by: facts

  • PositiveFixed-supply token with no owner, mint, pause or blacklistotherAI

    ZHOOK is the standard PonsV2LauncherToken: OpenZeppelin ERC20 plus a burn function holders can only use on their own tokens (or tokens they were approved to spend). The whole supply was minted once, to the bonding curve, in the constructor. There is no owner, no further mint, no blacklist, no pause and no transfer fee. The stored 'deployer' address is metadata only and gives no control. Slither found no issues.

    Evidence

    • codePonsV2LauncherToken.sol:L44-L71
      Show source
      constructor(
              string memory name_,
              string memory symbol_,
              string memory logo_,
              string memory description_,
              Socials memory socials_,
              address deployer_,
              address curve_,
              address launchFactory_,
              uint256 supply_
          ) ERC20(name_, symbol_) {
              if (deployer_ == address(0) || curve_ == address(0) || launchFactory_ == address(0)) {
                  revert ZeroAddress();
              }
    • codePonsV2LauncherToken.sol:L7-L20
      Show source
      /**
       * @title PonsV2LauncherToken
       * @notice Fixed-supply ERC-20 deployed by PonsV2LaunchFactory for a v2 launch.
       * The entire supply mints directly to the token's bonding curve instead of a
       * Uniswap position. Anyone, the deployer included, may buy any amount from
       * the curve at any time; the curve's own price impact and its reserved pool
       * allocation are the only limits on a large buy. `deployer` is carried here
       * as immutable reference data for off-chain attribution only, and confers no
       * privileges over the token.
       * `ERC20Burnable` lets any holder voluntarily burn their own balance; the
       * protocol's buyback mechanism does not use it, bought-back tokens are
       * locked into `PonsV2BuybackVault` for a five-year vest instead of being
       * burned.
       */
    • codeERC20Burnable.sol:L20-L38
      Show source
      function burn(uint256 value) public virtual {
              _burn(_msgSender(), value);
          }
      
          /**
           * @dev Destroys a `value` amount of tokens from `account`, deducting from
           * the caller's allowance.
           *
           * See {ERC20-_burn} and {ERC20-allowance}.
           *
           * Requirements:
           *
           * - the caller must have allowance for ``accounts``'s tokens of at least
           * `value`.
           */
    • on-chaincontract.privileges = [] ; static.issues = []

    Confirmed by: claude-opus-5.5, grok-4.7, gpt-5.6-sol

  • PositiveFork test: buys and sells work with 0% token taxhoneypotAI

    A fork simulation bought and sold on the graduated Uniswap v4 pool. Both trades returned exactly the expected amounts. A second wallet that received tokens by transfer could also sell, and selling still worked one hour later. Token-level buy, sell and transfer tax were all 0%. No honeypot behaviour was seen.

    Evidence

    • forksimulation: canBuy=true, canSell=true, buyTaxPct=0, sellTaxPct=0, transferTaxPct=0
      Show source
      second wallet (received via transfer) could sell
    • forksimulation notes
      Show source
      sell after +1h: ok

    Confirmed by: claude-opus-5.5, grok-4.7, gpt-5.6-sol

  • PositiveMain pool liquidity is 100% held by the Pons LP lockerliquidityAI

    The main ZHOOK/ETH v4 pool (about $13.4k liquidity) is reported 100% locked, with 0% held by the deployer. The Pons locker also holds 8.16% of the token supply. The locker's function table shows only lock functions, callable by the factory, and no withdraw function. The locker source was omitted, so unlock terms cannot be fully confirmed.

    Evidence

    • on-chainliquidity pool 0x3bc3b16c1c4bce9379e9e5334c4d4a4d586ee8a85d655ff64e08912dedb51f30: lpLockedPct=100, lpHeldByDeployerPct=0
    • staticLP-locker fns: lockPosition(address,uint256) [factory], lockTokenSupply(address,uint256) [factory], setFactory(address) [owner]

    Confirmed by: claude-opus-5.5, grok-4.7, gpt-5.6-sol

  • PositiveDeployer holds no tokens and sold almost nothingholdersAI

    The deployer wallet holds 0% now. It made 8 burns totalling 7.9478% of supply and sold only 0.0012%. The creator-declared insider wallet is the deployer itself, holding 0.0046%. Outside infrastructure, the largest holder has 2.93% and the top 10 hold 18.64%, a fairly spread distribution.

    Evidence

    • on-chaintoken.burns.by deployer 0x80e7a9cbbded990e481fb8bbcf971133bf217cdf pct=7.9478 count=8
    • on-chainDeployer 0x80e7a9cbbded990e481fb8bbcf971133bf217cdf holds 0% now; deployerSoldPct=0.0012; top10Pct=18.6426

    Confirmed by: claude-opus-5.5, grok-4.7 · Disputed by: gpt-5.6-sol

Notes (3)

  • LowPool takes a 3% fee per trade, frozen for this poolfeesAI

    The graduated pool uses the PonsV2MemeHook. Its afterSwap callback takes the pool's hook fee plus a creator tax out of every swap; facts show 1% hook fee plus 2% creator tax. The simulation reports 0% because it counts this pool fee inside the quotes, not as a token tax. The fee rates are copied into the pool's record when the pool is registered, and afterSwap reads only that record. So the hook owner's setHookFeeBps cannot raise the fee on this pool. Registration also capped hook fee plus creator tax at 20%. The hook can only take an amount from swaps (afterSwapReturnDelta); it has no beforeSwap permission, so it cannot block buys or sells.

    Evidence

    • codePonsV2MemeHook.sol:L444-L485
      Show source
      function _afterSwap(address, PoolKey calldata key, SwapParams calldata params, BalanceDelta delta, bytes calldata)
              internal
              override
              returns (bytes4, int128)
          {
              // The conversion and buyback legs swap against this same pool, but
              // they are never taxed here: v4-core skips a pool's hooks when the
              // hook itself is the caller (Hooks.afterSwap). Were that not so, the
              // skim would come out of the buyback before it reached the vault.
              PoolId poolId = key.toId();
              LaunchInfo memory info = launches[poolId];
              if (!info.registered) return (IHooks.afterSwap.selector, 0);
              if (info.hookFeeBps == 0 && info.creatorTaxBps == 0) return (IHooks.afterSwap.selector, 0);
      
              bool specifiedIsCurrency0 = (params.amountSpecified < 0) == params.zeroForOne;
    • codePonsV2MemeHook.sol:L337-L378
      Show source
      // Terms frozen here govern the pool for life, so each is held to the
              // same ceiling as the setter that produced it. protocolFeeShareBps
              // against BASIS_POINTS rather than MAX_PROTOCOL_FEE_SHARE_BPS would
              // let a pool be registered on terms the live policy could never
              // reach, paying the creator nothing.
              if (
                  policy.protocolFeeRecipient == address(0) || policy.protocolFeeShareBps > MAX_PROTOCOL_FEE_SHARE_BPS
                      || policy.buybackBurnBps > BASIS_POINTS || policy.hookFeeBps > MAX_HOOK_FEE_BPS
                      || policy.maxInternalPriceImpactBps == 0 || policy.maxInternalPriceImpactBps >= BASIS_POINTS
              ) {
                  revert InvalidBps();
              }
              // The curve bounds the same sum in its own constructor rather than
              // inheriting it from the factory. A pool taking more than the whole
              // unspecified leg would flip the swapper's output delta negative.
    • codePonsV2MemeHook.sol:L184-L201
      Show source
      function getHookPermissions() public pure override returns (Hooks.Permissions memory) {
              return Hooks.Permissions({
                  beforeInitialize: true,
                  afterInitialize: false,
                  beforeAddLiquidity: false,
                  afterAddLiquidity: false,
                  beforeRemoveLiquidity: false,
                  afterRemoveLiquidity: false,
                  beforeSwap: false,
                  afterSwap: true,
                  beforeDonate: false,
                  afterDonate: false,
                  beforeSwapReturnDelta: false,
                  afterSwapReturnDelta: true,
                  afterAddLiquidityReturnDelta: false,
    • on-chainlaunchpad.fees
      Show source
      protocol fee 1%; creator tax 2%

    Confirmed by: claude-opus-5.5, gpt-5.6-sol

  • InfoTeam openly discloses that no audit has been donewebsiteAI

    Docs, the principles page and the token page all say no audit has been done and that they will not claim one until it is published. That is a disclosed gap in the trading app's contracts, not a hidden claim. It does not by itself show the $ZHOOK token can be drained.

    Evidence

    Confirmed by: grok-4.7, gpt-5.6-sol

  • InfoScanner bot flagged marketing running ahead of the appsocialAI

    An automated scanner said private mode was marked soon in the app and that the site's private-by-default wording ran ahead of what it could test. It said it did not check the coin. Our comparison of the site, docs and the team's status post agrees with the wording gap. It is not independent proof of a rug.

    Evidence

    • Show source
      NARRATIVE: PARTLY REAL 35 · COIN: NOT CHECKED A real swap app exists, but private mode is marked 'soon' in the app itself. ... Site wording ahead of the product ... This checked the story only, NOT a coin.

    Confirmed by: grok-4.7, gpt-5.6-sol

Score breakdown

Higher is safer. The overall is the weighted average of the assessed parts, then capped by hard facts.

  • Contract

    weight 45%
    60
    Capped · max 60

    dApp asks for an unlimited token approval to an unreviewed spender → max 60

    The token itself is a clean, fixed-supply template with working 0%-tax trades, but the dApp's unlimited approval request caps this score, and protocol-level owner powers remain.

    Why this score

    Raised the score

    • Verified fixed-supply Pons template with no owner, mint, pause or blacklist
    • Buy, sell, transfer-then-sell and delayed sell all pass at 0% token tax
    • Pool fee rates frozen at 1% hook fee plus 2% creator tax
    • Slither found no issues

    Lowered the score

    • dApp requests an unlimited USDG approval (Permit2)
    • One protocol owner controls the hook, factory, buyback vault and LP locker
    • Factory rescue functions and locker source were not reviewed
    • Fee sweep operator sets slippage on fee swaps
  • Token

    weight 30%
    50

    Liquidity is locked and the deployer holds nothing and burned about 8%, but same-block bundles captured a large share of supply right at launch.

    Why this score

    Raised the score

    • Graduated pool liquidity 100% held by the Pons LP locker
    • Deployer holds 0%, sold almost nothing and burned about 7.9%
    • Ongoing burns verified on-chain
    • Current holders fairly spread; top 10 hold about 18.6%

    Lowered the score

    • Bundles bought roughly 21%, 12% and 9% of supply in the first blocks
    • One wallet appears in five launch bundles
    • Sniper checks paused, so remaining bundle holdings are not fully measured
    • Small pool liquidity of about $13.4k
  • Social / X

    weight 15%
    45

    The X account is brand new and its posts are inconsistent about which privacy features are actually live, though there are no confirmed third-party scam calls.

    Why this score

    Raised the score

    • No third-party rug or honeypot calls naming this token
    • Team openly states no audit has happened

    Lowered the score

    • X account created on the same day as the token
    • Posts disagree on whether the shielded balance is live or in beta
    • Scanner bot noted marketing ahead of the product, which matches our facts
  • Website

    weight 10%
    38

    The site presents private-by-default trading as current, but the dApp test showed a plain public swap and the project's own docs mark key privacy features as pending.

    Why this score

    Raised the score

    • Working swap dApp, docs, terms and risk disclosure pages
    • No-audit status disclosed in writing

    Lowered the score

    • Claim of stealth-wallet private trading contradicted by the dApp test
    • Docs mark the shielded balance as pending while the site calls it the default
    • Domain registered one day before launch with no archive history