diff --git a/.changeset/nasty-terms-cover.md b/.changeset/nasty-terms-cover.md new file mode 100644 index 000000000..ca269683f --- /dev/null +++ b/.changeset/nasty-terms-cover.md @@ -0,0 +1,6 @@ +--- +'@reservoir0x/relay-sdk': patch +'@reservoir0x/relay-kit-ui': patch +--- + +Fix dead address being allowed as burn address diff --git a/packages/sdk/src/actions/execute.ts b/packages/sdk/src/actions/execute.ts index 5b59630ff..0ce6af80c 100644 --- a/packages/sdk/src/actions/execute.ts +++ b/packages/sdk/src/actions/execute.ts @@ -8,6 +8,7 @@ import { } from '../utils/index.js' import { type WalletClient } from 'viem' import { isViemWalletClient } from '../utils/viemWallet.js' +import { isDeadAddress } from '../constants/address.js' export type ExecuteActionParameters = { quote: Execute @@ -49,6 +50,10 @@ export async function execute(data: ExecuteActionParameters) { throw new Error('Missing chainId from quote') } + if (isDeadAddress(quote?.details?.recipient)) { + throw new Error('Recipient should never be burn address') + } + const { request, ...restOfQuote } = quote const _quote = safeStructuredClone(restOfQuote) diff --git a/packages/sdk/src/actions/getQuote.test.ts b/packages/sdk/src/actions/getQuote.test.ts index d07a446dc..cee6da6af 100644 --- a/packages/sdk/src/actions/getQuote.test.ts +++ b/packages/sdk/src/actions/getQuote.test.ts @@ -68,13 +68,13 @@ describe('Should test the getQuote action.', () => { expect.objectContaining({ url: expect.stringContaining('quote'), data: expect.objectContaining({ - user: '0x0000000000000000000000000000000000000000', + user: '0x000000000000000000000000000000000000dead', destinationCurrency: '0x0000000000000000000000000000000000000000', destinationChainId: 1, originCurrency: '0x0000000000000000000000000000000000000000', originChainId: 8453, amount: '1000000000000000', - recipient: '0x0000000000000000000000000000000000000000', + recipient: '0x000000000000000000000000000000000000dead', tradeType: 'EXACT_INPUT' }) }) @@ -106,13 +106,13 @@ describe('Should test the getQuote action.', () => { expect.objectContaining({ url: expect.stringContaining('quote'), data: expect.objectContaining({ - user: '0x0000000000000000000000000000000000000000', + user: '0x000000000000000000000000000000000000dead', destinationCurrency: '0x0000000000000000000000000000000000000000', destinationChainId: 1, originCurrency: '0x0000000000000000000000000000000000000000', originChainId: 8453, amount: '1000000000000000', - recipient: '0x0000000000000000000000000000000000000000', + recipient: '0x000000000000000000000000000000000000dead', tradeType: 'EXACT_INPUT', txs: [{ data: '0x', value: '0', to: '0x' }] }) diff --git a/packages/sdk/src/actions/getQuote.ts b/packages/sdk/src/actions/getQuote.ts index 363ee3e69..63443845e 100644 --- a/packages/sdk/src/actions/getQuote.ts +++ b/packages/sdk/src/actions/getQuote.ts @@ -11,6 +11,7 @@ import { import { isViemWalletClient } from '../utils/viemWallet.js' import { getClient } from '../client.js' import type { AdaptedWallet, Execute, paths } from '../types/index.js' +import { getDeadAddress } from '../constants/address.js' export type QuoteBody = NonNullable< paths['/quote']['post']['requestBody']['content']['application/json'] @@ -85,14 +86,26 @@ export async function getQuote( }) } + const fromChain = client.chains.find((chain) => chain.id === chainId) + const toChain = client.chains.find((chain) => chain.id === toChainId) + + const originDeadAddress = fromChain + ? getDeadAddress(fromChain.vmType, fromChain.id) + : undefined + const destinationDeadAddress = toChain + ? getDeadAddress(toChain.vmType, toChain.id) + : undefined + const query: QuoteBody = { - user: caller || zeroAddress, + user: caller || originDeadAddress || zeroAddress, destinationCurrency: toCurrency, destinationChainId: toChainId, originCurrency: currency, originChainId: chainId, amount, - recipient: recipient ? (recipient as string) : caller ?? zeroAddress, + recipient: recipient + ? (recipient as string) + : caller || destinationDeadAddress || zeroAddress, tradeType, referrer: client.source || undefined, txs: preparedTransactions, diff --git a/packages/sdk/src/constants/address.ts b/packages/sdk/src/constants/address.ts index 72e88ef8d..d375af679 100644 --- a/packages/sdk/src/constants/address.ts +++ b/packages/sdk/src/constants/address.ts @@ -20,3 +20,20 @@ export const getDeadAddress = (vmType?: ChainVM, chainId?: number) => { return evmDeadAddress } } + +export const isDeadAddress = (address?: string) => { + if (!address) { + return false + } + + if ( + address === eclipseDeadAddress || + address === solDeadAddress || + address === bitcoinDeadAddress || + address === evmDeadAddress + ) { + return true + } + + return false +} diff --git a/packages/ui/src/components/common/TransactionModal/TransactionModalRenderer.tsx b/packages/ui/src/components/common/TransactionModal/TransactionModalRenderer.tsx index bfe4eae36..f400cbe0f 100644 --- a/packages/ui/src/components/common/TransactionModal/TransactionModalRenderer.tsx +++ b/packages/ui/src/components/common/TransactionModal/TransactionModalRenderer.tsx @@ -293,7 +293,6 @@ export const TransactionModalRenderer: FC = ({ wallet ?? adaptViemWallet(walletClient.data as WalletClient) const activeWalletChainId = await _wallet?.getChainId() - if (fromToken && fromToken?.chainId !== activeWalletChainId) { onAnalyticEvent?.(EventNames.SWAP_SWITCH_NETWORK, { activeWalletChainId,