Skip to content

Commit

Permalink
Revert "feat(swap): partial approve (#5256)"
Browse files Browse the repository at this point in the history
This reverts commit f080ffd.
  • Loading branch information
alfetopito committed Jan 9, 2025
1 parent f080ffd commit 7a1ce48
Show file tree
Hide file tree
Showing 43 changed files with 149 additions and 350 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { ReactElement, useEffect, useMemo, useState } from 'react'
import { latest } from '@cowprotocol/app-data'
import { CowHookDetails, HookToDappMatch, matchHooksToDappsRegistry } from '@cowprotocol/hook-dapp-lib'
import { InfoTooltip } from '@cowprotocol/ui'
import { useWalletInfo } from '@cowprotocol/wallet'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'

import { ChevronDown, ChevronUp } from 'react-feather'

Expand All @@ -16,27 +14,15 @@ import { HookItem } from './HookItem'
import * as styledEl from './styled'
import { CircleCount } from './styled'

import { parsePermitData } from '../../utils/parsePermitData'

interface OrderHooksDetailsProps {
appData: string | AppDataInfo
children: (content: ReactElement) => ReactElement
margin?: string
isTradeConfirmation?: boolean
slippageAdjustedSellAmount?: CurrencyAmount<Currency>
isPartialApprove?: boolean
}

