1# This file is part of the KEEPKEY project.
2#
3# Copyright (C) 2021 Shapeshift
4#
5# This library is free software: you can redistribute it and/or modify
6# it under the terms of the GNU Lesser General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# This library is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public License
16# along with this library.  If not, see <http://www.gnu.org/licenses/>.
17
18import unittest
19import common
20import binascii
21import struct
22
23import keepkeylib.messages_pb2 as proto
24import keepkeylib.types_pb2 as proto_types
25import keepkeylib.exchange_pb2 as proto_exchange
26from keepkeylib.client import CallException
27from keepkeylib.tools import int_to_big_endian
28
29class TestMsgEthereumUniswaptxERC20(common.KeepKeyTest):
30
31    def test_sign_uni_approve_liquidity_ETH(self):
32        self.requires_firmware("7.1.0")
33        self.setup_mnemonic_nopin_nopassphrase()
34
35        # Approval tx for the ETH/FOX pool
36        sig_v, sig_r, sig_s = self.client.ethereum_sign_tx(
37            n=[2147483692,2147483708,2147483648,0,0],
38            nonce=0xf,
39            gas_price=0x2980872680,
40            gas_limit=0xbd0e,
41            value=0x0,
42            to=binascii.unhexlify('470e8de2ebaef52014a47cb5e6af86884947f08c'),     # fox pool
43            address_type=0,
44            chain_id=1,
45            # The data below is generally broken into 32-byte chunks except for the function selector (4 bytes_ and
46            # keccak signatures (4 bytes)
47            data=binascii.unhexlify('095ea7b3' +                                      # approve
48                '0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d' +  # uniswap v2: router 2 contract address
49                'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')   # approve amount
50
51        )
52        self.assertEqual(sig_v, 38)
53        self.assertEqual(binascii.hexlify(sig_r), '7f7a5ce501371a01ead394d2186385742d5fbdc3d85da98249d2a05043ac6d5a')
54        self.assertEqual(binascii.hexlify(sig_s), '329954b284ed1df9a6242820e793b9719c0c6c21cae5f90190ce61c7f73c731e')
55
56    def test_sign_uni_add_liquidity_ETH(self):
57        if self.client.features.firmware_variant == "Emulator":
58            self.skipTest("Skip until emulator issue resolved")
59            return
60        self.requires_firmware("7.1.0")
61        self.setup_mnemonic_nopin_nopassphrase()
62
63        # Add liquidity to ETH/FOX pool
64        sig_v, sig_r, sig_s = self.client.ethereum_sign_tx(
65            n=[2147483692,2147483708,2147483648,0,0],
66            nonce=0xf,
67            gas_price=0x25d5c13900,
68            gas_limit=0x2b28b,
69            value=0x9d3f71f8b4680,
70            to=binascii.unhexlify('7a250d5630B4cF539739dF2C5dAcb4c659F2488D'),     # UNISWAP router
71            address_type=0,
72            chain_id=1,
73            # The data below is generally broken into 32-byte chunks except for the function selector (4 bytes_ and
74            # keccak signatures (4 bytes)
75            data=binascii.unhexlify('f305d719' +                                      # addLiquidityETH
76                '000000000000000000000000c770eefad204b5180df6a14ee197d99d808ee52d' +  # FOX token
77                '000000000000000000000000000000000000000000000000a688906bd8b00000' +  # amount of fox token
78                '00000000000000000000000000000000000000000000000001aa535d3d0c0000' +  # min amount of fox token
79                '0000000000000000000000000000000000000000000000000000fb98b65aba40' +  # min amount of eth token
80                '0000000000000000000000003f2329C9ADFbcCd9A84f52c906E936A42dA18CB8' +  # eth address (self)
81                '00000000000000000000000000000000000000000000000000000178a9380e5f')   # deadline
82        )
83        self.assertEqual(sig_v, 37)
84        self.assertEqual(binascii.hexlify(sig_r), '8547542bc74c0dcc6ca8b02a79e0dccd336856d8c48376289a2a697d864a5892')
85        self.assertEqual(binascii.hexlify(sig_s), '0a8eec6856aef8caa234240b06862976f8e238e8b24f5c989279507dd7e51ccd')
86
87    def test_sign_uni_remove_liquidity_ETH(self):
88        if self.client.features.firmware_variant == "Emulator":
89            self.skipTest("Skip until emulator issue resolved")
90            return
91        self.requires_firmware("7.1.0")
92        self.setup_mnemonic_nopin_nopassphrase()
93
94        # remove liquidity from the ETH/FOX pool
95        sig_v, sig_r, sig_s = self.client.ethereum_sign_tx(
96            n=[2147483692,2147483708,2147483648,0,0],
97            nonce=0xf,
98            gas_price=0x320313e400,
99            gas_limit=0x3b754,
100            value=0x0,
101            to=binascii.unhexlify('7a250d5630B4cF539739dF2C5dAcb4c659F2488D'),     # UNISWAP router
102            address_type=0,
103            chain_id=1,
104            # The data below is generally broken into 32-byte chunks except for the function selector (4 bytes_ and
105            # keccak signatures (4 bytes)
106            data=binascii.unhexlify('02751cec' +                                      # addLiquidityETH
107                '000000000000000000000000c770eefad204b5180df6a14ee197d99d808ee52d' +  # FOX token
108                '00000000000000000000000000000000000000000000000002684b14a52bcefc' +  # liquidity amount
109                '000000000000000000000000000000000000000000000000010a741a46278000' +  # min amount of fox token
110                '0000000000000000000000000000000000000000000000000000fb04c77f3e94' +  # min amount of eth token
111                '0000000000000000000000005028d647b74f12903e6d5f3969f8f624e6a9a93d' +  # to address (not self)
112                '00000000000000000000000000000000000000000000000000000178b2062f3d')   # deadline
113        )
114        self.assertEqual(sig_v, 37)
115        self.assertEqual(binascii.hexlify(sig_r), '7143f0d8e5505a8cfb1df55e9c5d7433eba33a61959137c08cc5c088ec12ab5d')
116        self.assertEqual(binascii.hexlify(sig_s), '20b456d6c13295f5abb6109d7ade2c5d5fc395963b1e45d92e6dc8c33749c517')
117
118if __name__ == '__main__':
119    unittest.main()
120