Skip to content

fix(widget): fire ON_BEFORE_APPROVAL widget hook before permit signing#7697

Open
tenderdeve wants to merge 10 commits into
cowprotocol:developfrom
tenderdeve:fix/7685-widget-on-before-approval
Open

fix(widget): fire ON_BEFORE_APPROVAL widget hook before permit signing#7697
tenderdeve wants to merge 10 commits into
cowprotocol:developfrom
tenderdeve:fix/7685-widget-on-before-approval

Conversation

@tenderdeve

@tenderdeve tenderdeve commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #7685.

When a permittable token is selected in a widget that has the `onBeforeApproval` hook configured, the widget integrator never sees the hook fire. Instead, the user is immediately asked to sign the EIP-2612 permit and no pre-approval action is dispatched.

Root cause

`ON_BEFORE_APPROVAL` is only fired from the on-chain ERC-20 approval path (`useApproveCurrency`). For permittable tokens, CowSwap signs an EIP-2612 permit instead of performing an on-chain approval, so the hook path is bypassed entirely — even though, from an integrator's perspective, the permit signature is the user's "approval" of token spending.

Fix

Fire `ON_BEFORE_APPROVAL` in both the swap and limit order trade flows right before requesting the permit signature, mirroring the payload shape used by `useApproveCurrency`:

```ts
{ chainId, sellToken, sellAmount, walletAddress, spenderAddress }
```

The hook is skipped when a cached permit is reused, matching the existing permit request UI step's behaviour. If the integrator's hook returns `false`, the flow aborts cleanly:

  • Swap flow — `swapFlow` returns `false`, the same pattern used when the user declines a price impact warning. No permit signature is requested.
  • Limit order flow — `tradeFlow` throws a new `WidgetHookDeclineError`, which is swallowed by `useHandleOrderPlacement` and dismisses the trade confirmation modal.

No other flows are affected (TWAP does not use permit signatures).

Test plan

  • Open the widget configurator
  • Connect a wallet
  • Enable the `on_before_approval` hook in the widget panel
  • Pick a permittable, not-approved sell token
  • Press "approve and swap"
  • Verify the `onBeforeApproval` handler is called before the permit signature is requested
  • Returning `false` from the handler aborts the flow without prompting the wallet
  • Returning `true` proceeds to the normal permit signature step
  • Repeat the above on the limit order page
  • Regression: tokens that require on-chain approval (USDT) still fire `ON_BEFORE_APPROVAL` exactly once, via the existing `useApproveCurrency` path

Summary by CodeRabbit

  • New Features

    • Added widget-hook gating for permit signing in swap and limit-order flows when no cached permit is available.
    • Integrated widget-hook approval into permit generation-in-advance for ERC-20 approvals.
  • Bug Fixes

    • Improved handling of widget-hook declines to exit cleanly and avoid duplicate error handling.
    • Prevented widget-hook declines from triggering generic swap error analytics/telemetry.

For permittable tokens, CowSwap signs an EIP-2612 permit instead of
performing an on-chain ERC-20 approval. The ON_BEFORE_APPROVAL widget
hook, however, was only fired from the on-chain approval path
(useApproveCurrency), so widget integrators that subscribed to
onBeforeApproval never saw the event when the user was about to
sign a permit. From the integrator's perspective the user authorized
spending without their pre-approval handler ever running.

Fire ON_BEFORE_APPROVAL in the swap and limit order trade flows
right before requesting the permit signature, mirroring the payload
shape used by useApproveCurrency (chainId, sellToken, sellAmount,
walletAddress, spenderAddress). The hook is skipped when a cached
permit is reused, matching the behaviour of the existing permit
request UI step. If the integrator's hook returns false, the
relevant flow aborts cleanly without dispatching a permit request:

- swap flow returns false, just like a declined price impact;
- limit order flow throws a new WidgetHookDeclineError which is
  swallowed by useHandleOrderPlacement and only dismisses the
  trade confirmation modal.

Closes cowprotocol#7685
@vercel

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown

@tenderdeve is attempting to deploy a commit to the cow-dev Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Introduces WidgetHookDeclineError and gates permit signing with callWidgetHook(ON_BEFORE_APPROVAL) in limitOrders/tradeFlow, swapFlow, and useGeneratePermitInAdvanceToTrade. When no cached permit exists, the widget hook is called; a decline throws the new error or returns false. useHandleOrderPlacement catches the error and dismisses the confirm dialog.

