From 28c60bda7b8817ff7156e9e24f253f57da427b36 Mon Sep 17 00:00:00 2001
From: Alexandr Kazachenko <shoom3301@gmail.com>
Date: Fri, 29 Mar 2024 14:00:41 +0500
Subject: [PATCH 1/2] fix(limit-orders): use ff for zero balance orders (#4117)

---
 .../containers/LimitOrdersWidget/index.tsx    |  5 ++-
 .../TradeWidget/TradeWidgetForm.tsx           | 40 ++++++++++---------
 .../trade/pure/UnlockWidgetScreen/index.tsx   | 23 +++++++----
 .../hooks/useTradeFormValidationContext.ts    |  4 +-
 4 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/index.tsx b/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/index.tsx
index 3f86479988..b89538ef5d 100644
--- a/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/index.tsx
+++ b/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/index.tsx
@@ -31,14 +31,15 @@ import { LimitOrdersConfirmModal } from '../LimitOrdersConfirmModal'
 import { RateInput } from '../RateInput'
 import { SettingsWidget } from '../SettingsWidget'
 
-export const LIMIT_BULLET_LIST_CONTENT: BulletListItem[] = [
+const LIMIT_BULLET_LIST_CONTENT: BulletListItem[] = [
   { content: 'Set any limit price and time horizon' },
   { content: 'FREE order placement and cancellation' },
   { content: 'Place multiple orders using the same balance' },
   { content: 'Receive surplus of your order' },
   { content: 'Protection from MEV by default' },
   {
-    content: <span>Place orders for higher than available balance!</span>,
+    featureFlag: 'isZeroBalanceOrdersEnabled',
+    content: 'Place orders for higher than available balance!',
   },
 ]
 
diff --git a/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx b/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx
index c1757ca25f..c17bd6a9a9 100644
--- a/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx
+++ b/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx
@@ -22,6 +22,7 @@ import { wasImFeelingLuckyClickedAtom } from 'modules/swap/hooks/useImFeelingLuc
 import { useOpenTokenSelectWidget } from 'modules/tokensList'
 import { useIsAlternativeOrderModalVisible } from 'modules/trade/state/alternativeOrder'
 
+import { FeatureGuard } from 'common/containers/FeatureGuard'
 import { useCategorizeRecentActivity } from 'common/hooks/useCategorizeRecentActivity'
 import { useIsProviderNetworkUnsupported } from 'common/hooks/useIsProviderNetworkUnsupported'
 import { useThrottleFn } from 'common/hooks/useThrottleFn'
@@ -107,7 +108,6 @@ export function TradeWidgetForm(props: TradeWidgetProps) {
 
   const showDropdown = shouldShowMyOrdersButton || isInjectedWidgetMode
 
-
   const currencyInputCommonProps = {
     isChainIdUnsupported,
     chainId,
@@ -172,24 +172,26 @@ export function TradeWidgetForm(props: TradeWidgetProps) {
                 {...currencyInputCommonProps}
               />
 
-              {isLimitOrderMode &&
-                !isWrapOrUnwrap &&
-                ClosableBanner(ZERO_BANNER_STORAGE_KEY, (onClose) => (
-                  <InlineBanner
-                    bannerType="success"
-                    orientation={BannerOrientation.Horizontal}
-                    customIcon={ICON_TOKENS}
-                    iconSize={32}
-                    margin={'10px 0 0'}
-                    onClose={onClose}
-                  >
-                    <p>
-                      <b>NEW: </b>You can now place limit orders for amounts larger than your wallet balance. Partial
-                      fill orders will execute until you run out of sell tokens. Fill-or-kill orders will become active
-                      once you top up your balance.
-                    </p>
-                  </InlineBanner>
-                ))}
+              <FeatureGuard featureFlag="isZeroBalanceOrdersEnabled">
+                {isLimitOrderMode &&
+                  !isWrapOrUnwrap &&
+                  ClosableBanner(ZERO_BANNER_STORAGE_KEY, (onClose) => (
+                    <InlineBanner
+                      bannerType="success"
+                      orientation={BannerOrientation.Horizontal}
+                      customIcon={ICON_TOKENS}
+                      iconSize={32}
+                      margin={'10px 0 0'}
+                      onClose={onClose}
+                    >
+                      <p>
+                        <b>NEW: </b>You can now place limit orders for amounts larger than your wallet balance. Partial
+                        fill orders will execute until you run out of sell tokens. Fill-or-kill orders will become
+                        active once you top up your balance.
+                      </p>
+                    </InlineBanner>
+                  ))}
+              </FeatureGuard>
             </div>
             {!isWrapOrUnwrap && middleContent}
             {!hideBuyTokenInput && (
diff --git a/apps/cowswap-frontend/src/modules/trade/pure/UnlockWidgetScreen/index.tsx b/apps/cowswap-frontend/src/modules/trade/pure/UnlockWidgetScreen/index.tsx
index 8c4c0ad37c..58558e07c1 100644
--- a/apps/cowswap-frontend/src/modules/trade/pure/UnlockWidgetScreen/index.tsx
+++ b/apps/cowswap-frontend/src/modules/trade/pure/UnlockWidgetScreen/index.tsx
@@ -5,11 +5,14 @@ import { ExternalLink } from '@cowprotocol/ui'
 
 import SVG from 'react-inlinesvg'
 
+import { FeatureGuard } from 'common/containers/FeatureGuard'
+
 import * as styledEl from './styled'
 
 export type BulletListItem = {
   content: string | React.ReactNode
   isNew?: boolean
+  featureFlag?: string
 }
 
 type UnlockWidgetProps = {
@@ -42,14 +45,18 @@ export function UnlockWidgetScreen({
 
       {items && (
         <styledEl.List>
-          {items.map(({ isNew, content }, index) => (
-            <li key={index} data-is-new={isNew || null}>
-              <span>
-                <SVG src={iconCompleted} />
-              </span>{' '}
-              {content}
-            </li>
-          ))}
+          {items.map(({ isNew, content, featureFlag }, index) => {
+            const item = (
+              <li key={index} data-is-new={isNew || null}>
+                <span>
+                  <SVG src={iconCompleted} />
+                </span>{' '}
+                {content}
+              </li>
+            )
+
+            return featureFlag ? <FeatureGuard featureFlag={featureFlag}>{item}</FeatureGuard> : item
+          })}
         </styledEl.List>
       )}
 
diff --git a/apps/cowswap-frontend/src/modules/tradeFormValidation/hooks/useTradeFormValidationContext.ts b/apps/cowswap-frontend/src/modules/tradeFormValidation/hooks/useTradeFormValidationContext.ts
index 1a2eb136fe..7b619e1f82 100644
--- a/apps/cowswap-frontend/src/modules/tradeFormValidation/hooks/useTradeFormValidationContext.ts
+++ b/apps/cowswap-frontend/src/modules/tradeFormValidation/hooks/useTradeFormValidationContext.ts
@@ -1,5 +1,6 @@
 import { useMemo } from 'react'
 
+import { useFeatureFlags } from '@cowprotocol/common-hooks'
 import { useENSAddress } from '@cowprotocol/ens'
 import { useIsTradeUnsupported } from '@cowprotocol/tokens'
 import { useGnosisSafeInfo, useIsBundlingSupported, useWalletDetails, useWalletInfo } from '@cowprotocol/wallet'
@@ -19,6 +20,7 @@ export function useTradeFormValidationContext(): TradeFormValidationCommonContex
   const { account } = useWalletInfo()
   const { state: derivedTradeState } = useDerivedTradeState()
   const tradeQuote = useTradeQuote()
+  const { isZeroBalanceOrdersEnabled } = useFeatureFlags()
 
   const { inputCurrency, outputCurrency, slippageAdjustedSellAmount, recipient, tradeType } = derivedTradeState || {}
   const { state: approvalState } = useApproveState(slippageAdjustedSellAmount)
@@ -35,7 +37,7 @@ export function useTradeFormValidationContext(): TradeFormValidationCommonContex
 
   const isPermitSupported = useTokenSupportsPermit(inputCurrency, tradeType)
 
-  const isInsufficientBalanceOrderAllowed = tradeType === TradeType.LIMIT_ORDER
+  const isInsufficientBalanceOrderAllowed = isZeroBalanceOrdersEnabled && tradeType === TradeType.LIMIT_ORDER
 
   const commonContext = {
     account,

From 37ecfcf05df4bbc08193e04008bb83ed7a03c424 Mon Sep 17 00:00:00 2001
From: Alexandr Kazachenko <shoom3301@gmail.com>
Date: Fri, 29 Mar 2024 14:02:32 +0500
Subject: [PATCH 2/2] chore: release main (#4118)

---
 .release-please-manifest.json      | 2 +-
 apps/cowswap-frontend/CHANGELOG.md | 7 +++++++
 apps/cowswap-frontend/package.json | 2 +-
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index b6d99cd2cb..e1e0c0eedf 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,5 +1,5 @@
 {
-  "apps/cowswap-frontend": "1.64.1",
+  "apps/cowswap-frontend": "1.64.2",
   "apps/explorer": "2.29.2",
   "libs/permit-utils": "0.1.2",
   "libs/widget-lib": "0.7.1",
diff --git a/apps/cowswap-frontend/CHANGELOG.md b/apps/cowswap-frontend/CHANGELOG.md
index f5ad42fe24..b2eb0ba675 100644
--- a/apps/cowswap-frontend/CHANGELOG.md
+++ b/apps/cowswap-frontend/CHANGELOG.md
@@ -1,5 +1,12 @@
 # Changelog
 
+## [1.64.2](https://github.com/cowprotocol/cowswap/compare/cowswap-v1.64.1...cowswap-v1.64.2) (2024-03-29)
+
+
+### Bug Fixes
+
+* **limit-orders:** use ff for zero balance orders ([#4117](https://github.com/cowprotocol/cowswap/issues/4117)) ([28c60bd](https://github.com/cowprotocol/cowswap/commit/28c60bda7b8817ff7156e9e24f253f57da427b36))
+
 ## [1.64.1](https://github.com/cowprotocol/cowswap/compare/cowswap-v1.64.0...cowswap-v1.64.1) (2024-03-28)
 
 
diff --git a/apps/cowswap-frontend/package.json b/apps/cowswap-frontend/package.json
index 7bfcab6249..5bd8cfb5c5 100644
--- a/apps/cowswap-frontend/package.json
+++ b/apps/cowswap-frontend/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@cowprotocol/cowswap",
-  "version": "1.64.1",
+  "version": "1.64.2",
   "description": "CoW Swap",
   "main": "index.js",
   "author": "",