@@ -6,7 +6,13 @@ import { TradingSdk, TradeParameters } from '@cowprotocol/sdk-trading'
66import { createAdapters , TEST_ADDRESS } from '../../tests/setup'
77
88import { AaveCollateralSwapSdk } from './AaveCollateralSwapSdk'
9- import { AAVE_ADAPTER_FACTORY , ADAPTER_DOMAIN_NAME , HASH_ZERO } from './const'
9+ import {
10+ AAVE_ADAPTER_FACTORY ,
11+ ADAPTER_DOMAIN_NAME ,
12+ AAVE_HOOK_ADAPTER_PER_TYPE ,
13+ AaveFlashLoanType ,
14+ HASH_ZERO ,
15+ } from './const'
1016
1117const adapters = createAdapters ( )
1218const adapterNames = Object . keys ( adapters ) as Array < keyof typeof adapters >
@@ -755,5 +761,195 @@ adapterNames.forEach((adapterName) => {
755761 expect ( signature ) . toContain ( '0x' )
756762 } )
757763 } )
764+
765+ describe ( 'constructor configuration' , ( ) => {
766+ beforeEach ( ( ) => {
767+ // Clear any existing mocks before each test
768+ jest . clearAllMocks ( )
769+ } )
770+
771+ const setupReadContractMock = ( ) => {
772+ return jest . spyOn ( adapter , 'readContract' ) . mockImplementation ( ( ...args : any [ ] ) => {
773+ const params = args [ 0 ]
774+ if ( params . functionName === 'getInstanceDeterministicAddress' ) {
775+ return Promise . resolve ( '0x1234567890123456789012345678901234567890' as any )
776+ }
777+ if ( params . functionName === 'allowance' ) {
778+ return Promise . resolve ( BigInt ( 0 ) as any )
779+ }
780+ return Promise . resolve ( '0x0000000000000000000000000000000000000000' as any )
781+ } )
782+ }
783+
784+ test ( 'should use default hook adapter addresses when no config provided' , async ( ) => {
785+ const defaultSdk = new AaveCollateralSwapSdk ( )
786+ const readContractSpy = setupReadContractMock ( )
787+
788+ await defaultSdk . collateralSwap (
789+ {
790+ chainId : SupportedChainId . GNOSIS_CHAIN ,
791+ tradeParameters : mockTradeParameters ,
792+ collateralToken,
793+ } ,
794+ mockTradingSdk ,
795+ )
796+
797+ // Verify that the default address was used
798+ const readContractCalls = readContractSpy . mock . calls
799+ const getInstanceCall = readContractCalls . find (
800+ ( call ) => call [ 0 ] ?. functionName === 'getInstanceDeterministicAddress' ,
801+ )
802+
803+ expect ( getInstanceCall ) . toBeDefined ( )
804+ expect ( getInstanceCall ?. [ 0 ] ?. args ?. [ 0 ] ) . toBe (
805+ AAVE_HOOK_ADAPTER_PER_TYPE [ AaveFlashLoanType . CollateralSwap ] [ SupportedChainId . GNOSIS_CHAIN ] ,
806+ )
807+ } )
808+
809+ test ( 'should use custom hook adapter addresses when provided' , async ( ) => {
810+ const customHookAdapterAddress = '0x1234567890123456789012345678901234567890'
811+ const customConfig = {
812+ hookAdapterPerType : {
813+ ...AAVE_HOOK_ADAPTER_PER_TYPE ,
814+ [ AaveFlashLoanType . CollateralSwap ] : {
815+ ...AAVE_HOOK_ADAPTER_PER_TYPE [ AaveFlashLoanType . CollateralSwap ] ,
816+ [ SupportedChainId . GNOSIS_CHAIN ] : customHookAdapterAddress ,
817+ } ,
818+ } ,
819+ }
820+
821+ const customSdk = new AaveCollateralSwapSdk ( customConfig )
822+ const readContractSpy = setupReadContractMock ( )
823+
824+ await customSdk . collateralSwap (
825+ {
826+ chainId : SupportedChainId . GNOSIS_CHAIN ,
827+ tradeParameters : mockTradeParameters ,
828+ collateralToken,
829+ } ,
830+ mockTradingSdk ,
831+ )
832+
833+ // Verify that the custom address was used in getInstanceDeterministicAddress
834+ const readContractCalls = readContractSpy . mock . calls
835+ const getInstanceCall = readContractCalls . find (
836+ ( call ) => call [ 0 ] ?. functionName === 'getInstanceDeterministicAddress' ,
837+ )
838+
839+ expect ( getInstanceCall ) . toBeDefined ( )
840+ expect ( getInstanceCall ?. [ 0 ] ?. args ?. [ 0 ] ) . toBe ( customHookAdapterAddress )
841+
842+ // Verify that the custom address is used in the pre-hook call data
843+ const swapSettingsCall = ( mockPostSwapOrderFromQuote as jest . Mock ) . mock . calls [ 0 ] [ 0 ]
844+ const preHookCallData = swapSettingsCall . appData . metadata . hooks . pre [ 0 ] . callData
845+
846+ // The call data should contain the custom adapter address
847+ // We can verify this by checking if the encoded function includes the custom address
848+ expect ( preHookCallData ) . toBeDefined ( )
849+ expect ( typeof preHookCallData ) . toBe ( 'string' )
850+ // The call data should be a hex string that includes the custom address (without 0x prefix)
851+ const customAddressWithoutPrefix = customHookAdapterAddress . toLowerCase ( ) . slice ( 2 )
852+ expect ( preHookCallData . toLowerCase ( ) ) . toContain ( customAddressWithoutPrefix )
853+ } )
854+
855+ test ( 'should use custom hook adapter addresses for different flash loan types' , async ( ) => {
856+ const customCollateralSwapAddress = '0x1111111111111111111111111111111111111111'
857+ const customDebtSwapAddress = '0x2222222222222222222222222222222222222222'
858+ const customRepayAddress = '0x3333333333333333333333333333333333333333'
859+
860+ const customConfig = {
861+ hookAdapterPerType : {
862+ [ AaveFlashLoanType . CollateralSwap ] : {
863+ ...AAVE_HOOK_ADAPTER_PER_TYPE [ AaveFlashLoanType . CollateralSwap ] ,
864+ [ SupportedChainId . GNOSIS_CHAIN ] : customCollateralSwapAddress ,
865+ } ,
866+ [ AaveFlashLoanType . DebtSwap ] : {
867+ ...AAVE_HOOK_ADAPTER_PER_TYPE [ AaveFlashLoanType . DebtSwap ] ,
868+ [ SupportedChainId . GNOSIS_CHAIN ] : customDebtSwapAddress ,
869+ } ,
870+ [ AaveFlashLoanType . RepayCollateral ] : {
871+ ...AAVE_HOOK_ADAPTER_PER_TYPE [ AaveFlashLoanType . RepayCollateral ] ,
872+ [ SupportedChainId . GNOSIS_CHAIN ] : customRepayAddress ,
873+ } ,
874+ } ,
875+ }
876+
877+ const customSdk = new AaveCollateralSwapSdk ( customConfig )
878+ const readContractSpy = setupReadContractMock ( )
879+
880+ await customSdk . collateralSwap (
881+ {
882+ chainId : SupportedChainId . GNOSIS_CHAIN ,
883+ tradeParameters : mockTradeParameters ,
884+ collateralToken,
885+ } ,
886+ mockTradingSdk ,
887+ )
888+
889+ // Verify that the custom CollateralSwap address was used
890+ const readContractCalls = readContractSpy . mock . calls
891+ const getInstanceCall = readContractCalls . find (
892+ ( call ) => call [ 0 ] ?. functionName === 'getInstanceDeterministicAddress' ,
893+ )
894+
895+ expect ( getInstanceCall ) . toBeDefined ( )
896+ expect ( getInstanceCall ?. [ 0 ] ?. args ?. [ 0 ] ) . toBe ( customCollateralSwapAddress )
897+ } )
898+
899+ test ( 'should use custom hook adapter addresses for different chains' , async ( ) => {
900+ const customGnosisAddress = '0x4444444444444444444444444444444444444444'
901+ const customMainnetAddress = '0x5555555555555555555555555555555555555555'
902+
903+ const customConfig = {
904+ hookAdapterPerType : {
905+ ...AAVE_HOOK_ADAPTER_PER_TYPE ,
906+ [ AaveFlashLoanType . CollateralSwap ] : {
907+ ...AAVE_HOOK_ADAPTER_PER_TYPE [ AaveFlashLoanType . CollateralSwap ] ,
908+ [ SupportedChainId . GNOSIS_CHAIN ] : customGnosisAddress ,
909+ [ SupportedChainId . MAINNET ] : customMainnetAddress ,
910+ } ,
911+ } ,
912+ }
913+
914+ const customSdk = new AaveCollateralSwapSdk ( customConfig )
915+ const readContractSpy = setupReadContractMock ( )
916+
917+ // Test with Gnosis Chain
918+ await customSdk . collateralSwap (
919+ {
920+ chainId : SupportedChainId . GNOSIS_CHAIN ,
921+ tradeParameters : mockTradeParameters ,
922+ collateralToken,
923+ } ,
924+ mockTradingSdk ,
925+ )
926+
927+ let readContractCalls = readContractSpy . mock . calls
928+ let getInstanceCall = readContractCalls . find (
929+ ( call ) => call [ 0 ] ?. functionName === 'getInstanceDeterministicAddress' ,
930+ )
931+
932+ expect ( getInstanceCall ?. [ 0 ] ?. args ?. [ 0 ] ) . toBe ( customGnosisAddress )
933+
934+ // Reset mocks
935+ readContractSpy . mockClear ( )
936+ mockPostSwapOrderFromQuote . mockClear ( )
937+
938+ // Test with Mainnet
939+ await customSdk . collateralSwap (
940+ {
941+ chainId : SupportedChainId . MAINNET ,
942+ tradeParameters : mockTradeParameters ,
943+ collateralToken,
944+ } ,
945+ mockTradingSdk ,
946+ )
947+
948+ readContractCalls = readContractSpy . mock . calls
949+ getInstanceCall = readContractCalls . find ( ( call ) => call [ 0 ] ?. functionName === 'getInstanceDeterministicAddress' )
950+
951+ expect ( getInstanceCall ?. [ 0 ] ?. args ?. [ 0 ] ) . toBe ( customMainnetAddress )
952+ } )
953+ } )
758954 } )
759955} )
0 commit comments