afp-sdk 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- afp/__init__.py +10 -0
- afp/api/__init__.py +0 -0
- afp/api/admin.py +55 -0
- afp/api/base.py +76 -0
- afp/api/builder.py +201 -0
- afp/api/clearing.py +377 -0
- afp/api/liquidation.py +167 -0
- afp/api/trading.py +342 -0
- afp/bindings/__init__.py +48 -0
- afp/bindings/auctioneer_facet.py +758 -0
- afp/bindings/bankruptcy_facet.py +355 -0
- afp/bindings/clearing_facet.py +1019 -0
- afp/bindings/erc20.py +379 -0
- afp/bindings/facade.py +87 -0
- afp/bindings/final_settlement_facet.py +268 -0
- afp/bindings/margin_account.py +1355 -0
- afp/bindings/margin_account_registry.py +617 -0
- afp/bindings/mark_price_tracker_facet.py +111 -0
- afp/bindings/oracle_provider.py +539 -0
- afp/bindings/product_registry.py +1302 -0
- afp/bindings/trading_protocol.py +1181 -0
- afp/config.py +38 -0
- afp/decorators.py +74 -0
- afp/enums.py +27 -0
- afp/exceptions.py +26 -0
- afp/exchange.py +151 -0
- afp/py.typed +0 -0
- afp/schemas.py +207 -0
- afp/signing.py +69 -0
- afp/validators.py +43 -0
- afp_sdk-0.1.0.dist-info/METADATA +180 -0
- afp_sdk-0.1.0.dist-info/RECORD +34 -0
- afp_sdk-0.1.0.dist-info/WHEEL +4 -0
- afp_sdk-0.1.0.dist-info/licenses/LICENSE +21 -0
afp/api/clearing.py
ADDED
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
from functools import cache
|
|
3
|
+
|
|
4
|
+
from eth_typing.evm import ChecksumAddress
|
|
5
|
+
from hexbytes import HexBytes
|
|
6
|
+
from web3 import Web3
|
|
7
|
+
from web3.exceptions import ContractCustomError
|
|
8
|
+
|
|
9
|
+
from .. import validators
|
|
10
|
+
from ..bindings import (
|
|
11
|
+
ClearingDiamond,
|
|
12
|
+
MarginAccount,
|
|
13
|
+
MarginAccountRegistry,
|
|
14
|
+
ProductRegistry,
|
|
15
|
+
)
|
|
16
|
+
from ..bindings.erc20 import ERC20
|
|
17
|
+
from ..bindings.facade import CLEARING_DIAMOND_ABI
|
|
18
|
+
from ..bindings.margin_account import ABI as MARGIN_CONTRACT_ABI
|
|
19
|
+
from ..bindings.margin_account_registry import ABI as MARGIN_ACCOUNT_REGISTRY_ABI
|
|
20
|
+
from ..bindings.product_registry import ABI as PRODUCT_REGISTRY_ABI
|
|
21
|
+
from ..decorators import convert_web3_error
|
|
22
|
+
from ..exceptions import NotFoundError
|
|
23
|
+
from ..schemas import Position
|
|
24
|
+
from .base import ClearingSystemAPI
|
|
25
|
+
from .builder import Builder
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Clearing(ClearingSystemAPI):
|
|
29
|
+
"""API for managing margin accounts.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
private_key : str
|
|
34
|
+
The private key of the blockchain account that manages the margin account.
|
|
35
|
+
autonity_rpc_url : str
|
|
36
|
+
The URL of a JSON-RPC provider for Autonity. (HTTPS only.)
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
### Transactions ###
|
|
40
|
+
|
|
41
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
42
|
+
def authorize(self, collateral_asset: str, intent_account_id: str) -> str:
|
|
43
|
+
"""Authorizes a blockchain account to submit intents to the clearing system
|
|
44
|
+
using the margin account associated with the collateral asset.
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
collateral_asset : str
|
|
49
|
+
The address of the collateral token.
|
|
50
|
+
intent_account_id : str
|
|
51
|
+
The address of the intent account.
|
|
52
|
+
|
|
53
|
+
Returns
|
|
54
|
+
-------
|
|
55
|
+
str
|
|
56
|
+
The hash of the transaction.
|
|
57
|
+
"""
|
|
58
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
59
|
+
intent_account_id = validators.validate_address(intent_account_id)
|
|
60
|
+
|
|
61
|
+
tx_hash = (
|
|
62
|
+
self._margin_contract(collateral_asset)
|
|
63
|
+
.authorize(intent_account_id)
|
|
64
|
+
.transact()
|
|
65
|
+
)
|
|
66
|
+
self._w3.eth.wait_for_transaction_receipt(tx_hash)
|
|
67
|
+
return Web3.to_hex(tx_hash)
|
|
68
|
+
|
|
69
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
70
|
+
def deposit_into_margin_account(
|
|
71
|
+
self, collateral_asset: str, amount: Decimal
|
|
72
|
+
) -> tuple[str, str]:
|
|
73
|
+
"""Deposits the specified amount of collateral tokens into the margin account
|
|
74
|
+
associated with the collateral asset.
|
|
75
|
+
|
|
76
|
+
First approves the token transfer with the collateral token, then executes the
|
|
77
|
+
transfer.
|
|
78
|
+
|
|
79
|
+
Parameters
|
|
80
|
+
----------
|
|
81
|
+
collateral_asset : str
|
|
82
|
+
The address of the collateral token.
|
|
83
|
+
amount : Decimal
|
|
84
|
+
The amount of collateral tokens to deposit.
|
|
85
|
+
|
|
86
|
+
Returns
|
|
87
|
+
-------
|
|
88
|
+
str
|
|
89
|
+
The hash of the approval transaction.
|
|
90
|
+
str
|
|
91
|
+
The hash of the deposit transaction.
|
|
92
|
+
"""
|
|
93
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
94
|
+
token_amount = int(amount * 10 ** self._decimals(collateral_asset))
|
|
95
|
+
token_contract = ERC20(self._w3, collateral_asset)
|
|
96
|
+
|
|
97
|
+
tx1_hash = token_contract.approve(
|
|
98
|
+
self._margin_contract(collateral_asset)._contract.address, # type: ignore
|
|
99
|
+
token_amount,
|
|
100
|
+
).transact()
|
|
101
|
+
self._w3.eth.wait_for_transaction_receipt(tx1_hash)
|
|
102
|
+
|
|
103
|
+
tx2_hash = (
|
|
104
|
+
self._margin_contract(collateral_asset).deposit(token_amount).transact()
|
|
105
|
+
)
|
|
106
|
+
self._w3.eth.wait_for_transaction_receipt(tx2_hash)
|
|
107
|
+
|
|
108
|
+
return (Web3.to_hex(tx1_hash), Web3.to_hex(tx2_hash))
|
|
109
|
+
|
|
110
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
111
|
+
def withdraw_from_margin_account(
|
|
112
|
+
self, collateral_asset: str, amount: Decimal
|
|
113
|
+
) -> str:
|
|
114
|
+
"""Withdraws the specified amount of collateral tokens from the margin account
|
|
115
|
+
associated with the collateral asset.
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
collateral_asset : str
|
|
120
|
+
The address of the collateral token.
|
|
121
|
+
amount : Decimal
|
|
122
|
+
The amount of collateral tokens to withdraw.
|
|
123
|
+
|
|
124
|
+
Returns
|
|
125
|
+
-------
|
|
126
|
+
str
|
|
127
|
+
The hash of the transaction.
|
|
128
|
+
"""
|
|
129
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
130
|
+
token_amount = int(amount * 10 ** self._decimals(collateral_asset))
|
|
131
|
+
tx_hash = (
|
|
132
|
+
self._margin_contract(collateral_asset).withdraw(token_amount).transact()
|
|
133
|
+
)
|
|
134
|
+
self._w3.eth.wait_for_transaction_receipt(tx_hash)
|
|
135
|
+
return Web3.to_hex(tx_hash)
|
|
136
|
+
|
|
137
|
+
@convert_web3_error(CLEARING_DIAMOND_ABI)
|
|
138
|
+
def initiate_final_settlement(self, product_id: str, accounts: list[str]) -> str:
|
|
139
|
+
"""Initiate final settlement (closeout) process for the specified accounts.
|
|
140
|
+
|
|
141
|
+
The product must be in Final Settlement state. The accounts must hold non-zero
|
|
142
|
+
positions in the product that offset each other (i.e. the sum of their position
|
|
143
|
+
sizes is 0.)
|
|
144
|
+
|
|
145
|
+
Parameters
|
|
146
|
+
----------
|
|
147
|
+
product_id : str
|
|
148
|
+
The ID of the product.
|
|
149
|
+
accounts : list of str
|
|
150
|
+
List of margin account IDs to initiate settlement for.
|
|
151
|
+
|
|
152
|
+
Returns
|
|
153
|
+
-------
|
|
154
|
+
str
|
|
155
|
+
The hash of the transaction.
|
|
156
|
+
"""
|
|
157
|
+
product_id = validators.validate_hexstr32(product_id)
|
|
158
|
+
addresses = [validators.validate_address(account) for account in accounts]
|
|
159
|
+
|
|
160
|
+
clearing_contract = ClearingDiamond(self._w3)
|
|
161
|
+
tx_hash = clearing_contract.initiate_final_settlement(
|
|
162
|
+
HexBytes(product_id), addresses
|
|
163
|
+
).transact()
|
|
164
|
+
self._w3.eth.wait_for_transaction_receipt(tx_hash)
|
|
165
|
+
return Web3.to_hex(tx_hash)
|
|
166
|
+
|
|
167
|
+
### Views ###
|
|
168
|
+
|
|
169
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
170
|
+
def capital(self, collateral_asset: str) -> Decimal:
|
|
171
|
+
"""Returns the amount of collateral tokens in the margin account associated
|
|
172
|
+
with the collateral asset.
|
|
173
|
+
|
|
174
|
+
Parameters
|
|
175
|
+
----------
|
|
176
|
+
collateral_asset : str
|
|
177
|
+
The address of the collateral token.
|
|
178
|
+
|
|
179
|
+
Returns
|
|
180
|
+
-------
|
|
181
|
+
Decimal
|
|
182
|
+
"""
|
|
183
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
184
|
+
amount = self._margin_contract(collateral_asset).capital(self._account.address)
|
|
185
|
+
return Decimal(amount) / 10 ** self._decimals(collateral_asset)
|
|
186
|
+
|
|
187
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
188
|
+
def position(self, collateral_asset: str, position_id: str) -> Position:
|
|
189
|
+
"""Returns the parameters of a position in the margin account associated with
|
|
190
|
+
the collateral asset.
|
|
191
|
+
|
|
192
|
+
Parameters
|
|
193
|
+
----------
|
|
194
|
+
collateral_asset : str
|
|
195
|
+
The address of the collateral token.
|
|
196
|
+
position_id: str
|
|
197
|
+
The ID of the position.
|
|
198
|
+
|
|
199
|
+
Returns
|
|
200
|
+
-------
|
|
201
|
+
afp.schemas.Position
|
|
202
|
+
"""
|
|
203
|
+
validators.validate_hexstr32(position_id)
|
|
204
|
+
data = self._margin_contract(collateral_asset).position_data(
|
|
205
|
+
self._account.address, HexBytes(position_id)
|
|
206
|
+
)
|
|
207
|
+
decimals = self._decimals(collateral_asset)
|
|
208
|
+
return Position(
|
|
209
|
+
id=Web3.to_hex(data.position_id),
|
|
210
|
+
quantity=data.quantity,
|
|
211
|
+
cost_basis=Decimal(data.cost_basis) / 10**decimals,
|
|
212
|
+
maintenance_margin=Decimal(data.maintenance_margin) / 10**decimals,
|
|
213
|
+
pnl=Decimal(data.pnl) / 10**decimals,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
217
|
+
def positions(self, collateral_asset: str) -> list[Position]:
|
|
218
|
+
"""Returns all positions in the margin account associated with the collateral
|
|
219
|
+
asset.
|
|
220
|
+
|
|
221
|
+
Parameters
|
|
222
|
+
----------
|
|
223
|
+
collateral_asset : str
|
|
224
|
+
The address of the collateral token.
|
|
225
|
+
|
|
226
|
+
Returns
|
|
227
|
+
-------
|
|
228
|
+
list of afp.schemas.Position
|
|
229
|
+
"""
|
|
230
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
231
|
+
position_ids = self._margin_contract(collateral_asset).positions(
|
|
232
|
+
self._account.address
|
|
233
|
+
)
|
|
234
|
+
return [self.position(collateral_asset, Web3.to_hex(id)) for id in position_ids]
|
|
235
|
+
|
|
236
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
237
|
+
def margin_account_equity(self, collateral_asset: str) -> Decimal:
|
|
238
|
+
"""Returns the margin account equity in the margin account associated with the
|
|
239
|
+
collateral asset.
|
|
240
|
+
|
|
241
|
+
Parameters
|
|
242
|
+
----------
|
|
243
|
+
collateral_asset : str
|
|
244
|
+
The address of the collateral token.
|
|
245
|
+
|
|
246
|
+
Returns
|
|
247
|
+
-------
|
|
248
|
+
Decimal
|
|
249
|
+
"""
|
|
250
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
251
|
+
amount = self._margin_contract(collateral_asset).mae(self._account.address)
|
|
252
|
+
return Decimal(amount) / 10 ** self._decimals(collateral_asset)
|
|
253
|
+
|
|
254
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
255
|
+
def maintenance_margin_available(self, collateral_asset: str) -> Decimal:
|
|
256
|
+
"""Returns the maintenance margin available in the margin account associated
|
|
257
|
+
with the collateral asset.
|
|
258
|
+
|
|
259
|
+
Parameters
|
|
260
|
+
----------
|
|
261
|
+
collateral_asset : str
|
|
262
|
+
The address of the collateral token.
|
|
263
|
+
|
|
264
|
+
Returns
|
|
265
|
+
-------
|
|
266
|
+
Decimal
|
|
267
|
+
"""
|
|
268
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
269
|
+
amount = self._margin_contract(collateral_asset).mma(self._account.address)
|
|
270
|
+
return Decimal(amount) / 10 ** self._decimals(collateral_asset)
|
|
271
|
+
|
|
272
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
273
|
+
def maintenance_margin_used(self, collateral_asset: str) -> Decimal:
|
|
274
|
+
"""Returns the maintenance margin used in the margin account associated with
|
|
275
|
+
the collateral asset.
|
|
276
|
+
|
|
277
|
+
Parameters
|
|
278
|
+
----------
|
|
279
|
+
collateral_asset : str
|
|
280
|
+
The address of the collateral token.
|
|
281
|
+
|
|
282
|
+
Returns
|
|
283
|
+
-------
|
|
284
|
+
Decimal
|
|
285
|
+
"""
|
|
286
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
287
|
+
amount = self._margin_contract(collateral_asset).mmu(self._account.address)
|
|
288
|
+
return Decimal(amount) / 10 ** self._decimals(collateral_asset)
|
|
289
|
+
|
|
290
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
291
|
+
def profit_and_loss(self, collateral_asset: str) -> Decimal:
|
|
292
|
+
"""Returns the profit and loss in the margin account associated with the
|
|
293
|
+
collateral asset.
|
|
294
|
+
|
|
295
|
+
Parameters
|
|
296
|
+
----------
|
|
297
|
+
collateral_asset : str
|
|
298
|
+
The address of the collateral token.
|
|
299
|
+
|
|
300
|
+
Returns
|
|
301
|
+
-------
|
|
302
|
+
Decimal
|
|
303
|
+
"""
|
|
304
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
305
|
+
amount = self._margin_contract(collateral_asset).pnl(self._account.address)
|
|
306
|
+
return Decimal(amount) / 10 ** self._decimals(collateral_asset)
|
|
307
|
+
|
|
308
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
309
|
+
def withdrawable_amount(self, collateral_asset: str) -> Decimal:
|
|
310
|
+
"""Returns the amount of collateral tokens withdrawable from the margin account
|
|
311
|
+
associated with the collateral asset.
|
|
312
|
+
|
|
313
|
+
Parameters
|
|
314
|
+
----------
|
|
315
|
+
collateral_asset : str
|
|
316
|
+
The address of the collateral token.
|
|
317
|
+
|
|
318
|
+
Returns
|
|
319
|
+
-------
|
|
320
|
+
Decimal
|
|
321
|
+
"""
|
|
322
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
323
|
+
amount = self._margin_contract(collateral_asset).withdrawable(
|
|
324
|
+
self._account.address
|
|
325
|
+
)
|
|
326
|
+
return Decimal(amount) / 10 ** self._decimals(collateral_asset)
|
|
327
|
+
|
|
328
|
+
@convert_web3_error(PRODUCT_REGISTRY_ABI)
|
|
329
|
+
def collateral_asset(self, product_id: str) -> str:
|
|
330
|
+
"""Returns the collateral asset of a product.
|
|
331
|
+
|
|
332
|
+
Parameters
|
|
333
|
+
----------
|
|
334
|
+
product_id : str
|
|
335
|
+
The ID of the product.
|
|
336
|
+
|
|
337
|
+
Returns
|
|
338
|
+
-------
|
|
339
|
+
str
|
|
340
|
+
"""
|
|
341
|
+
product_registry_contract = ProductRegistry(self._w3)
|
|
342
|
+
collateral_asset = product_registry_contract.collateral_asset(
|
|
343
|
+
HexBytes(product_id)
|
|
344
|
+
)
|
|
345
|
+
if Web3.to_int(hexstr=collateral_asset) == 0:
|
|
346
|
+
raise NotFoundError("Product not found in the product registry")
|
|
347
|
+
return collateral_asset
|
|
348
|
+
|
|
349
|
+
def product_state(self, product_id: str) -> str:
|
|
350
|
+
"""Returns the current state of a product.
|
|
351
|
+
|
|
352
|
+
Parameters
|
|
353
|
+
----------
|
|
354
|
+
product_id : str
|
|
355
|
+
The ID of the product.
|
|
356
|
+
|
|
357
|
+
Returns
|
|
358
|
+
-------
|
|
359
|
+
str
|
|
360
|
+
"""
|
|
361
|
+
return Builder.product_state(self, product_id)
|
|
362
|
+
|
|
363
|
+
### Internal getters ###
|
|
364
|
+
|
|
365
|
+
@cache
|
|
366
|
+
@convert_web3_error(MARGIN_ACCOUNT_REGISTRY_ABI)
|
|
367
|
+
def _margin_contract(self, collateral_asset: ChecksumAddress) -> MarginAccount:
|
|
368
|
+
margin_account_registry_contract = MarginAccountRegistry(self._w3)
|
|
369
|
+
try:
|
|
370
|
+
margin_contract_address = (
|
|
371
|
+
margin_account_registry_contract.get_margin_account(
|
|
372
|
+
Web3.to_checksum_address(collateral_asset)
|
|
373
|
+
)
|
|
374
|
+
)
|
|
375
|
+
except ContractCustomError:
|
|
376
|
+
raise NotFoundError("No margin account found for collateral asset")
|
|
377
|
+
return MarginAccount(self._w3, margin_contract_address)
|
afp/api/liquidation.py
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
from functools import cache
|
|
3
|
+
from typing import Iterable
|
|
4
|
+
|
|
5
|
+
from hexbytes import HexBytes
|
|
6
|
+
from web3 import Web3
|
|
7
|
+
|
|
8
|
+
from .. import validators
|
|
9
|
+
from ..bindings import (
|
|
10
|
+
BidData,
|
|
11
|
+
ClearingDiamond,
|
|
12
|
+
ProductRegistry,
|
|
13
|
+
Side as OnChainOrderSide,
|
|
14
|
+
)
|
|
15
|
+
from ..bindings.facade import CLEARING_DIAMOND_ABI
|
|
16
|
+
from ..bindings.product_registry import ABI as PRODUCT_REGISTRY_ABI
|
|
17
|
+
from ..decorators import convert_web3_error
|
|
18
|
+
from ..enums import OrderSide
|
|
19
|
+
from ..schemas import AuctionData, Bid
|
|
20
|
+
from .base import ClearingSystemAPI
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Liquidation(ClearingSystemAPI):
|
|
24
|
+
"""API for participating in liquidation auctions.
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
private_key : str
|
|
29
|
+
The private key of the blockchain account that participates in a liquidation
|
|
30
|
+
auction.
|
|
31
|
+
autonity_rpc_url : str
|
|
32
|
+
The URL of a JSON-RPC provider for Autonity. (HTTPS only.)
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
def create_bid(product_id: str, price: Decimal, quantity: int, side: str) -> Bid:
|
|
37
|
+
"""Create a bid to be submitted to a liquidation auction.
|
|
38
|
+
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
product_id : str
|
|
42
|
+
price: Decimal
|
|
43
|
+
quantity: int
|
|
44
|
+
side: str
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
afp.schemas.Bid
|
|
49
|
+
"""
|
|
50
|
+
return Bid(
|
|
51
|
+
product_id=product_id,
|
|
52
|
+
price=price,
|
|
53
|
+
quantity=quantity,
|
|
54
|
+
side=getattr(OrderSide, side.upper()),
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
### Transactions ###
|
|
58
|
+
|
|
59
|
+
@convert_web3_error(CLEARING_DIAMOND_ABI)
|
|
60
|
+
def request_liquidation(self, margin_account_id: str, collateral_asset: str) -> str:
|
|
61
|
+
"""Request a liquidation auction to be started.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
margin_account_id : str
|
|
66
|
+
The ID of the margin account to be liquidated.
|
|
67
|
+
collateral_asset : str
|
|
68
|
+
The address of the collateral token that the margin account is trading with.
|
|
69
|
+
|
|
70
|
+
Returns
|
|
71
|
+
-------
|
|
72
|
+
str
|
|
73
|
+
The hash of the transaction.
|
|
74
|
+
"""
|
|
75
|
+
margin_account_id = validators.validate_address(margin_account_id)
|
|
76
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
77
|
+
|
|
78
|
+
clearing_contract = ClearingDiamond(self._w3)
|
|
79
|
+
tx_hash = clearing_contract.request_liquidation(
|
|
80
|
+
margin_account_id, collateral_asset
|
|
81
|
+
).transact()
|
|
82
|
+
self._w3.eth.wait_for_transaction_receipt(tx_hash)
|
|
83
|
+
return Web3.to_hex(tx_hash)
|
|
84
|
+
|
|
85
|
+
@convert_web3_error(CLEARING_DIAMOND_ABI, PRODUCT_REGISTRY_ABI)
|
|
86
|
+
def submit_bids(
|
|
87
|
+
self, margin_account_id: str, collateral_asset: str, bids: Iterable[Bid]
|
|
88
|
+
) -> str:
|
|
89
|
+
"""Submit bids to a liquidation auction.
|
|
90
|
+
|
|
91
|
+
Parameters
|
|
92
|
+
----------
|
|
93
|
+
margin_account_id : str
|
|
94
|
+
The ID of the margin account that is being liquidated.
|
|
95
|
+
collateral_asset : str
|
|
96
|
+
The address of the collateral token that the margin account is trading with.
|
|
97
|
+
bids: list of afp.schemas.Bid
|
|
98
|
+
|
|
99
|
+
Returns
|
|
100
|
+
-------
|
|
101
|
+
str
|
|
102
|
+
The hash of the transaction.
|
|
103
|
+
"""
|
|
104
|
+
margin_account_id = validators.validate_address(margin_account_id)
|
|
105
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
106
|
+
|
|
107
|
+
converted_bids = [
|
|
108
|
+
BidData(
|
|
109
|
+
product_id=HexBytes(bid.product_id),
|
|
110
|
+
price=int(bid.price * 10 ** self._tick_size(bid.product_id)),
|
|
111
|
+
quantity=bid.quantity,
|
|
112
|
+
side=getattr(OnChainOrderSide, bid.side.name),
|
|
113
|
+
)
|
|
114
|
+
for bid in bids
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
clearing_contract = ClearingDiamond(self._w3)
|
|
118
|
+
tx_hash = clearing_contract.bid_auction(
|
|
119
|
+
margin_account_id, collateral_asset, converted_bids
|
|
120
|
+
).transact()
|
|
121
|
+
self._w3.eth.wait_for_transaction_receipt(tx_hash)
|
|
122
|
+
return Web3.to_hex(tx_hash)
|
|
123
|
+
|
|
124
|
+
### Views ###
|
|
125
|
+
|
|
126
|
+
@convert_web3_error(CLEARING_DIAMOND_ABI)
|
|
127
|
+
def auction_data(
|
|
128
|
+
self, margin_account_id: str, collateral_asset: str
|
|
129
|
+
) -> AuctionData:
|
|
130
|
+
"""Returns information on a liquidation auction.
|
|
131
|
+
|
|
132
|
+
Parameters
|
|
133
|
+
----------
|
|
134
|
+
margin_account_id : str
|
|
135
|
+
The ID of the margin account to be liquidated.
|
|
136
|
+
collateral_asset : str
|
|
137
|
+
The address of the collateral token that the margin account is trading with.
|
|
138
|
+
|
|
139
|
+
Returns
|
|
140
|
+
-------
|
|
141
|
+
str
|
|
142
|
+
The hash of the transaction.
|
|
143
|
+
"""
|
|
144
|
+
margin_account_id = validators.validate_address(margin_account_id)
|
|
145
|
+
collateral_asset = validators.validate_address(collateral_asset)
|
|
146
|
+
|
|
147
|
+
clearing_contract = ClearingDiamond(self._w3)
|
|
148
|
+
data = clearing_contract.auction_data(margin_account_id, collateral_asset)
|
|
149
|
+
divisor = 10 ** self._decimals(collateral_asset)
|
|
150
|
+
return AuctionData(
|
|
151
|
+
start_block=data.start_block,
|
|
152
|
+
margin_account_equity_at_initiation=(
|
|
153
|
+
Decimal(data.mae_at_initiation) / divisor
|
|
154
|
+
),
|
|
155
|
+
maintenance_margin_used_at_initiation=(
|
|
156
|
+
Decimal(data.mmu_at_initiation) / divisor
|
|
157
|
+
),
|
|
158
|
+
margin_account_equity_now=(Decimal(data.mae_now) / divisor),
|
|
159
|
+
maintenance_margin_used_now=(Decimal(data.mmu_now) / divisor),
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
### Internal getters ###
|
|
163
|
+
|
|
164
|
+
@cache
|
|
165
|
+
def _tick_size(self, product_id: str) -> int:
|
|
166
|
+
product_registry_contract = ProductRegistry(self._w3)
|
|
167
|
+
return product_registry_contract.tick_size(HexBytes(product_id))
|