Skip to content

Commit 13a4365

Browse files
committed
Fix cowswap orders
- Use new quote endpoint to get fees
1 parent aeacce3 commit 13a4365

File tree

2 files changed

+59
-30
lines changed

2 files changed

+59
-30
lines changed

gnosis/protocol/gnosis_protocol_api.py

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -77,27 +77,34 @@ def weth_address(self) -> ChecksumAddress:
7777
else: # XDAI
7878
return ChecksumAddress("0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1")
7979

80-
def get_fee(self, order: Order) -> int:
81-
if order.is_sell_order():
82-
amount = order.sellAmount
83-
else:
84-
amount = order.buyAmount
85-
url = (
86-
self.base_url
87-
+ f"fee/?sellToken={order.sellToken}&buyToken={order.buyToken}"
88-
f"&amount={amount}&kind={order.kind}"
89-
)
90-
result = self.http_session.get(url).json()
91-
if "amount" in result:
92-
return int(result["amount"])
80+
def get_fee(self, order: Order, from_address: ChecksumAddress) -> int:
81+
url = self.base_url + "quote"
82+
data_json = {
83+
"sellToken": order.sellToken.lower(),
84+
"buyToken": order.buyToken.lower(),
85+
"sellAmountBeforeFee": str(order.sellAmount),
86+
"validTo": order.validTo,
87+
"appData": HexBytes(order.appData).hex()
88+
if isinstance(order.appData, bytes)
89+
else order.appData,
90+
"feeAmount": str(order.feeAmount),
91+
"kind": order.kind,
92+
"partiallyFillable": order.partiallyFillable,
93+
"signingScheme": "ethsign",
94+
"from": from_address,
95+
"priceQuality": "fast",
96+
}
97+
r = self.http_session.post(url, json=data_json)
98+
if r.ok:
99+
return int(r.json()["quote"]["feeAmount"])
93100
else:
94-
return 0
101+
return ErrorResponse(r.json())
95102

96103
def place_order(
97104
self, order: Order, private_key: HexStr
98105
) -> Union[HexStr, ErrorResponse]:
99106
"""
100-
Place order. If `feeAmount=0` in Order it will be calculated calling `get_fee(order)`
107+
Place order. If `feeAmount=0` in Order it will be calculated calling `get_fee(order, from_address)`
101108
102109
:return: UUID for the order as an hex hash
103110
"""
@@ -106,7 +113,13 @@ def place_order(
106113
), "Order buyAmount and sellAmount cannot be empty"
107114