export function OrderHooksDetails({
appData,
children,
margin,
isTradeConfirmation,
slippageAdjustedSellAmount,
isPartialApprove,
}: OrderHooksDetailsProps) {
export function OrderHooksDetails({ appData, children, margin, isTradeConfirmation }: OrderHooksDetailsProps) {
const [isOpen, setOpen] = useState(false)
const { account } = useWalletInfo()
const appDataDoc = useMemo(() => {
return typeof appData === 'string' ? decodeAppData(appData) : appData.doc
}, [appData])
Expand All @@ -55,32 +41,9 @@ export function OrderHooksDetails({

const metadata = appDataDoc.metadata as latest.Metadata

/**
* AppData might include a hook with account agnostic permit which is used to fetch a quote.
* This hook should be ignored.
* Moreover, any hook with a permit which has owner !== current account will be excluded.
* We also remove the permit from appData before order signing (see filterPermitSignerPermit).
*/
const preHooks = account
? metadata.hooks?.pre?.filter((hook) => {
try {
const permitHookData = parsePermitData(hook.callData)
const isOwnerMatched = permitHookData.owner.toLowerCase() === account.toLowerCase()

// If the hook is a partial approve, we need to check if the value is equal to the slippageAdjustedSellAmount
// Because there might be a hook with an "infinite" permit from other widget
return isPartialApprove && slippageAdjustedSellAmount
? isOwnerMatched && permitHookData.value.eq(slippageAdjustedSellAmount.quotient.toString())
: isOwnerMatched
} catch {
return true
}
})
: metadata.hooks?.pre

const hasSomeFailedSimulation = isTradeConfirmation && Object.values(data || {}).some((hook) => !hook.status)

const preHooksToDapp = matchHooksToDappsRegistry(preHooks || [], preCustomHookDapps)
const preHooksToDapp = matchHooksToDappsRegistry(metadata.hooks?.pre || [], preCustomHookDapps)
const postHooksToDapp = matchHooksToDappsRegistry(metadata.hooks?.post || [], postCustomHookDapps)

if (!preHooksToDapp.length && !postHooksToDapp.length) return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@ export interface TradeApproveButtonProps {
amountToApprove: CurrencyAmount<Currency>
children?: React.ReactNode
isDisabled?: boolean
isPartialApprove?: boolean
}

export function TradeApproveButton(props: TradeApproveButtonProps) {
const { amountToApprove, children, isDisabled, isPartialApprove } = props
const { amountToApprove, children, isDisabled } = props

const currency = amountToApprove.currency

const { state: approvalState } = useApproveState(amountToApprove)
const tradeApproveCallback = useTradeApproveCallback(amountToApprove, isPartialApprove)
const tradeApproveCallback = useTradeApproveCallback(amountToApprove)
const shouldZeroApprove = useShouldZeroApprove(amountToApprove)
const zeroApprove = useZeroApprove(amountToApprove.currency)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,13 @@ export interface TradeApproveCallback {
(params?: TradeApproveCallbackParams): Promise<TransactionResponse | undefined>
}

export function useTradeApproveCallback(
amountToApprove?: CurrencyAmount<Currency>,
isPartialApprove?: boolean,
): TradeApproveCallback {
export function useTradeApproveCallback(amountToApprove?: CurrencyAmount<Currency>): TradeApproveCallback {
const updateTradeApproveState = useUpdateTradeApproveState()
const spender = useTradeSpenderAddress()
const currency = amountToApprove?.currency
const symbol = currency?.symbol

const approveCallback = useApproveCallback(amountToApprove, spender, isPartialApprove)
const approveCallback = useApproveCallback(amountToApprove, spender)

return useCallback(
async ({ useModals = true }: TradeApproveCallbackParams = { useModals: true }) => {
Expand Down Expand Up @@ -61,6 +58,6 @@ export function useTradeApproveCallback(
return undefined
})
},
[symbol, approveCallback, updateTradeApproveState, currency],
[symbol, approveCallback, updateTradeApproveState, currency]
)
}
15 changes: 5 additions & 10 deletions apps/cowswap-frontend/src/common/hooks/useApproveCallback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,14 @@ export async function estimateApprove(
tokenContract: Erc20,
spender: string,
amountToApprove: CurrencyAmount<Currency>,
isPartialApprove?: boolean,
): Promise<{
approveAmount: BigNumber | string
gasLimit: BigNumber
}> {
const approveAmount =
isPartialApprove && amountToApprove ? BigNumber.from(amountToApprove.quotient.toString()) : MaxUint256

try {
return {
approveAmount,
gasLimit: await tokenContract.estimateGas.approve(spender, approveAmount),
approveAmount: MaxUint256,
gasLimit: await tokenContract.estimateGas.approve(spender, MaxUint256),
}
} catch {
// Fallback: Attempt to set an approval for the maximum wallet balance (instead of the MaxUint256).
Expand All @@ -49,7 +45,7 @@ export async function estimateApprove(
)

return {
approveAmount,
approveAmount: MaxUint256,
gasLimit: GAS_LIMIT_DEFAULT,
}
}
Expand All @@ -59,7 +55,6 @@ export async function estimateApprove(
export function useApproveCallback(
amountToApprove?: CurrencyAmount<Currency>,
spender?: string,
isPartialApprove?: boolean,
): (summary?: string) => Promise<TransactionResponse | undefined> {
const { chainId } = useWalletInfo()
const currency = amountToApprove?.currency
Expand All @@ -73,7 +68,7 @@ export function useApproveCallback(
return
}

const estimation = await estimateApprove(tokenContract, spender, amountToApprove, isPartialApprove)
const estimation = await estimateApprove(tokenContract, spender, amountToApprove)
return tokenContract
.approve(spender, estimation.approveAmount, {
gasLimit: calculateGasMargin(estimation.gasLimit),
Expand All @@ -86,5 +81,5 @@ export function useApproveCallback(
})
return response
})
}, [chainId, token, tokenContract, amountToApprove, spender, addTransaction, isPartialApprove])
}, [chainId, token, tokenContract, amountToApprove, spender, addTransaction])
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export function ApproveButton(props: ApproveButtonProps) {
content={
<Trans>
You must give the CoW Protocol smart contracts permission to use your <TokenSymbol token={currency} />.
If you approve the default amount, you will only have to do this once per token.
</Trans>
}
>
Expand Down
15 changes: 3 additions & 12 deletions apps/cowswap-frontend/src/common/pure/OrderProgressBarV2/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,7 @@ import { ExplorerDataType, getExplorerLink, getRandomInt, isSellOrder, shortenAd
import { OrderKind, SupportedChainId } from '@cowprotocol/cow-sdk'
import { TokenLogo } from '@cowprotocol/tokens'
import { Command } from '@cowprotocol/types'
import {
Confetti,
ExternalLink,
InfoTooltip,
ProductLogo,
ProductVariant,
TokenAmount,
UI,
UnderlinedLinkStyledButton,
} from '@cowprotocol/ui'
import { Confetti, ExternalLink, InfoTooltip, ProductLogo, ProductVariant, TokenAmount, UI } from '@cowprotocol/ui'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'

import { AnimatePresence, motion } from 'framer-motion'
Expand Down Expand Up @@ -1132,14 +1123,14 @@ function ExpiredStep(props: OrderProgressBarV2Props) {
<h3>The good news</h3>
<p>
Unlike on other exchanges, you won't be charged for this! Feel free to{' '}
<UnderlinedLinkStyledButton
<styledEl.Button
onClick={() => {
props.navigateToNewOrder?.()
trackNewOrderClick()
}}
>
place a new order
</UnderlinedLinkStyledButton>{' '}
</styledEl.Button>{' '}
without worry.
</p>
</styledEl.InfoCard>
Expand Down
12 changes: 10 additions & 2 deletions apps/cowswap-frontend/src/common/pure/OrderProgressBarV2/styled.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import IMAGE_STAR_SHINE from '@cowprotocol/assets/cow-swap/star-shine.svg'
import { SingleLetterLogoWrapper } from '@cowprotocol/tokens'
import { ButtonPrimary, Font, Media, UI } from '@cowprotocol/ui'
import { ButtonPrimary, Font, LinkStyledButton, Media, UI } from '@cowprotocol/ui'

import styled, { css, keyframes } from 'styled-components/macro'

Expand Down Expand Up @@ -66,7 +66,6 @@ export const StepsContainer = styled.div<{ $height: number; $minHeight?: string;
padding: 0;
// implement a gradient to hide the bottom of the steps container using white to opacity white using pseudo element
&::after {
content: ${({ bottomGradient }) => (bottomGradient ? '""' : 'none')};
position: absolute;
Expand Down Expand Up @@ -144,6 +143,15 @@ export const CancelButton = styled(CancelButtonOriginal)`
}
`

export const Button = styled(LinkStyledButton)`
font-size: 14px;
text-decoration: underline;
&:hover {
text-decoration: none;
}
`

export const ProgressImageWrapper = styled.div<{ bgColor?: string; padding?: string; height?: string; gap?: string }>`
width: 100%;
height: ${({ height }) => height || '246px'};
Expand Down
15 changes: 0 additions & 15 deletions apps/cowswap-frontend/src/common/utils/parsePermitData.ts

This file was deleted.

19 changes: 0 additions & 19 deletions apps/cowswap-frontend/src/legacy/state/user/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ import { Currency } from '@uniswap/sdk-core'

import { shallowEqual } from 'react-redux'

import { useIsHooksTradeType } from 'modules/trade/hooks/useIsHooksTradeType'

import {
updateHooksEnabled,
updatePartialApprove,
updateRecipientToggleVisible,
updateUserDarkMode,
updateUserDeadline,
Expand Down Expand Up @@ -121,22 +118,6 @@ export function useUserTransactionTTL(): [number, (slippage: number) => void] {
return [deadline, setUserDeadline]
}

export function usePartialApprove(): [boolean, (value: boolean) => void] {
const dispatch = useAppDispatch()
const isHookTradeType = useIsHooksTradeType()
const partialApprove = useAppSelector((state) => state.user.partialApprove)

const setPartialApprove = useCallback(
(partialApprove: boolean) => {
dispatch(updatePartialApprove({ partialApprove }))
},
[dispatch],
)

// Partial approve is disabled for Hooks store
return [isHookTradeType ? false : partialApprove, setPartialApprove]
}

export function useSelectedWallet(): string | undefined {
return useAppSelector(({ user: { selectedWallet } }) => selectedWallet)
}
Expand Down
7 changes: 1 addition & 6 deletions apps/cowswap-frontend/src/legacy/state/user/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export interface UserState {
// TODO: mod, shouldn't be here
recipientToggleVisible: boolean
hooksEnabled: boolean
partialApprove: boolean

// deadline set by user in minutes, used in all txns
userDeadline: number
Expand All @@ -28,9 +27,9 @@ export const initialState: UserState = {
selectedWallet: undefined,
matchesDarkMode: false,
userDarkMode: null,
// TODO: mod, shouldn't be here
recipientToggleVisible: false,
hooksEnabled: false,
partialApprove: false,
userLocale: null,
userDeadline: DEFAULT_DEADLINE_FROM_NOW,
}
Expand All @@ -57,9 +56,6 @@ const userSlice = createSlice({
updateUserDeadline(state, action) {
state.userDeadline = action.payload.userDeadline
},
updatePartialApprove(state, action) {
state.partialApprove = action.payload.partialApprove
},
updateRecipientToggleVisible(state, action) {
state.recipientToggleVisible = action.payload.recipientToggleVisible
},
Expand All @@ -74,6 +70,5 @@ export const {
updateUserDeadline,
updateUserLocale,
updateRecipientToggleVisible,
updatePartialApprove,
} = userSlice.actions
export default userSlice.reducer
Loading

0 comments on commit 7a1ce48

Please sign in to comment.