diff --git a/packages/rest-api/src/routes/swapRoute.ts b/packages/rest-api/src/routes/swapRoute.ts index 8c050f3b2b..85b46223b8 100644 --- a/packages/rest-api/src/routes/swapRoute.ts +++ b/packages/rest-api/src/routes/swapRoute.ts @@ -8,6 +8,7 @@ import { isTokenAddress } from '../utils/isTokenAddress' import { isTokenSupportedOnChain } from '../utils/isTokenSupportedOnChain' import { checksumAddresses } from '../middleware/checksumAddresses' import { normalizeNativeTokenAddress } from '../middleware/normalizeNativeTokenAddress' +import { validSwap } from '../validations/validSwap' const router = express.Router() @@ -162,6 +163,13 @@ router.get( ) .withMessage('Token not supported on specified chain'), check('amount').exists().withMessage('amount is required').isNumeric(), + check() + .custom((_value, { req }) => { + const { chain, fromToken, toToken } = req.query + + return validSwap(chain, fromToken, toToken) + }) + .withMessage('Swap not supported'), ], showFirstValidationError, swapController diff --git a/packages/rest-api/src/tests/swapRoute.test.ts b/packages/rest-api/src/tests/swapRoute.test.ts index 775372bc31..bf993647ed 100644 --- a/packages/rest-api/src/tests/swapRoute.test.ts +++ b/packages/rest-api/src/tests/swapRoute.test.ts @@ -3,7 +3,7 @@ import express from 'express' import swapRoute from '../routes/swapRoute' import { NativeGasAddress, ZeroAddress } from '../constants' -import { DAI, NETH, USDC } from '../constants/bridgeable' +import { DAI, ETH, NETH, USDC } from '../constants/bridgeable' const app = express() app.use('/swap', swapRoute) @@ -78,6 +78,21 @@ describe('Swap Route with Real Synapse Service', () => { ) }, 10_000) + it('should return 400 for invalid fromToken + toToken combo', async () => { + const response = await request(app).get('/swap').query({ + chain: '1', + fromToken: ETH.addresses[1], + toToken: USDC.addresses[1], + amount: '1000', + }) + + expect(response.status).toBe(400) + expect(response.body.error).toHaveProperty( + 'message', + 'Swap route not supported' + ) + }) + it('should return 400 for token not supported on specified chain', async () => { const response = await request(app).get('/swap').query({ chain: '1', diff --git a/packages/rest-api/src/utils/tokenAddressToToken.ts b/packages/rest-api/src/utils/tokenAddressToToken.ts index 6bad892582..d4e88c255d 100644 --- a/packages/rest-api/src/utils/tokenAddressToToken.ts +++ b/packages/rest-api/src/utils/tokenAddressToToken.ts @@ -16,5 +16,6 @@ export const tokenAddressToToken = (chain: string, tokenAddress: string) => { address: tokenAddress, symbol: tokenInfo.symbol, decimals: tokenInfo.decimals, + swappable: tokenInfo.swappable, } } diff --git a/packages/rest-api/src/validations/validSwap.ts b/packages/rest-api/src/validations/validSwap.ts new file mode 100644 index 0000000000..2759d4b39c --- /dev/null +++ b/packages/rest-api/src/validations/validSwap.ts @@ -0,0 +1,12 @@ +import { tokenAddressToToken } from '../utils/tokenAddressToToken' + +export const validSwap = (chain, fromToken, toToken) => { + const fromTokenInfo = tokenAddressToToken(chain.toString(), fromToken) + const toTokenInfo = tokenAddressToToken(chain.toString(), toToken) + + if (!fromTokenInfo || !toTokenInfo) { + return false + } + + return fromTokenInfo.swappable.includes(toToken) +}