108115
url = self.base_url + "orders/"
109-
order.feeAmount = order.feeAmount or self.get_fee(order)
116+
from_address = Account.from_key(private_key).address
117+
if not order.feeAmount:
118+
fee_amount = self.get_fee(order, from_address)
119+
if "errorType" in fee_amount: # ErrorResponse
120+
return fee_amount
121+
order.feeAmount = fee_amount
122+
110123
signable_hash = eip712_encode_hash(
111124
order.get_eip712_structured_data(
112125
self.network.value, self.settlement_contract_address
@@ -129,7 +142,7 @@ def place_order(
129142
"partiallyFillable": order.partiallyFillable,
130143
"signature": signed_message.signature.hex(),
131144
"signingScheme": "ethsign",
132-
"from": Account.from_key(private_key).address,
145+
"from": from_address,
133146
}
134147
r = self.http_session.post(url, json=data_json)
135148
if r.ok:

gnosis/protocol/tests/test_gnosis_protocol_api.py

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ def setUpClass(cls):
1717
super().setUpClass()
1818
cls.mainnet_gnosis_protocol_api = GnosisProtocolAPI(EthereumNetwork.MAINNET)
1919
cls.goerli_gnosis_protocol_api = GnosisProtocolAPI(EthereumNetwork.GOERLI)
20-
cls.gno_token_address = "0x6810e776880C02933D47DB1b9fc05908e5386b96"
21-
cls.weth_token_address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
22-
cls.rinkeby_dai_address = "0x5592EC0cfb4dbc12D3aB100b257153436a1f0FEa"
20+
cls.mainnet_gno_token_address = "0x6810e776880C02933D47DB1b9fc05908e5386b96"
21+
cls.goerli_cow_token_address = "0x3430d04E42a722c5Ae52C5Bffbf1F230C2677600"
2322

2423
def test_api_is_available(self):
2524
random_owner = Account.create().address
@@ -36,7 +35,10 @@ def test_api_is_available(self):
3635
def test_get_estimated_amount(self):
3736
gnosis_protocol_api = GnosisProtocolAPI(EthereumNetwork.MAINNET)
3837
response = gnosis_protocol_api.get_estimated_amount(
39-
self.gno_token_address, self.gno_token_address, OrderKind.SELL, 1
38+
self.mainnet_gno_token_address,
39+
self.mainnet_gno_token_address,
40+
OrderKind.SELL,
41+
1,
4042
)
4143
self.assertDictEqual(
4244
response,
@@ -48,26 +50,29 @@ def test_get_estimated_amount(self):
4850

4951
response = gnosis_protocol_api.get_estimated_amount(
5052
"0x6820e776880c02933d47db1b9fc05908e5386b96",
51-
self.gno_token_address,
53+
self.mainnet_gno_token_address,
5254
OrderKind.SELL,
5355
1,
5456
)
5557
self.assertIn("errorType", response)
5658
self.assertIn("description", response)
5759

5860
response = gnosis_protocol_api.get_estimated_amount(
59-
self.gno_token_address, self.weth_token_address, OrderKind.SELL, int(1e18)
61+
self.mainnet_gno_token_address,
62+
self.mainnet_gnosis_protocol_api.weth_address,
63+
OrderKind.SELL,
64+
int(1e18),
6065
)
6166
amount = int(response["amount"]) / 1e18
6267
self.assertGreater(amount, 0)
6368
self.assertLess(amount, 1)
6469

6570
def test_get_fee(self):
6671
order = Order(
67-
sellToken=self.gno_token_address,
68-
buyToken=self.gno_token_address,
72+
sellToken=self.mainnet_gno_token_address,
73+
buyToken=self.mainnet_gno_token_address,
6974
receiver=NULL_ADDRESS,
70-
sellAmount=1,
75+
sellAmount=int(1e18),
7176
buyAmount=1,
7277
validTo=int(time()) + 3600,
7378
appData=Web3.keccak(text="hola"),
@@ -77,7 +82,18 @@ def test_get_fee(self):
7782
sellTokenBalance="erc20",
7883
buyTokenBalance="erc20",
7984
)
80-
self.assertGreaterEqual(self.goerli_gnosis_protocol_api.get_fee(order), 0)
85+
from_address = Account.create().address
86+
self.assertEqual(
87+
self.mainnet_gnosis_protocol_api.get_fee(order, from_address),
88+
{
89+
"errorType": "SameBuyAndSellToken",
90+
"description": "Buy token is the same as the sell token.",
91+
},
92+
)
93+
order.buyToken = self.mainnet_gnosis_protocol_api.weth_address
94+
self.assertGreaterEqual(
95+
self.mainnet_gnosis_protocol_api.get_fee(order, from_address), 0
96+
)
8197

8298
def test_get_trades(self):
8399
mainnet_order_ui = "0x65F1206182C77A040ED41D507B59C622FA94AB5E71CCA567202CFF3909F3D5C4DBE338E45276630FD8237149DD47EE027AF26F9C619723D0"
@@ -101,8 +117,8 @@ def test_get_trades(self):
101117

102118
def test_place_order(self):
103119
order = Order(
104-
sellToken=self.gno_token_address,
105-
buyToken=self.gno_token_address,
120+
sellToken=self.mainnet_gno_token_address,
121+
buyToken=self.mainnet_gno_token_address,
106122
receiver=NULL_ADDRESS,
107123
sellAmount=1,
108124
buyAmount=1,
@@ -129,7 +145,7 @@ def test_place_order(self):
129145
)
130146

131147
order.sellToken = self.goerli_gnosis_protocol_api.weth_address
132-
order.buyToken = self.rinkeby_dai_address
148+
order.buyToken = self.goerli_cow_token_address
133149
order_id = self.goerli_gnosis_protocol_api.place_order(
134150
order, Account().create().key
135151
)

0 commit comments

Comments
 (0)