Changes

Widget hook approval gating for permit signing

Layer / File(s) Summary
WidgetHookDeclineError type definition
apps/cowswap-frontend/src/modules/limitOrders/services/types.ts
Adds WidgetHookDeclineError extends Error as an exported class, placed alongside the existing PriceImpactDeclineError.
Widget hook gating in limitOrders tradeFlow
apps/cowswap-frontend/src/modules/limitOrders/services/tradeFlow/index.ts
Gates beforePermit() behind callWidgetHook(ON_BEFORE_APPROVAL) when no cached permit exists; throws WidgetHookDeclineError if declined and rethrows it early in the outer error handler to bypass generic swap-error analytics. Imports and eslint comment updated accordingly.
Widget hook gating in swapFlow
apps/cowswap-frontend/src/modules/tradeFlow/services/swapFlow/index.ts
Adds callWidgetHook(ON_BEFORE_APPROVAL) gating using COW_PROTOCOL_VAULT_RELAYER_ADDRESS[chainId] as spender before requesting permit signature; returns false if the hook is not passed.
Widget hook gating in advance-permit generation
apps/cowswap-frontend/src/modules/erc20Approve/hooks/useGeneratePermitInAdvanceToTrade.ts
Derives tradeSpenderAddress via useTradeSpenderAddress and calls callWidgetHook(ON_BEFORE_APPROVAL) before generating the permit; returns false early if the hook fails. Precomputes amountRaw and adds tradeSpenderAddress to the useCallback dependency array.
WidgetHookDeclineError handling in useHandleOrderPlacement
apps/cowswap-frontend/src/modules/limitOrders/hooks/useHandleOrderPlacement.ts
Imports WidgetHookDeclineError and adds a dedicated .catch branch that calls tradeConfirmActions.onDismiss() and returns early, preventing the error from reaching OperatorError or generic onError logic.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant UI as OrderPlacement UI
  participant TradeFlow as Limit Orders / Swap Flow
  participant Widget as Widget Hook
  participant Wallet

  User->>UI: Initiate order/swap
  UI->>TradeFlow: Start trade flow
  TradeFlow->>TradeFlow: Check cached permit
  alt No cached permit
    TradeFlow->>Widget: callWidgetHook(ON_BEFORE_APPROVAL)
    alt Widget hook approved
      Widget-->>TradeFlow: Permission granted
      TradeFlow->>Wallet: Request permit signature
      Wallet-->>TradeFlow: Signed
    else Widget hook declined
      Widget-->>TradeFlow: Declined
      TradeFlow-->>UI: WidgetHookDeclineError
      UI->>User: Dismiss confirm dialog
    end
  else Cached permit exists
    TradeFlow->>TradeFlow: Proceed to beforePermit
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • cowprotocol/cowswap#7557: Ensures COW_PROTOCOL_VAULT_RELAYER_ADDRESS is correctly imported from @cowprotocol/common-utils, which this PR uses as the spender address in widget-hook gated permit signing.
  • cowprotocol/cowswap#7570: Modifies useHandleOrderPlacement.ts to adjust widget-hook payload; this PR adds error handling for WidgetHookDeclineError in the same file.
  • cowprotocol/cowswap#7662: Modifies the same limitOrders/services/tradeFlow/index.ts permit-signing path, specifically around the permit amount used in handlePermit.

Suggested labels

Security

Suggested reviewers

  • kernelwhisperer
  • elena-zh
  • Danziger
  • limitofzero

🐰 A hook before approval, the widget must say yes,
Or the permit gets no signing — the rabbit knows best!
WidgetHookDeclineError hops in to dismiss,
No telemetry fires for a polite little "miss." ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: firing the ON_BEFORE_APPROVAL widget hook before permit signing.
Description check ✅ Passed The description is comprehensive with summary, root cause analysis, fix explanation, test plan, and regression considerations matching the template structure.
Linked Issues check ✅ Passed The PR addresses all requirements from issue #7685: the ON_BEFORE_APPROVAL hook now fires before permit signature requests with the correct payload shape, supporting both swap and limit order flows.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing the ON_BEFORE_APPROVAL hook gate for permit signatures in swap and limit order flows, directly addressing issue #7685.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/cowswap-frontend/src/modules/limitOrders/services/tradeFlow/index.ts`:
- Around line 102-103: The WidgetHookDeclineError thrown at the throw statement
is an expected abort path that should not be treated as a generic swap error in
error analytics. Locate the catch block that handles exceptions from the code
path containing the WidgetHookDeclineError throw statement, and add a specific
check to detect if the caught error is an instance of WidgetHookDeclineError.
When this error type is caught, handle it separately by either skipping the
generic error capture/analytics logic or routing it through a non-error
telemetry path, ensuring that expected widget-hook declines do not create
analytics noise in the swap error reporting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 565e6df6-e142-4427-a042-ddee973a2c43

