@@ -15,6 +15,7 @@ describe("ZeroExApiAdapter", () => {
1515 const sourceToken = "0x6cf5f1d59fddae3a688210953a512b6aee6ea643" ;
1616 const destToken = "0x5e5d0bea9d4a15db2d0837aff0435faba166190d" ;
1717 const otherToken = "0xae9902bb655de1a67f334d8661b3ae6a96723d5b" ;
18+ const wethToken = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" ;
1819 const extraHopToken = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" ;
1920 const destination = "0x89b3515cad4f23c1deacea79fc12445cc21bd0e1" ;
2021 const otherDestination = "0xdeb100c55cccfd6e39753f78c8b0c3bcbef86157" ;
@@ -33,7 +34,7 @@ describe("ZeroExApiAdapter", () => {
3334
3435 // Mock OneInch exchange that allows for only fixed exchange amounts
3536 zeroExMock = await deployer . mocks . deployZeroExMock ( ADDRESS_ZERO , ADDRESS_ZERO , ZERO , ZERO ) ;
36- zeroExApiAdapter = await deployer . adapters . deployZeroExApiAdapter ( zeroExMock . address ) ;
37+ zeroExApiAdapter = await deployer . adapters . deployZeroExApiAdapter ( zeroExMock . address , wethToken ) ;
3738 } ) ;
3839
3940 addSnapshotBeforeRestoreAfterEach ( ) ;
@@ -305,6 +306,26 @@ describe("ZeroExApiAdapter", () => {
305306 expect ( _data ) . to . deep . eq ( data ) ;
306307 } ) ;
307308
309+ it ( "permits any destination address when recipient is null" , async ( ) => {
310+ const data = zeroExMock . interface . encodeFunctionData ( "sellToLiquidityProvider" , [
311+ sourceToken ,
312+ destToken ,
313+ ADDRESS_ZERO ,
314+ ADDRESS_ZERO ,
315+ sourceQuantity ,
316+ minDestinationQuantity ,
317+ EMPTY_BYTES ,
318+ ] ) ;
319+ await zeroExApiAdapter . getTradeCalldata (
320+ sourceToken ,
321+ destToken ,
322+ destination ,
323+ sourceQuantity ,
324+ minDestinationQuantity ,
325+ data ,
326+ ) ;
327+ } ) ;
328+
308329 it ( "rejects wrong input token" , async ( ) => {
309330 const data = zeroExMock . interface . encodeFunctionData ( "sellToLiquidityProvider" , [
310331 otherToken ,
@@ -659,6 +680,7 @@ describe("ZeroExApiAdapter", () => {
659680
660681 describe ( "sellTokenForTokenToUniswapV3" , ( ) => {
661682 const additionalHops = [ otherToken , extraHopToken ] ;
683+
662684 for ( let i = 0 ; i <= additionalHops . length ; i ++ ) {
663685 const hops = take ( additionalHops , i ) ;
664686 it ( `validates data for ${ i + 1 } hops` , async ( ) => {
@@ -684,6 +706,25 @@ describe("ZeroExApiAdapter", () => {
684706 } ) ;
685707 }
686708
709+ it ( "permits any destination address when recipient is null" , async ( ) => {
710+ const path = [ sourceToken , destToken ] ;
711+
712+ const data = zeroExMock . interface . encodeFunctionData ( "sellTokenForTokenToUniswapV3" , [
713+ encodePath ( path ) ,
714+ sourceQuantity ,
715+ minDestinationQuantity ,
716+ ADDRESS_ZERO ,
717+ ] ) ;
718+ await zeroExApiAdapter . getTradeCalldata (
719+ sourceToken ,
720+ destToken ,
721+ destination ,
722+ sourceQuantity ,
723+ minDestinationQuantity ,
724+ data ,
725+ ) ;
726+ } ) ;
727+
687728 it ( "rejects wrong input token" , async ( ) => {
688729 const data = zeroExMock . interface . encodeFunctionData ( "sellTokenForTokenToUniswapV3" , [
689730 encodePath ( [ otherToken , destToken ] ) ,
@@ -779,12 +820,12 @@ describe("ZeroExApiAdapter", () => {
779820 encodePath ( [ sourceToken , destToken ] ) ,
780821 sourceQuantity ,
781822 minDestinationQuantity ,
782- ADDRESS_ZERO ,
823+ destination ,
783824 ] ) ;
784825 const tx = zeroExApiAdapter . getTradeCalldata (
785826 sourceToken ,
786827 destToken ,
787- destination ,
828+ otherDestination ,
788829 sourceQuantity ,
789830 minDestinationQuantity ,
790831 data ,
@@ -798,7 +839,7 @@ describe("ZeroExApiAdapter", () => {
798839 for ( let i = 0 ; i <= additionalHops . length ; i ++ ) {
799840 const hops = take ( additionalHops , i ) ;
800841 it ( `validates data for ${ i + 1 } hops` , async ( ) => {
801- const path = [ sourceToken , ...hops , ETH_ADDRESS ] ;
842+ const path = [ sourceToken , ...hops , wethToken ] ;
802843
803844 const data = zeroExMock . interface . encodeFunctionData ( "sellTokenForEthToUniswapV3" , [
804845 encodePath ( path ) ,
@@ -820,9 +861,28 @@ describe("ZeroExApiAdapter", () => {
820861 } ) ;
821862 }
822863
864+ it ( "permits any destination address when recipient is null" , async ( ) => {
865+ const path = [ sourceToken , wethToken ] ;
866+
867+ const data = zeroExMock . interface . encodeFunctionData ( "sellTokenForEthToUniswapV3" , [
868+ encodePath ( path ) ,
869+ sourceQuantity ,
870+ minDestinationQuantity ,
871+ ADDRESS_ZERO ,
872+ ] ) ;
873+ await zeroExApiAdapter . getTradeCalldata (
874+ sourceToken ,
875+ ETH_ADDRESS ,
876+ destination ,
877+ sourceQuantity ,
878+ minDestinationQuantity ,
879+ data ,
880+ ) ;
881+ } ) ;
882+
823883 it ( "rejects wrong input token" , async ( ) => {
824884 const data = zeroExMock . interface . encodeFunctionData ( "sellTokenForEthToUniswapV3" , [
825- encodePath ( [ otherToken , ETH_ADDRESS ] ) ,
885+ encodePath ( [ otherToken , wethToken ] ) ,
826886 sourceQuantity ,
827887 minDestinationQuantity ,
828888 destination ,
@@ -839,6 +899,24 @@ describe("ZeroExApiAdapter", () => {
839899 } ) ;
840900
841901 it ( "rejects wrong output token" , async ( ) => {
902+ const data = zeroExMock . interface . encodeFunctionData ( "sellTokenForEthToUniswapV3" , [
903+ encodePath ( [ sourceToken , wethToken ] ) ,
904+ sourceQuantity ,
905+ minDestinationQuantity ,
906+ destination ,
907+ ] ) ;
908+ const tx = zeroExApiAdapter . getTradeCalldata (
909+ sourceToken ,
910+ otherToken ,
911+ destination ,
912+ sourceQuantity ,
913+ minDestinationQuantity ,
914+ data ,
915+ ) ;
916+ await expect ( tx ) . to . be . revertedWith ( "Mismatched output token" ) ;
917+ } ) ;
918+
919+ it ( "rejects non-WETH output token in encoded path" , async ( ) => {
842920 const data = zeroExMock . interface . encodeFunctionData ( "sellTokenForEthToUniswapV3" , [
843921 encodePath ( [ sourceToken , otherToken ] ) ,
844922 sourceQuantity ,
@@ -853,12 +931,12 @@ describe("ZeroExApiAdapter", () => {
853931 minDestinationQuantity ,
854932 data ,
855933 ) ;
856- await expect ( tx ) . to . be . revertedWith ( "Mismatched output token" ) ;
934+ await expect ( tx ) . to . be . revertedWith ( "Last token must be WETH " ) ;
857935 } ) ;
858936
859937 it ( "rejects wrong input token quantity" , async ( ) => {
860938 const data = zeroExMock . interface . encodeFunctionData ( "sellTokenForEthToUniswapV3" , [
861- encodePath ( [ sourceToken , ETH_ADDRESS ] ) ,
939+ encodePath ( [ sourceToken , wethToken ] ) ,
862940 otherQuantity ,
863941 minDestinationQuantity ,
864942 destination ,
@@ -876,7 +954,7 @@ describe("ZeroExApiAdapter", () => {
876954
877955 it ( "rejects wrong output token quantity" , async ( ) => {
878956 const data = zeroExMock . interface . encodeFunctionData ( "sellTokenForEthToUniswapV3" , [
879- encodePath ( [ sourceToken , ETH_ADDRESS ] ) ,
957+ encodePath ( [ sourceToken , wethToken ] ) ,
880958 sourceQuantity ,
881959 otherQuantity ,
882960 destination ,
@@ -912,15 +990,15 @@ describe("ZeroExApiAdapter", () => {
912990
913991 it ( "rejects wrong destination" , async ( ) => {
914992 const data = zeroExMock . interface . encodeFunctionData ( "sellTokenForEthToUniswapV3" , [
915- encodePath ( [ sourceToken , ETH_ADDRESS ] ) ,
993+ encodePath ( [ sourceToken , wethToken ] ) ,
916994 sourceQuantity ,
917995 minDestinationQuantity ,
918- ADDRESS_ZERO ,
996+ destination ,
919997 ] ) ;
920998 const tx = zeroExApiAdapter . getTradeCalldata (
921999 sourceToken ,
9221000 ETH_ADDRESS ,
923- destination ,
1001+ otherDestination ,
9241002 sourceQuantity ,
9251003 minDestinationQuantity ,
9261004 data ,
@@ -934,7 +1012,7 @@ describe("ZeroExApiAdapter", () => {
9341012 for ( let i = 0 ; i <= additionalHops . length ; i ++ ) {
9351013 const hops = take ( additionalHops , i ) ;
9361014 it ( `validates data for ${ i + 1 } hops` , async ( ) => {
937- const path = [ ETH_ADDRESS , ...hops , destToken ] ;
1015+ const path = [ wethToken , ...hops , destToken ] ;
9381016
9391017 const data = zeroExMock . interface . encodeFunctionData ( "sellEthForTokenToUniswapV3" , [
9401018 encodePath ( path ) ,
@@ -955,9 +1033,44 @@ describe("ZeroExApiAdapter", () => {
9551033 } ) ;
9561034 }
9571035
1036+ it ( "permits any destination address when recipient is null" , async ( ) => {
1037+ const path = [ wethToken , destToken ] ;
1038+
1039+ const data = zeroExMock . interface . encodeFunctionData ( "sellEthForTokenToUniswapV3" , [
1040+ encodePath ( path ) ,
1041+ minDestinationQuantity ,
1042+ ADDRESS_ZERO ,
1043+ ] ) ;
1044+ await zeroExApiAdapter . getTradeCalldata (
1045+ ETH_ADDRESS ,
1046+ destToken ,
1047+ destination ,
1048+ sourceQuantity ,
1049+ minDestinationQuantity ,
1050+ data ,
1051+ ) ;
1052+ } ) ;
1053+
1054+ it ( "rejects non-WETH input token in encoded path" , async ( ) => {
1055+ const data = zeroExMock . interface . encodeFunctionData ( "sellEthForTokenToUniswapV3" , [
1056+ encodePath ( [ otherToken , destToken ] ) ,
1057+ minDestinationQuantity ,
1058+ destination ,
1059+ ] ) ;
1060+ const tx = zeroExApiAdapter . getTradeCalldata (
1061+ ETH_ADDRESS ,
1062+ destToken ,
1063+ destination ,
1064+ sourceQuantity ,
1065+ minDestinationQuantity ,
1066+ data ,
1067+ ) ;
1068+ await expect ( tx ) . to . be . revertedWith ( "First token must be WETH" ) ;
1069+ } ) ;
1070+
9581071 it ( "rejects wrong input token" , async ( ) => {
9591072 const data = zeroExMock . interface . encodeFunctionData ( "sellEthForTokenToUniswapV3" , [
960- encodePath ( [ ETH_ADDRESS , destToken ] ) ,
1073+ encodePath ( [ wethToken , destToken ] ) ,
9611074 minDestinationQuantity ,
9621075 destination ,
9631076 ] ) ;
@@ -974,7 +1087,7 @@ describe("ZeroExApiAdapter", () => {
9741087
9751088 it ( "rejects wrong output token" , async ( ) => {
9761089 const data = zeroExMock . interface . encodeFunctionData ( "sellEthForTokenToUniswapV3" , [
977- encodePath ( [ ETH_ADDRESS , otherToken ] ) ,
1090+ encodePath ( [ wethToken , otherToken ] ) ,
9781091 minDestinationQuantity ,
9791092 destination ,
9801093 ] ) ;
@@ -991,7 +1104,7 @@ describe("ZeroExApiAdapter", () => {
9911104
9921105 it ( "rejects wrong output token quantity" , async ( ) => {
9931106 const data = zeroExMock . interface . encodeFunctionData ( "sellEthForTokenToUniswapV3" , [
994- encodePath ( [ ETH_ADDRESS , destToken ] ) ,
1107+ encodePath ( [ wethToken , destToken ] ) ,
9951108 otherQuantity ,
9961109 destination ,
9971110 ] ) ;
@@ -1008,7 +1121,7 @@ describe("ZeroExApiAdapter", () => {
10081121
10091122 it ( "rejects invalid uniswap path" , async ( ) => {
10101123 const data = zeroExMock . interface . encodeFunctionData ( "sellEthForTokenToUniswapV3" , [
1011- encodePath ( [ ETH_ADDRESS ] ) ,
1124+ encodePath ( [ wethToken ] ) ,
10121125 minDestinationQuantity ,
10131126 destination ,
10141127 ] ) ;
@@ -1025,14 +1138,14 @@ describe("ZeroExApiAdapter", () => {
10251138
10261139 it ( "rejects wrong destination" , async ( ) => {
10271140 const data = zeroExMock . interface . encodeFunctionData ( "sellEthForTokenToUniswapV3" , [
1028- encodePath ( [ ETH_ADDRESS , destToken ] ) ,
1141+ encodePath ( [ wethToken , destToken ] ) ,
10291142 minDestinationQuantity ,
1030- ADDRESS_ZERO ,
1143+ destination ,
10311144 ] ) ;
10321145 const tx = zeroExApiAdapter . getTradeCalldata (
10331146 ETH_ADDRESS ,
10341147 destToken ,
1035- destination ,
1148+ otherDestination ,
10361149 sourceQuantity ,
10371150 minDestinationQuantity ,
10381151 data ,
0 commit comments