github.com/status-im/status-go@v1.1.0/services/wallet/router/pathprocessor/processor_swap_paraswap_test.go (about) 1 package pathprocessor 2 3 import ( 4 "errors" 5 "math/big" 6 "testing" 7 8 "github.com/ethereum/go-ethereum/common" 9 10 gomock "github.com/golang/mock/gomock" 11 12 "github.com/status-im/status-go/params" 13 "github.com/status-im/status-go/services/wallet/bigint" 14 walletCommon "github.com/status-im/status-go/services/wallet/common" 15 "github.com/status-im/status-go/services/wallet/thirdparty/paraswap" 16 mock_paraswap "github.com/status-im/status-go/services/wallet/thirdparty/paraswap/mock" 17 "github.com/status-im/status-go/services/wallet/token" 18 19 "github.com/stretchr/testify/require" 20 ) 21 22 func TestParaswapWithPartnerFee(t *testing.T) { 23 testPriceRoute := ¶swap.Route{ 24 GasCost: &bigint.BigInt{Int: big.NewInt(500)}, 25 SrcAmount: &bigint.BigInt{Int: big.NewInt(1000)}, 26 SrcTokenAddress: common.HexToAddress("0x123"), 27 SrcTokenDecimals: 18, 28 DestAmount: &bigint.BigInt{Int: big.NewInt(2000)}, 29 DestTokenAddress: common.HexToAddress("0x465"), 30 DestTokenDecimals: 6, 31 Side: paraswap.SellSide, 32 ContractAddress: common.HexToAddress("0x789"), 33 TokenTransferProxy: common.HexToAddress("0xabc"), 34 } 35 36 processor := NewSwapParaswapProcessor(nil, nil, nil) 37 38 fromToken := token.Token{ 39 Symbol: EthSymbol, 40 } 41 toToken := token.Token{ 42 Symbol: UsdcSymbol, 43 } 44 chainIDs := []uint64{walletCommon.EthereumMainnet, walletCommon.ArbitrumMainnet, walletCommon.OptimismMainnet, walletCommon.UnknownChainID} 45 46 for _, chainID := range chainIDs { 47 key := makeKey(chainID, chainID, fromToken.Symbol, toToken.Symbol) 48 processor.priceRoute.Store(key, testPriceRoute) 49 50 testInputParams := ProcessorInputParams{ 51 FromChain: ¶ms.Network{ChainID: chainID}, 52 ToChain: ¶ms.Network{ChainID: chainID}, 53 FromToken: &fromToken, 54 ToToken: &toToken, 55 } 56 57 partnerAddress, partnerFeePcnt := getPartnerAddressAndFeePcnt(chainID) 58 59 if partnerAddress != walletCommon.ZeroAddress { 60 require.Greater(t, partnerFeePcnt, 0.0) 61 62 expectedFee := uint64(float64(testPriceRoute.DestAmount.Uint64()) * partnerFeePcnt / 100.0) 63 expectedDestAmount := testPriceRoute.DestAmount.Uint64() - expectedFee 64 65 amountOut, err := processor.CalculateAmountOut(testInputParams) 66 require.NoError(t, err) 67 require.NotNil(t, amountOut) 68 require.InEpsilon(t, expectedDestAmount, amountOut.Uint64(), 2.0) 69 } else { 70 require.Equal(t, 0.0, partnerFeePcnt) 71 72 amountOut, err := processor.CalculateAmountOut(testInputParams) 73 require.NoError(t, err) 74 require.NotNil(t, amountOut) 75 require.Equal(t, testPriceRoute.DestAmount.Uint64(), amountOut.Uint64()) 76 } 77 78 // Check contract address 79 contractAddress, err := processor.GetContractAddress(testInputParams) 80 require.NoError(t, err) 81 require.Equal(t, testPriceRoute.TokenTransferProxy, contractAddress) 82 } 83 } 84 85 func expectClientFetchPriceRoute(clientMock *mock_paraswap.MockClientInterface, route paraswap.Route, err error) { 86 clientMock.EXPECT().FetchPriceRoute( 87 gomock.Any(), 88 gomock.Any(), 89 gomock.Any(), 90 gomock.Any(), 91 gomock.Any(), 92 gomock.Any(), 93 gomock.Any(), 94 gomock.Any(), 95 gomock.Any(), 96 ).Return(route, err) 97 } 98 99 func TestParaswapErrors(t *testing.T) { 100 ctrl := gomock.NewController(t) 101 defer ctrl.Finish() 102 103 client := mock_paraswap.NewMockClientInterface(ctrl) 104 105 processor := NewSwapParaswapProcessor(nil, nil, nil) 106 processor.paraswapClient = client 107 108 fromToken := token.Token{ 109 Symbol: EthSymbol, 110 } 111 toToken := token.Token{ 112 Symbol: UsdcSymbol, 113 } 114 chainID := walletCommon.EthereumMainnet 115 116 testInputParams := ProcessorInputParams{ 117 FromChain: ¶ms.Network{ChainID: chainID}, 118 ToChain: ¶ms.Network{ChainID: chainID}, 119 FromToken: &fromToken, 120 ToToken: &toToken, 121 } 122 123 // Test Errors 124 type testCase struct { 125 clientError string 126 processorError error 127 } 128 129 testCases := []testCase{ 130 {"Price Timeout", ErrPriceTimeout}, 131 {"No routes found with enough liquidity", ErrNotEnoughLiquidity}, 132 {"ESTIMATED_LOSS_GREATER_THAN_MAX_IMPACT", ErrPriceImpactTooHigh}, 133 } 134 135 for _, tc := range testCases { 136 expectClientFetchPriceRoute(client, paraswap.Route{}, errors.New(tc.clientError)) 137 _, err := processor.EstimateGas(testInputParams) 138 require.Equal(t, tc.processorError.Error(), err.Error()) 139 } 140 }