📥 Commits

Reviewing files that changed from the base of the PR and between 8942c59 and 1567101.

📒 Files selected for processing (4)
  • apps/cowswap-frontend/src/modules/limitOrders/hooks/useHandleOrderPlacement.ts
  • apps/cowswap-frontend/src/modules/limitOrders/services/tradeFlow/index.ts
  • apps/cowswap-frontend/src/modules/limitOrders/services/types.ts
  • apps/cowswap-frontend/src/modules/tradeFlow/services/swapFlow/index.ts

Comment on lines +102 to +103
if (!isWidgetHookPassed) throw new WidgetHookDeclineError()
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Do not report widget-hook declines as swap errors.

At Line 102, WidgetHookDeclineError is an expected abort path, but it currently goes through generic error capture/analytics in the catch block, which will create telemetry noise.

Suggested fix
   } catch (err: unknown) {
     const error = normalizeError(err)
+    if (error instanceof WidgetHookDeclineError) {
+      throw error
+    }
 
     logTradeFlow('LIMIT ORDER FLOW', 'STEP 9: ERROR: ', error)
     const swapErrorMessage = getSwapErrorMessage(error)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/cowswap-frontend/src/modules/limitOrders/services/tradeFlow/index.ts`
around lines 102 - 103, The WidgetHookDeclineError thrown at the throw statement
is an expected abort path that should not be treated as a generic swap error in
error analytics. Locate the catch block that handles exceptions from the code
path containing the WidgetHookDeclineError throw statement, and add a specific
check to detect if the caught error is an instance of WidgetHookDeclineError.
When this error type is caught, handle it separately by either skipping the
generic error capture/analytics logic or routing it through a non-error
telemetry path, ensuring that expected widget-hook declines do not create
analytics noise in the swap error reporting.

@elena-zh elena-zh added the trigger-preview Add to a fork PR to trigger CF-pages preview. See https://github.com/cowprotocol/cowswap/pull/7615 label Jun 22, 2026
@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Cloudflare Pages preview mirror

Preview branch URL: https://github.com/cowprotocol/cowswap/tree/cf-preview/pr-7697
Mirror PR: #7699
Cloudflare Pages preview links will be posted on the mirror PR by the Cloudflare Pages GitHub integration once builds complete.

Source fork branch: tenderdeve/cowswap:fix/7685-widget-on-before-approval
Approval target SHA: c81179d5837a
Last mirrored SHA: 40d5d5f5a014
Last comment update: @elena-zh at 2026-07-07T09:12:35.284Z

  • Sync Cloudflare preview to approval target commit

Treat the widget-hook decline as an expected abort path rather than a
generic swap error: re-throw before the catch block routes it through
captureError and analytics, so declined ON_BEFORE_APPROVAL hooks no
longer pollute error telemetry.

Addresses @coderabbitai's feedback on cowprotocol#7697.
@tenderdeve

Copy link
Copy Markdown
Contributor Author

@coderabbitai updated in f9d6050 — re-throw WidgetHookDeclineError from the catch block before captureError/analytics.error run, so widget-hook declines no longer create swap-error telemetry noise.

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the commit f9d605085 to verify the re-throw of WidgetHookDeclineError
git show f9d605085 --stat
git show f9d605085

Length of output: 2213



@tenderdeve: Confirmed — the guard clause in f9d605085 is exactly right. Re-throwing WidgetHookDeclineError before logTradeFlow / getSwapErrorMessage / captureError ensures the decline is treated as an expected abort path and stays completely out of swap-error telemetry. Clean fix. 🐇 ✨


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@elena-zh elena-zh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @tenderdeve, thank you for the fix.
It is working on Limit orders page while is not working on Swap page.
Could you please fix it?

The previous fix only wired ON_BEFORE_APPROVAL into the permit-signing
paths (limit orders + swap permit flow). On the Swap page with a
non-permittable token, the approval still goes through
`useTradeApproveCallback` -> `approveCallback`, which never fired the
hook. Result: the widget's onBeforeApproval listener never ran on the
Swap page in that scenario.

Call the hook in `useTradeApproveCallback` right before the ERC20
`approve` transaction. If the host widget declines, reset the approve
progress modal and bail out without sending the tx, matching the
behaviour of the other hook call sites.

Addresses @elena-zh's review on cowprotocol#7697.
@tenderdeve

Copy link
Copy Markdown
Contributor Author

@elena-zh updated in 97b1ab5 — wired ON_BEFORE_APPROVAL into useTradeApproveCallback so the hook also fires on the Swap page when a regular ERC20 approve tx is required (non-permittable token). If the host widget declines, the approve flow is dismissed before sending the tx.

@elena-zh elena-zh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still not fixed

Image

On the Swap page, when the user clicks Approve for a permittable token,
the trade form pre-signs an EIP-2612 permit via
`useGeneratePermitInAdvanceToTrade`. That path skipped the
`ON_BEFORE_APPROVAL` widget hook, so the host widget's `onBeforeApproval`
listener never ran on Swap with permittable tokens (it worked on Limit
Orders because the permit is signed inside the limit-order `tradeFlow`,
which already calls the hook).

Call the hook in `useGeneratePermitInAdvanceToTrade` right before
`generatePermit`. If the host widget declines, bail out without signing,
matching the behaviour of the other hook call sites.

Also drop the speculative hook call I added to `useTradeApproveCallback`
in 97b1ab5: `useApproveCurrency` (the only path that consumes
`useTradeApproveCallback` for the Swap form) already fires the hook,
so the extra call would double-prompt.

Addresses @elena-zh's follow-up review on cowprotocol#7697.
@tenderdeve

Copy link
Copy Markdown
Contributor Author

@elena-zh updated in 6653bb1 — root cause was the Swap page's pre-sign permit path (useGeneratePermitInAdvanceToTrade), which never fired the hook. Permit-signing in advance now calls ON_BEFORE_APPROVAL and bails out cleanly if the host widget declines. Also dropped the earlier duplicate hook call in useTradeApproveCallback since useApproveCurrency already covers the non-permit on-chain approve path.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/cowswap-frontend/src/modules/erc20Approve/hooks/useGeneratePermitInAdvanceToTrade.ts`:
- Around line 30-45: The ON_BEFORE_APPROVAL hook invocation in the conditional
block for tradeSpenderAddress bypasses the pre-approval gate when
tradeSpenderAddress is falsy, allowing the function to proceed directly to
generatePermit without gating. Move the callWidgetHook invocation for
WidgetHookEvents.ON_BEFORE_APPROVAL outside the if (tradeSpenderAddress)
conditional check so the hook is always invoked before any permit generation
logic, ensure the early return if (!isWidgetHookPassed) return false is always
evaluated regardless of tradeSpenderAddress availability, and adjust the hook
payload to handle cases where tradeSpenderAddress might be undefined while still
maintaining the necessary validation gate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0b334a9f-34e5-4923-a5b2-7592697c9349

📥 Commits

Reviewing files that changed from the base of the PR and between 97b1ab5 and 6653bb1.

📒 Files selected for processing (1)
  • apps/cowswap-frontend/src/modules/erc20Approve/hooks/useGeneratePermitInAdvanceToTrade.ts

If \`tradeSpenderAddress\` was unavailable, the previous version skipped
the \`ON_BEFORE_APPROVAL\` widget hook but still called \`generatePermit\`,
letting a permit be signed without the pre-approval gate. Treat a
missing spender as a hard precondition (same as missing \`account\` /
\`permitInfo\`) so the hook is always evaluated before any permit
signature.

Addresses @coderabbitai's review on cowprotocol#7697.
@tenderdeve

Copy link
Copy Markdown
Contributor Author

@coderabbitai addressed in this push — tradeSpenderAddress is now part of the precondition guard, so the permit can never be signed without going through ON_BEFORE_APPROVAL.

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
cat apps/cowswap-frontend/src/modules/erc20Approve/hooks/useGeneratePermitInAdvanceToTrade.ts

Length of output: 3057



@tenderdeve: Verified in the current branch — the guard at Line 27 (if (!account || !permitInfo || !tradeSpenderAddress) return false) makes tradeSpenderAddress a hard prerequisite, and callWidgetHook(ON_BEFORE_APPROVAL, { ..., spenderAddress: tradeSpenderAddress }) is called unconditionally before generatePermit. There is no code path that can reach permit signing without the hook having been invoked first. Clean and airtight. 🐇 ✅

@elena-zh elena-zh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM now, thank you

@elena-zh elena-zh requested a review from kernelwhisperer June 23, 2026 15:46
@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
swap-dev Ready Ready Preview Jul 7, 2026 9:15am
widget-configurator Ready Ready Preview Jul 7, 2026 9:15am

Request Review

@tenderdeve

Copy link
Copy Markdown
Contributor Author

@coderabbitai this one is already handled — the limit-order flow's catch block re-throws WidgetHookDeclineError before getSwapErrorMessage/captureError/analytics.error (index.ts lines 229-232), so widget-hook declines never reach the generic swap-error telemetry. No change needed.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@tenderdeve Understood, thanks for confirming. That matches what I verified earlier in this thread — the re-throw of WidgetHookDeclineError ahead of getSwapErrorMessage/captureError/analytics.error in index.ts keeps widget-hook declines out of the swap-error telemetry path. No further action needed on my end here. 🐇

@fairlighteth fairlighteth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ AI Review (Codex GPT-5, worked 17m): cached permits still trigger the approval hook

Finding: [BLOCKING] Skip ON_BEFORE_APPROVAL when reusing a cached permit

  • Location: useGeneratePermitInAdvanceToTrade.ts:31, limitOrders/services/tradeFlow/index.ts:86
  • This one is important: the PR says cached permits skip the hook, but generated permits are cached by chain, token, spender, account, and amount.
  • Limit orders call getCachedPermit(sellToken.address) without permitAmountToSign, so an amount-keyed cached permit is missed.
  • The advance-permit flow calls the hook before generatePermit, whose internal cache lookup happens afterward.
  • Consequently, Swap and Limit flows can ask the integrator for approval again and abort when it returns false, even though no permit signature is needed.
  • Related work: #7838, stacked on the permit-cache changes in #7837, implements the same permit-in-advance gate through a shared helper. Its current implementation also invokes the hook before generatePermit checks the cache, so it does not address this cached-reuse case.

Suggested fix

  • Coordinate with #7838 and make the shared approval gate cache-aware, or invoke it immediately after the permit generator confirms a cache miss.
  • Pass the same token, amount, and spender used by permit generation when checking the limit-order cache.
  • Add regression tests proving cached permits skip the hook, while an uncached decline prevents permit signing in both flows.
  • Avoid merging two divergent implementations; port only #7697’s unique limit-order and lower-level swapFlow coverage into the shared approach if those paths require it.
Review scope and related context
  • Of the current open PRs, only #7838 overlaps a real source file with #7697; it changes useGeneratePermitInAdvanceToTrade.ts. The other four files changed by #7697 remain unique. #7699 is only its preview mirror.
  • The unresolved CodeRabbit telemetry thread is stale: current code rethrows WidgetHookDeclineError before error capture and analytics.
  • The resolved missing-spender finding is fixed by the guard in useGeneratePermitInAdvanceToTrade.
  • Unit tests, lint, and typecheck passed in CI. Cypress did not execute its scenarios because INTEGRATION_TEST_PRIVATE_KEY was missing.
  • Security review incomplete: DeepSec PR mode was attempted against the exact five changed files but exited before analysis because deepsec@2.1.2 depends on unpublished @aws-sdk/token-providers@3.1083.0; no comment artifact was produced.
🤖 Prompt for AI agents
Verify this finding against current code and the stacked implementation in PRs #7837/#7838.

Context:
- Generated permits are cached using token, spender, account, and amount.
- Limit-order code checks the cache without permitAmountToSign.
- Both #7697 and #7838 call ON_BEFORE_APPROVAL before generatePermit performs its cache lookup.
- Cached permits must bypass ON_BEFORE_APPROVAL; uncached permits must still call it before signing.
- Prefer one shared implementation and add focused cached/uncached/declined tests.

Generated using the pr-review skill from the CoW Protocol skills repo.

@elena-zh

Copy link
Copy Markdown
Contributor

Hey @tenderdeve , could you please resolve conflicts in the branch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Widget: on_before_approval hook does not appear before permit signing

4 participants