From 6a1c7d39c15e6d692e71dc2b51ea0d4f27fa8e0d Mon Sep 17 00:00:00 2001
From: Chef Penguin
Date: Mon, 4 Nov 2024 16:50:00 +0530
Subject: [PATCH 1/5] chore: revert from free to discounted swaps on zksync
---
apps/web/src/config/paymaster.ts | 54 +++++++++++---------------------
1 file changed, 18 insertions(+), 36 deletions(-)
diff --git a/apps/web/src/config/paymaster.ts b/apps/web/src/config/paymaster.ts
index eb5029fa0f6f8..b705119b70187 100644
--- a/apps/web/src/config/paymaster.ts
+++ b/apps/web/src/config/paymaster.ts
@@ -7,11 +7,11 @@ import addresses from 'config/constants/contracts'
import { getAddressFromMap } from 'utils/addressHelpers'
import { Address, Hex } from 'viem'
-// export const DEFAULT_PAYMASTER_TOKEN = Native.onChain(ChainId.ZKSYNC)
+export const DEFAULT_PAYMASTER_TOKEN = Native.onChain(ChainId.ZKSYNC)
export const paymasterTokens: Currency[] = [
- // DEFAULT_PAYMASTER_TOKEN,
- Native.onChain(ChainId.ZKSYNC),
+ DEFAULT_PAYMASTER_TOKEN,
+ zksyncTokens.zk,
zksyncTokens.wbtc,
zksyncTokens.dai,
zksyncTokens.usdc,
@@ -26,73 +26,55 @@ export const paymasterTokens: Currency[] = [
zksyncTokens.weth,
zksyncTokens.wethe,
zksyncTokens.hold,
- zksyncTokens.zk,
]
-export const DEFAULT_PAYMASTER_TOKEN = paymasterTokens[4]
-
export const paymasterInfo: {
[gasTokenAddress: Address]: { discount: `-${number}%` | 'FREE'; discountLabel?: string }
} = {
[zksyncTokens.wbtc.address]: {
- discount: 'FREE', // Example: -20%, FREE
- discountLabel: 'FREE SWAP',
+ discount: '-20%', // Example: -20%, FREE
},
[zksyncTokens.dai.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.usdc.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.usdcNative.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.usdt.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.grai.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.tes.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.busd.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.reth.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.wstETH.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.meow.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.weth.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.wethe.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.hold.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-20%',
},
[zksyncTokens.zk.address]: {
- discount: 'FREE',
- discountLabel: 'FREE SWAP',
+ discount: '-40%',
},
}
From 6a6b7f61736c08879453bcb8d6707a3b76888bf6 Mon Sep 17 00:00:00 2001
From: Chef Penguin
Date: Mon, 4 Nov 2024 16:56:25 +0530
Subject: [PATCH 2/5] chore: gas token help text
---
.../components/Paymaster/GasTokenSelector.tsx | 18 ++++++++++--------
apps/web/src/pages/api/paymaster/index.ts | 2 +-
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/apps/web/src/components/Paymaster/GasTokenSelector.tsx b/apps/web/src/components/Paymaster/GasTokenSelector.tsx
index e14f0032fba9c..aad6a686e4008 100644
--- a/apps/web/src/components/Paymaster/GasTokenSelector.tsx
+++ b/apps/web/src/components/Paymaster/GasTokenSelector.tsx
@@ -6,6 +6,7 @@ import {
Button,
CircleLoader,
Column,
+ DottedHelpText,
Flex,
Heading,
ModalBody,
@@ -15,6 +16,7 @@ import {
ModalTitle,
ModalV2,
QuestionHelper,
+ QuestionHelperV2,
RowBetween,
RowFixed,
Text,
@@ -265,12 +267,9 @@ export const GasTokenSelector = ({ currency: inputCurrency }: GasTokenSelectorPr
return (
<>
-
+
-
- {t('Gas Token')}
-
-
@@ -285,11 +284,14 @@ export const GasTokenSelector = ({ currency: inputCurrency }: GasTokenSelectorPr
>
}
- ml="4px"
placement="top"
- />
+ >
+
+ {t('Gas Token')}
+
+
{gasTokenInfo && gasTokenInfo.discount && (
-
+
⛽️ {gasTokenInfo.discountLabel ?? gasTokenInfo.discount}
)}
diff --git a/apps/web/src/pages/api/paymaster/index.ts b/apps/web/src/pages/api/paymaster/index.ts
index 487775a090a7e..a45689d1ea012 100644
--- a/apps/web/src/pages/api/paymaster/index.ts
+++ b/apps/web/src/pages/api/paymaster/index.ts
@@ -25,7 +25,7 @@ const handler: NextApiHandler = async (req, res) => {
// Check calldata for ERC20 approve
const decodedCalldata = decodeFunctionData({ data: call.calldata, abi: erc20Abi })
if (decodedCalldata.functionName === 'approve') isTransactionWhitelisted = true
- } catch (e) {
+ } catch {
// do nothing. must be another type of transaction if decoding failed
}
From 306e8fcc6e70926cfaf187d7e8f5ffd90bb7ae88 Mon Sep 17 00:00:00 2001
From: Chef Penguin
Date: Mon, 4 Nov 2024 17:45:18 +0530
Subject: [PATCH 3/5] chore: whitelist cake as gas token
---
apps/web/src/config/paymaster.ts | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/apps/web/src/config/paymaster.ts b/apps/web/src/config/paymaster.ts
index b705119b70187..b72052c22f5c6 100644
--- a/apps/web/src/config/paymaster.ts
+++ b/apps/web/src/config/paymaster.ts
@@ -12,6 +12,7 @@ export const DEFAULT_PAYMASTER_TOKEN = Native.onChain(ChainId.ZKSYNC)
export const paymasterTokens: Currency[] = [
DEFAULT_PAYMASTER_TOKEN,
zksyncTokens.zk,
+ zksyncTokens.cake,
zksyncTokens.wbtc,
zksyncTokens.dai,
zksyncTokens.usdc,
@@ -31,8 +32,11 @@ export const paymasterTokens: Currency[] = [
export const paymasterInfo: {
[gasTokenAddress: Address]: { discount: `-${number}%` | 'FREE'; discountLabel?: string }
} = {
+ [zksyncTokens.zk.address]: {
+ discount: '-40%',
+ },
[zksyncTokens.wbtc.address]: {
- discount: '-20%', // Example: -20%, FREE
+ discount: '-20%',
},
[zksyncTokens.dai.address]: {
discount: '-20%',
@@ -73,8 +77,8 @@ export const paymasterInfo: {
[zksyncTokens.hold.address]: {
discount: '-20%',
},
- [zksyncTokens.zk.address]: {
- discount: '-40%',
+ [zksyncTokens.cake.address]: {
+ discount: '-20%',
},
}
From 360a3118a4cfc31040b3f17ad59a27bec69baa5d Mon Sep 17 00:00:00 2001
From: Chef Penguin
Date: Mon, 4 Nov 2024 19:56:55 +0530
Subject: [PATCH 4/5] chore: new gas token selector location and design
---
.../components/Paymaster/GasTokenSelector.tsx | 21 +++++++++++--------
.../Swap/V3Swap/containers/TradeDetails.tsx | 6 ++++--
.../V4Swap/AdvancedSwapDetails.tsx | 5 +----
.../V4Swap/ButtonAndDetailsPanel.tsx | 9 ++++++--
.../SwapSimplify/V4Swap/TradeDetails.tsx | 5 -----
.../src/views/SwapSimplify/V4Swap/index.tsx | 7 +++++++
6 files changed, 31 insertions(+), 22 deletions(-)
diff --git a/apps/web/src/components/Paymaster/GasTokenSelector.tsx b/apps/web/src/components/Paymaster/GasTokenSelector.tsx
index aad6a686e4008..e68f349c6bb2f 100644
--- a/apps/web/src/components/Paymaster/GasTokenSelector.tsx
+++ b/apps/web/src/components/Paymaster/GasTokenSelector.tsx
@@ -2,6 +2,7 @@ import { useTranslation } from '@pancakeswap/localization'
import {
ArrowDropDownIcon,
ArrowForwardIcon,
+ AtomBoxProps,
Box,
Button,
CircleLoader,
@@ -41,8 +42,10 @@ import { DEFAULT_PAYMASTER_TOKEN, paymasterInfo, paymasterTokens } from 'config/
import { useGasToken } from 'hooks/useGasToken'
// Selector Styles
-const GasTokenSelectButton = styled(Button).attrs({ variant: 'text', scale: 'xs' })`
- padding: 18px 0 18px 6px;
+const GasTokenSelectButton = styled(Button).attrs({ variant: 'tertiary', scale: 'xs' })`
+ padding: 16px 0 14px 6px;
+ border-radius: 12px;
+ border-bottom: 2px solid rgba(0, 0, 0, 0.1);
`
// Modal Styles
@@ -108,7 +111,7 @@ const SameTokenWarningBox = styled(Box)`
font-size: 13px;
background-color: #ffb2371a;
padding: 10px;
- margin: 5px 0 8px;
+ margin-bottom: 8px;
color: ${({ theme }) => theme.colors.yellow};
border: 1px solid ${({ theme }) => theme.colors.yellow};
border-radius: ${({ theme }) => theme.radii['12px']};
@@ -118,11 +121,11 @@ const StyledWarningIcon = styled(WarningIcon)`
fill: ${({ theme }) => theme.colors.yellow};
`
-interface GasTokenSelectorProps {
- currency?: Currency
+interface GasTokenSelectorProps extends AtomBoxProps {
+ inputCurrency?: Currency
}
-export const GasTokenSelector = ({ currency: inputCurrency }: GasTokenSelectorProps) => {
+export const GasTokenSelector = ({ inputCurrency, ...props }: GasTokenSelectorProps) => {
const { t } = useTranslation()
const { isOpen, setIsOpen, onDismiss } = useModalV2()
const { address: account } = useAccount()
@@ -267,7 +270,7 @@ export const GasTokenSelector = ({ currency: inputCurrency }: GasTokenSelectorPr
return (
<>
-
+
⛽️
-
+
{(gasToken && gasToken.symbol && gasToken.symbol.length > 10
? `${gasToken.symbol.slice(0, 4)}...${gasToken.symbol.slice(
gasToken.symbol.length - 5,
@@ -317,7 +320,7 @@ export const GasTokenSelector = ({ currency: inputCurrency }: GasTokenSelectorPr
)}`
: gasToken?.symbol) || ''}
-
+
diff --git a/apps/web/src/views/Swap/V3Swap/containers/TradeDetails.tsx b/apps/web/src/views/Swap/V3Swap/containers/TradeDetails.tsx
index 541bf08d94601..0ab321d1e4403 100644
--- a/apps/web/src/views/Swap/V3Swap/containers/TradeDetails.tsx
+++ b/apps/web/src/views/Swap/V3Swap/containers/TradeDetails.tsx
@@ -5,9 +5,9 @@ import { memo, useMemo } from 'react'
import { TradeSummary } from 'views/Swap/components/AdvancedSwapDetails'
import { AdvancedDetailsFooter } from 'views/Swap/components/AdvancedSwapDetailsDropdown'
+import { PriceOrder } from '@pancakeswap/price-api-sdk'
import { GasTokenSelector } from 'components/Paymaster/GasTokenSelector'
import { usePaymaster } from 'hooks/usePaymaster'
-import { PriceOrder } from '@pancakeswap/price-api-sdk'
import { isClassicOrder, isXOrder } from 'views/Swap/utils'
import { RoutesBreakdown, XRoutesBreakdown } from '../components'
import { useIsWrapping, useSlippageAdjustedAmounts } from '../hooks'
@@ -53,7 +53,9 @@ export const TradeDetails = memo(function TradeDetails({ loaded, order }: Props)
priceImpactWithoutFee={priceImpactWithoutFee ?? undefined}
realizedLPFee={lpFeeAmount ?? undefined}
hasStablePair={hasStablePool}
- gasTokenSelector={isPaymasterAvailable && inputAmount && }
+ gasTokenSelector={
+ isPaymasterAvailable && inputAmount &&
+ }
/>
{isXOrder(order) ? : }
diff --git a/apps/web/src/views/SwapSimplify/V4Swap/AdvancedSwapDetails.tsx b/apps/web/src/views/SwapSimplify/V4Swap/AdvancedSwapDetails.tsx
index 4b03179841d59..bb63025876460 100644
--- a/apps/web/src/views/SwapSimplify/V4Swap/AdvancedSwapDetails.tsx
+++ b/apps/web/src/views/SwapSimplify/V4Swap/AdvancedSwapDetails.tsx
@@ -15,7 +15,7 @@ import {
} from '@pancakeswap/uikit'
import { formatAmount, formatFraction } from '@pancakeswap/utils/formatFractions'
import { useUserSlippage } from '@pancakeswap/utils/user'
-import React, { memo, useState } from 'react'
+import { memo, useState } from 'react'
import { NumberDisplay } from '@pancakeswap/widgets-internal'
import { RowBetween, RowFixed } from 'components/Layout/Row'
@@ -44,7 +44,6 @@ export const TradeSummary = memo(function TradeSummary({
slippageAdjustedAmounts,
priceImpactWithoutFee,
realizedLPFee,
- gasTokenSelector,
isX = false,
loading = false,
}: {
@@ -55,7 +54,6 @@ export const TradeSummary = memo(function TradeSummary({
slippageAdjustedAmounts: SlippageAdjustedAmounts
priceImpactWithoutFee?: Percent | null
realizedLPFee?: CurrencyAmount | null
- gasTokenSelector?: React.ReactNode
isX?: boolean
loading?: boolean
}) {
@@ -66,7 +64,6 @@ export const TradeSummary = memo(function TradeSummary({
return (
- {gasTokenSelector}
theme.colors.cardBorder};
`
interface ButtonAndDetailsPanelProps {
+ shouldRenderDetails?: boolean
+
swapCommitButton: React.ReactNode
pricingAndSlippage: React.ReactNode
tradeDetails: React.ReactNode
- shouldRenderDetails?: boolean
+
+ gasTokenSelector?: React.ReactNode
}
export const ButtonAndDetailsPanel: React.FC = ({
+ shouldRenderDetails,
swapCommitButton,
pricingAndSlippage,
tradeDetails,
- shouldRenderDetails,
+ gasTokenSelector,
}) => {
const [isOpen, setIsOpen] = useState(false)
return (
{swapCommitButton}
+ {gasTokenSelector}
{shouldRenderDetails && (
}
loading={!loaded}
/>
diff --git a/apps/web/src/views/SwapSimplify/V4Swap/index.tsx b/apps/web/src/views/SwapSimplify/V4Swap/index.tsx
index a263903f0bd94..d5c502a75f787 100644
--- a/apps/web/src/views/SwapSimplify/V4Swap/index.tsx
+++ b/apps/web/src/views/SwapSimplify/V4Swap/index.tsx
@@ -5,9 +5,11 @@ import { useUserSlippage } from '@pancakeswap/utils/user'
import { SwapUIV2 } from '@pancakeswap/widgets-internal'
import { useTokenRisk } from 'components/AccessRisk'
import { RiskDetailsPanel, useShouldRiskPanelDisplay } from 'components/AccessRisk/SwapRevampRiskDisplay'
+import { GasTokenSelector } from 'components/Paymaster/GasTokenSelector'
import { useCurrency } from 'hooks/Tokens'
import { useActiveChainId } from 'hooks/useActiveChainId'
import { useCurrencyUsdPrice } from 'hooks/useCurrencyUsdPrice'
+import { usePaymaster } from 'hooks/usePaymaster'
import { useMemo } from 'react'
import { Field } from 'state/swap/actions'
import { useSwapState } from 'state/swap/hooks'
@@ -120,6 +122,8 @@ export function V4SwapForm() {
const token0Risk = useTokenRisk(inputCurrency?.wrapped)
const token1Risk = useTokenRisk(outputCurrency?.wrapped)
+ const { isPaymasterAvailable } = usePaymaster()
+
return (
@@ -180,6 +184,9 @@ export function V4SwapForm() {
}
tradeDetails={}
+ gasTokenSelector={
+ isPaymasterAvailable &&
+ }
shouldRenderDetails={Boolean(executionPrice) && Boolean(bestOrder) && !isWrapping}
/>
From 2fffad9538e8a41edbe3676445fd60c63f46af26 Mon Sep 17 00:00:00 2001
From: Chef Penguin
Date: Tue, 5 Nov 2024 10:00:22 +0530
Subject: [PATCH 5/5] chore: paymaster whitelist only if txn is sponsored
---
apps/web/src/config/paymaster.ts | 2 +-
apps/web/src/pages/api/paymaster/index.ts | 28 ++++++++++++-----------
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/apps/web/src/config/paymaster.ts b/apps/web/src/config/paymaster.ts
index b72052c22f5c6..dc313e12b9552 100644
--- a/apps/web/src/config/paymaster.ts
+++ b/apps/web/src/config/paymaster.ts
@@ -83,7 +83,7 @@ export const paymasterInfo: {
}
/**
- * Contracts that the paymaster is allowed to interact with.
+ * Contracts that the paymaster is allowed to interact with if transaction is sponsored.
* In addition, ERC20 Approve transactions are allowed.
*/
export const PAYMASTER_CONTRACT_WHITELIST = [
diff --git a/apps/web/src/pages/api/paymaster/index.ts b/apps/web/src/pages/api/paymaster/index.ts
index a45689d1ea012..600bf0db5f205 100644
--- a/apps/web/src/pages/api/paymaster/index.ts
+++ b/apps/web/src/pages/api/paymaster/index.ts
@@ -19,22 +19,24 @@ const handler: NextApiHandler = async (req, res) => {
}
try {
- let isTransactionWhitelisted = PAYMASTER_CONTRACT_WHITELIST.includes(call.address.toLowerCase())
+ const gasTokenInfo = paymasterInfo[gasTokenAddress]
+ const isSponsored = gasTokenInfo?.discount === 'FREE'
- try {
- // Check calldata for ERC20 approve
- const decodedCalldata = decodeFunctionData({ data: call.calldata, abi: erc20Abi })
- if (decodedCalldata.functionName === 'approve') isTransactionWhitelisted = true
- } catch {
- // do nothing. must be another type of transaction if decoding failed
- }
+ if (isSponsored) {
+ let isTransactionWhitelisted = PAYMASTER_CONTRACT_WHITELIST.includes(call.address.toLowerCase())
- if (!isTransactionWhitelisted) {
- return res.status(400).json({ error: 'Transaction type not whitelisted for Paymaster' })
- }
+ try {
+ // Check calldata for ERC20 approve
+ const decodedCalldata = decodeFunctionData({ data: call.calldata, abi: erc20Abi })
+ if (decodedCalldata.functionName === 'approve') isTransactionWhitelisted = true
+ } catch {
+ // do nothing. must be another type of transaction if decoding failed
+ }
- const gasTokenInfo = paymasterInfo[gasTokenAddress]
- const isSponsored = gasTokenInfo?.discount === 'FREE'
+ if (!isTransactionWhitelisted) {
+ return res.status(400).json({ error: 'Transaction type not whitelisted for Paymaster' })
+ }
+ }
const PAYMASTER_URL = isSponsored ? ZYFI_SPONSORED_PAYMASTER_URL : ZYFI_PAYMASTER_URL
const gas = calculateGasMargin(BigInt(call.gas), 2000n)