ddx-python 1.0.5__cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.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.
Files changed (104) hide show
  1. ddx/.gitignore +1 -0
  2. ddx/__init__.py +58 -0
  3. ddx/_rust/__init__.pyi +2009 -0
  4. ddx/_rust/common/__init__.pyi +17 -0
  5. ddx/_rust/common/accounting.pyi +6 -0
  6. ddx/_rust/common/enums.pyi +3 -0
  7. ddx/_rust/common/requests/__init__.pyi +21 -0
  8. ddx/_rust/common/requests/intents.pyi +19 -0
  9. ddx/_rust/common/specs.pyi +17 -0
  10. ddx/_rust/common/state/__init__.pyi +41 -0
  11. ddx/_rust/common/state/keys.pyi +29 -0
  12. ddx/_rust/common/transactions.pyi +7 -0
  13. ddx/_rust/decimal.pyi +3 -0
  14. ddx/_rust/h256.pyi +3 -0
  15. ddx/_rust.abi3.so +0 -0
  16. ddx/app_config/ethereum/addresses.json +541 -0
  17. ddx/auditor/README.md +32 -0
  18. ddx/auditor/__init__.py +0 -0
  19. ddx/auditor/auditor_driver.py +1034 -0
  20. ddx/auditor/websocket_message.py +54 -0
  21. ddx/common/__init__.py +0 -0
  22. ddx/common/epoch_params.py +28 -0
  23. ddx/common/fill_context.py +144 -0
  24. ddx/common/item_utils.py +38 -0
  25. ddx/common/logging.py +184 -0
  26. ddx/common/market_specs.py +64 -0
  27. ddx/common/trade_mining_params.py +19 -0
  28. ddx/common/transaction_utils.py +85 -0
  29. ddx/common/transactions/__init__.py +0 -0
  30. ddx/common/transactions/advance_epoch.py +91 -0
  31. ddx/common/transactions/advance_settlement_epoch.py +63 -0
  32. ddx/common/transactions/all_price_checkpoints.py +84 -0
  33. ddx/common/transactions/cancel.py +76 -0
  34. ddx/common/transactions/cancel_all.py +88 -0
  35. ddx/common/transactions/complete_fill.py +103 -0
  36. ddx/common/transactions/disaster_recovery.py +97 -0
  37. ddx/common/transactions/event.py +48 -0
  38. ddx/common/transactions/fee_distribution.py +119 -0
  39. ddx/common/transactions/funding.py +294 -0
  40. ddx/common/transactions/futures_expiry.py +123 -0
  41. ddx/common/transactions/genesis.py +108 -0
  42. ddx/common/transactions/inner/__init__.py +0 -0
  43. ddx/common/transactions/inner/adl_outcome.py +25 -0
  44. ddx/common/transactions/inner/fill.py +227 -0
  45. ddx/common/transactions/inner/liquidated_position.py +41 -0
  46. ddx/common/transactions/inner/liquidation_entry.py +41 -0
  47. ddx/common/transactions/inner/liquidation_fill.py +118 -0
  48. ddx/common/transactions/inner/outcome.py +32 -0
  49. ddx/common/transactions/inner/trade_fill.py +125 -0
  50. ddx/common/transactions/insurance_fund_update.py +142 -0
  51. ddx/common/transactions/insurance_fund_withdraw.py +99 -0
  52. ddx/common/transactions/liquidation.py +357 -0
  53. ddx/common/transactions/partial_fill.py +125 -0
  54. ddx/common/transactions/pnl_realization.py +122 -0
  55. ddx/common/transactions/post.py +72 -0
  56. ddx/common/transactions/post_order.py +95 -0
  57. ddx/common/transactions/price_checkpoint.py +96 -0
  58. ddx/common/transactions/signer_registered.py +62 -0
  59. ddx/common/transactions/specs_update.py +61 -0
  60. ddx/common/transactions/strategy_update.py +156 -0
  61. ddx/common/transactions/tradable_product_update.py +98 -0
  62. ddx/common/transactions/trade_mining.py +147 -0
  63. ddx/common/transactions/trader_update.py +105 -0
  64. ddx/common/transactions/withdraw.py +91 -0
  65. ddx/common/transactions/withdraw_ddx.py +74 -0
  66. ddx/common/utils.py +176 -0
  67. ddx/config.py +17 -0
  68. ddx/derivadex_client.py +254 -0
  69. ddx/py.typed +0 -0
  70. ddx/realtime_client/__init__.py +2 -0
  71. ddx/realtime_client/config.py +2 -0
  72. ddx/realtime_client/logs/pytest.log +0 -0
  73. ddx/realtime_client/models/__init__.py +683 -0
  74. ddx/realtime_client/realtime_client.py +567 -0
  75. ddx/rest_client/__init__.py +0 -0
  76. ddx/rest_client/clients/__init__.py +0 -0
  77. ddx/rest_client/clients/base_client.py +60 -0
  78. ddx/rest_client/clients/market_client.py +1241 -0
  79. ddx/rest_client/clients/on_chain_client.py +432 -0
  80. ddx/rest_client/clients/signed_client.py +301 -0
  81. ddx/rest_client/clients/system_client.py +843 -0
  82. ddx/rest_client/clients/trade_client.py +335 -0
  83. ddx/rest_client/constants/__init__.py +0 -0
  84. ddx/rest_client/constants/endpoints.py +67 -0
  85. ddx/rest_client/contracts/__init__.py +0 -0
  86. ddx/rest_client/contracts/checkpoint/__init__.py +560 -0
  87. ddx/rest_client/contracts/ddx/__init__.py +1949 -0
  88. ddx/rest_client/contracts/dummy_token/__init__.py +1014 -0
  89. ddx/rest_client/contracts/i_collateral/__init__.py +1414 -0
  90. ddx/rest_client/contracts/i_stake/__init__.py +696 -0
  91. ddx/rest_client/exceptions/__init__.py +0 -0
  92. ddx/rest_client/exceptions/exceptions.py +32 -0
  93. ddx/rest_client/http/__init__.py +0 -0
  94. ddx/rest_client/http/http_client.py +305 -0
  95. ddx/rest_client/models/__init__.py +0 -0
  96. ddx/rest_client/models/market.py +683 -0
  97. ddx/rest_client/models/signed.py +60 -0
  98. ddx/rest_client/models/system.py +390 -0
  99. ddx/rest_client/models/trade.py +140 -0
  100. ddx/rest_client/utils/__init__.py +0 -0
  101. ddx/rest_client/utils/encryption_utils.py +26 -0
  102. ddx_python-1.0.5.dist-info/METADATA +63 -0
  103. ddx_python-1.0.5.dist-info/RECORD +104 -0
  104. ddx_python-1.0.5.dist-info/WHEEL +4 -0
@@ -0,0 +1,156 @@
1
+ """
2
+ Strategy Update module
3
+ """
4
+
5
+ from typing import Optional
6
+
7
+ from attrs import define, field
8
+ from ddx.common.item_utils import update_avail_collateral, update_locked_collateral
9
+ from ddx.common.transactions.event import Event
10
+ from ddx.common.utils import calculate_max_collateral
11
+ from ddx._rust.common import TokenSymbol
12
+ from ddx._rust.common.state import DerivadexSMT, Strategy, Trader
13
+ from ddx._rust.common.state.keys import StrategyKey, TraderKey
14
+ from ddx._rust.common.transactions import StrategyUpdateKind
15
+ from ddx._rust.decimal import Decimal
16
+
17
+
18
+ @define
19
+ class StrategyUpdate(Event):
20
+ """
21
+ Defines a Strategy Update
22
+
23
+ A StrategyUpdate is an update to a trader's strategy (such as
24
+ depositing or withdrawing collateral).
25
+
26
+ Attributes:
27
+ trader_address (str): Trader's Ethereum address this strategy belongs to
28
+ collateral_address (str): Collateral's Ethereum address a deposit/withdrawal has been made with
29
+ strategy_id_hash (str): Strategy ID hash for the given trader this event belongs to
30
+ strategy_id (Optional[str]): Strategy ID for the given trader this event belongs to. Only deposits will fill this field
31
+ amount (Decimal): The amount of collateral deposited or withdrawn
32
+ update_kind (StrategyUpdateKind): Update kind (Deposit=0, Withdraw=1)
33
+ tx_hash (str): The Ethereum transaction's hash
34
+ request_index (int): Sequenced request index of transaction
35
+ """
36
+
37
+ trader_address: str = field(eq=str.lower)
38
+ collateral_address: str = field(eq=str.lower)
39
+ strategy_id_hash: str = field(eq=str.lower)
40
+ strategy_id: Optional[str]
41
+ amount: Decimal
42
+ update_kind: StrategyUpdateKind
43
+ tx_hash: str = field(eq=str.lower)
44
+ request_index: int = field(default=-1, eq=False)
45
+
46
+ @classmethod
47
+ def decode_value_into_cls(cls, raw_tx_log_event: dict):
48
+ """
49
+ Decode a raw transaction log event (dict) into a StrategyUpdate
50
+ instance.
51
+
52
+ Parameters
53
+ ----------
54
+ raw_tx_log_event : dict
55
+ Raw transaction log event being processed
56
+ """
57
+
58
+ strategy_update_tx_event = raw_tx_log_event["event"]["c"]
59
+
60
+ return cls(
61
+ strategy_update_tx_event["trader"],
62
+ strategy_update_tx_event["collateralAddress"],
63
+ strategy_update_tx_event["strategyIdHash"],
64
+ strategy_update_tx_event.get("strategyId"),
65
+ Decimal(strategy_update_tx_event["amount"]),
66
+ StrategyUpdateKind(strategy_update_tx_event["updateKind"]),
67
+ strategy_update_tx_event["txHash"],
68
+ raw_tx_log_event["requestIndex"],
69
+ )
70
+
71
+ def process_tx(
72
+ self,
73
+ smt: DerivadexSMT,
74
+ **kwargs,
75
+ ):
76
+ """
77
+ Process a StrategyUpdate transaction. A StrategyUpdate consists
78
+ of information relating to updates for a trader's strategy, such
79
+ as when their free or frozen collateral has changed due to a
80
+ deposit or withdrawal. This will update the Strategy leaf in the
81
+ SMT.
82
+
83
+ Parameters
84
+ ----------
85
+ smt: DerivadexSMT
86
+ DerivaDEX Sparse Merkle Tree
87
+ **kwargs
88
+ Additional args specific to StrategyUpdate transactions
89
+ """
90
+
91
+ strategy_key: StrategyKey = StrategyKey(
92
+ self.trader_address, self.strategy_id_hash
93
+ )
94
+ strategy = smt.strategy(strategy_key)
95
+
96
+ symbol = TokenSymbol.from_address(self.collateral_address)
97
+ if self.update_kind == StrategyUpdateKind.Deposit:
98
+ # If StrategyUpdate is of deposit type
99
+
100
+ trader_key: TraderKey = TraderKey(self.trader_address)
101
+ trader = smt.trader(trader_key)
102
+
103
+ if strategy is None:
104
+ # If we haven't yet seen the Strategy leaf, create a new
105
+ # one
106
+ strategy = Strategy.default()
107
+
108
+ if trader is None:
109
+ # Initialize a new Trader Leaf
110
+ trader = Trader.default()
111
+
112
+ smt.store_trader(trader_key, trader)
113
+
114
+ # Compute max allowable deposit given the collateral guard
115
+ # for the trader's DDX balance
116
+ max_allowable_deposit = max(
117
+ (
118
+ calculate_max_collateral(
119
+ kwargs["collateral_tranches"], trader.avail_ddx_balance
120
+ )
121
+ - strategy.avail_collateral.total_value()
122
+ ),
123
+ Decimal("0"),
124
+ )
125
+
126
+ # Compute how much of the attempted deposit will be added
127
+ # to the Strategy's free collateral
128
+ net = min(max_allowable_deposit, self.amount)
129
+
130
+ # Increment the Strategy's free collateral
131
+ update_avail_collateral(
132
+ strategy, symbol, strategy.avail_collateral[symbol] + net
133
+ )
134
+
135
+ # Compute how much of the attempted deposit will be added
136
+ # to the Strategy's frozen collateral
137
+ kickback = self.amount - net
138
+ if kickback != Decimal("0"):
139
+ # Increment the Strategy's frozen collateral
140
+ update_locked_collateral(
141
+ strategy, symbol, strategy.locked_collateral[symbol] + kickback
142
+ )
143
+ elif self.update_kind == StrategyUpdateKind.Withdraw:
144
+ # If StrategyUpdate is of withdrawal (claimed) type
145
+ if strategy is None or strategy.locked_collateral[symbol] < self.amount:
146
+ raise Exception(
147
+ "Strategy leaf either non-existent or insufficiently capitalized to facilitate withdrawal"
148
+ )
149
+
150
+ # Adjust the existing strategy leaf by decrementing the
151
+ # free collateral by the amount in the withdrawal event
152
+ update_locked_collateral(
153
+ strategy, symbol, strategy.locked_collateral[symbol] - self.amount
154
+ )
155
+
156
+ smt.store_strategy(strategy_key, strategy)
@@ -0,0 +1,98 @@
1
+ """
2
+ Tradable Product Update module
3
+ """
4
+
5
+ from attrs import define, field
6
+ from ddx.common.transactions.event import Event
7
+ from ddx._rust.common.specs import SpecsKind
8
+ from ddx._rust.common.state import (DerivadexSMT, TradableProduct,
9
+ TradableProductParameters)
10
+ from ddx._rust.common.state.keys import SpecsKey, TradableProductKey
11
+
12
+
13
+ @define
14
+ class TradableProductUpdate(Event):
15
+ """
16
+ Defines a Tradable Product Update
17
+
18
+ A TradableProductUpdate is an update to a trader's strategy (such as depositing or withdrawing collateral).
19
+
20
+ Attributes:
21
+ additions (list[TradableProductKey]): List of tradable product keys that are marked tradable
22
+ removals (list[TradableProductKey]): List of tradable product keys that are marked untradable
23
+ request_index (int): Sequenced request index of transaction
24
+ """
25
+
26
+ additions: list[TradableProductKey]
27
+ removals: list[TradableProductKey]
28
+ request_index: int = field(default=-1, eq=False, hash=False)
29
+
30
+ @classmethod
31
+ def decode_value_into_cls(cls, raw_tx_log_event: dict):
32
+ """
33
+ Decode a raw transaction log event (dict) into a StrategyUpdate
34
+ instance.
35
+
36
+ Parameters
37
+ ----------
38
+ raw_tx_log_event : dict
39
+ Raw transaction log event being processed
40
+ """
41
+
42
+ tradable_product_update_tx_event = raw_tx_log_event["event"]["c"]
43
+
44
+ return cls(
45
+ [
46
+ TradableProductKey(
47
+ SpecsKey(
48
+ SpecsKind(tradable_product_key["specs"]["kind"]),
49
+ tradable_product_key["specs"]["name"],
50
+ ),
51
+ TradableProductParameters.from_dict(
52
+ tradable_product_key["parameters"]
53
+ ),
54
+ )
55
+ for tradable_product_key in tradable_product_update_tx_event[
56
+ "additions"
57
+ ]
58
+ ],
59
+ [
60
+ TradableProductKey(
61
+ SpecsKey(
62
+ SpecsKind(tradable_product_key["specs"]["kind"]),
63
+ tradable_product_key["specs"]["name"],
64
+ ),
65
+ TradableProductParameters.from_dict(
66
+ tradable_product_key["parameters"]
67
+ ),
68
+ )
69
+ for tradable_product_key in tradable_product_update_tx_event["removals"]
70
+ ],
71
+ raw_tx_log_event["requestIndex"],
72
+ )
73
+
74
+ def process_tx(
75
+ self,
76
+ smt: DerivadexSMT,
77
+ **kwargs,
78
+ ):
79
+ """
80
+ Process a TradableProductUpdate transaction. A TradableProductUpdate consists
81
+ of information relating to updates of the list of tradable products.
82
+
83
+ Parameters
84
+ ----------
85
+ smt: DerivadexSMT
86
+ DerivaDEX Sparse Merkle Tree
87
+ **kwargs
88
+ Additional args specific to TradableProductUpdate transactions
89
+ """
90
+
91
+ for tradable_product_key in self.additions:
92
+ smt.store_tradable_product(
93
+ tradable_product_key,
94
+ TradableProduct(),
95
+ )
96
+
97
+ for tradable_product_key in self.removals:
98
+ smt.store_tradable_product(tradable_product_key, None)
@@ -0,0 +1,147 @@
1
+ """
2
+ TradeMining module
3
+ """
4
+
5
+ import logging
6
+
7
+ from attrs import define, field
8
+ from ddx.common.transactions.event import Event
9
+ from ddx._rust.common.state import DerivadexSMT, Stats
10
+ from ddx._rust.common.state.keys import TraderKey
11
+ from ddx._rust.decimal import Decimal
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ @define
17
+ class TradeMining(Event):
18
+ """
19
+ Defines a TradeMining
20
+
21
+ A TradeMining is when a there is a trade mining distribution.
22
+
23
+ Attributes:
24
+ settlement_epoch_id (int): Settlement epoch id
25
+ ddx_distributed (Decimal): The total DDX distributed in this interval.
26
+ total_volume (Stats): The total maker and taker volume for this interval.
27
+ request_index (int): Sequenced request index of transaction
28
+ """
29
+
30
+ settlement_epoch_id: int
31
+ ddx_distributed: Decimal
32
+ total_volume: Stats
33
+ request_index: int = field(default=-1, eq=False)
34
+
35
+ @classmethod
36
+ def decode_value_into_cls(cls, raw_tx_log_event: dict):
37
+ """
38
+ Decode a raw transaction log event (dict) into a Funding
39
+ instance.
40
+
41
+ Parameters
42
+ ----------
43
+ raw_tx_log_event : dict
44
+ Raw transaction log event being processed
45
+ """
46
+
47
+ trade_mining_tx_event = raw_tx_log_event["event"]["c"]
48
+
49
+ return cls(
50
+ trade_mining_tx_event["settlementEpochId"],
51
+ Decimal(trade_mining_tx_event["ddxDistributed"]),
52
+ Stats(
53
+ Decimal(trade_mining_tx_event["totalVolume"]["makerVolume"]),
54
+ Decimal(trade_mining_tx_event["totalVolume"]["takerVolume"]),
55
+ ),
56
+ raw_tx_log_event["requestIndex"],
57
+ )
58
+
59
+ def process_tx(
60
+ self,
61
+ smt: DerivadexSMT,
62
+ **kwargs,
63
+ ):
64
+ """
65
+ Process a TradeMining transaction. A TradeMining event consists
66
+ of consists of information relating to the trade mining
67
+ distribution, when DDX will be allocated to traders due to
68
+ their maker and taker volume contributions as a proportion to
69
+ the overall exchange volume.
70
+
71
+ Parameters
72
+ ----------
73
+ smt: DerivadexSMT
74
+ DerivaDEX Sparse Merkle Tree
75
+ **kwargs
76
+ Additional args specific to TradeMining transactions
77
+ """
78
+
79
+ if not kwargs["trade_mining_active"]:
80
+ return
81
+
82
+ # The overall trade mining allocation is 75% of the
83
+ # liquidity mining supply (50mm DDX) issued over a 10-year
84
+ # schedule, 3 times a day
85
+ ddx_reward_per_epoch = kwargs["trade_mining_reward_per_epoch"]
86
+ trade_mining_maker_reward_percentage = kwargs[
87
+ "trade_mining_maker_reward_percentage"
88
+ ]
89
+ trade_mining_taker_reward_percentage = kwargs[
90
+ "trade_mining_taker_reward_percentage"
91
+ ]
92
+ if self.ddx_distributed != Decimal("0"):
93
+ # If trade mining did distribute DDX during the trade
94
+ # mining period, we should handle DDX distributions,
95
+ # otherwise we can gracefully skip
96
+
97
+ # Loop through all the stats leaves
98
+ for stats_key, stats in smt.all_stats():
99
+ # Compute the DDX gained as a result of maker volume
100
+ # for the trader (20% of the DDX rewards go to makers)
101
+ ddx_accrued_as_maker = (
102
+ stats.maker_volume
103
+ / self.total_volume.maker_volume
104
+ * ddx_reward_per_epoch
105
+ * trade_mining_maker_reward_percentage
106
+ if self.total_volume.maker_volume != Decimal("0")
107
+ else Decimal("0")
108
+ )
109
+
110
+ # Compute the DDX gained as a result of taker volume
111
+ # for the trader (80% of the DDX rewards go to takers)
112
+ ddx_accrued_as_taker = (
113
+ stats.taker_volume
114
+ / self.total_volume.taker_volume
115
+ * ddx_reward_per_epoch
116
+ * trade_mining_taker_reward_percentage
117
+ if self.total_volume.taker_volume != Decimal("0")
118
+ else Decimal("0")
119
+ )
120
+
121
+ if ddx_accrued_as_maker != Decimal(
122
+ "0"
123
+ ) or ddx_accrued_as_taker != Decimal("0"):
124
+ # If DDX accrued for trader is non-zero, handle
125
+ # distribution
126
+
127
+ # Derive TraderKey given the key
128
+ trader_key: TraderKey = stats_key.as_trader_key()
129
+
130
+ # Get Trader leaf given the key from above
131
+ trader = smt.trader(trader_key)
132
+
133
+ # Increment the Trader leaf's available balance by the
134
+ # DDX accrued (both maker and taker)
135
+ trader.avail_ddx_balance = (
136
+ trader.avail_ddx_balance
137
+ + ddx_accrued_as_maker
138
+ + ddx_accrued_as_taker
139
+ ).recorded_amount()
140
+
141
+ # Update the SMT with the H256 repr of the key and
142
+ # the Trader leaf
143
+ smt.store_trader(trader_key, trader)
144
+
145
+ # Update the SMT with the H256 repr of the key and
146
+ # the Stats leaf
147
+ smt.store_stats(stats_key, None)
@@ -0,0 +1,105 @@
1
+ """
2
+ Trader Update module
3
+ """
4
+
5
+ from attrs import define, field
6
+ from ddx.common.transactions.event import Event
7
+ from ddx._rust.common.state import DerivadexSMT, Trader
8
+ from ddx._rust.common.state.keys import TraderKey
9
+ from ddx._rust.common.transactions import TraderUpdateKind
10
+ from ddx._rust.decimal import Decimal
11
+
12
+
13
+ @define
14
+ class TraderUpdate(Event):
15
+ """
16
+ Defines a TraderUpdate
17
+
18
+ A TraderUpdate is an update to a trader's DDX account (such as depositing
19
+ or withdrawing DDX).
20
+
21
+ Attributes:
22
+ trader_address (str): Trader's Ethereum address this strategy belongs to
23
+ amount (Decimal): The amount of collateral deposited or withdrawn
24
+ update_kind (TraderUpdateKind): Update kind (Deposit, Withdraw, Profile)
25
+ pay_fees_in_ddx (bool): Whether trader has opted to pay fees in DDX by default
26
+ tx_hash (str): The Ethereum transaction's hash
27
+ request_index (int): Sequenced request index of transaction
28
+ """
29
+
30
+ trader_address: str = field(eq=str.lower)
31
+ amount: Decimal
32
+ update_kind: TraderUpdateKind
33
+ pay_fees_in_ddx: bool
34
+ request_index: int = field(default=-1, eq=False)
35
+
36
+ @classmethod
37
+ def decode_value_into_cls(cls, raw_tx_log_event: dict):
38
+ """
39
+ Decode a raw transaction log event (dict) into a StrategyUpdate
40
+ instance.
41
+
42
+ Parameters
43
+ ----------
44
+ raw_tx_log_event : dict
45
+ Raw transaction log event being processed
46
+ """
47
+
48
+ trader_update_tx_event = raw_tx_log_event["event"]["c"]
49
+
50
+ return cls(
51
+ trader_update_tx_event["trader"],
52
+ Decimal(trader_update_tx_event["amount"]),
53
+ TraderUpdateKind(trader_update_tx_event["updateKind"]),
54
+ trader_update_tx_event["payFeesInDdx"],
55
+ raw_tx_log_event["requestIndex"],
56
+ )
57
+
58
+ def process_tx(
59
+ self,
60
+ smt: DerivadexSMT,
61
+ **kwargs,
62
+ ):
63
+ """
64
+ Process a TraderUpdate transaction. A TraderUpdate consists
65
+ of information relating to updates to a trader. This will
66
+ update the Trader leaf in the SMT.
67
+
68
+ Parameters
69
+ ----------
70
+ smt: DerivadexSMT
71
+ DerivaDEX Sparse Merkle Tree
72
+ **kwargs
73
+ Additional args specific to TraderUpdate transactions
74
+ """
75
+
76
+ trader_key: TraderKey = TraderKey(self.trader_address)
77
+ trader = smt.trader(trader_key)
78
+
79
+ if self.update_kind == TraderUpdateKind.DepositDDX:
80
+ # If TraderUpdate is of deposit type
81
+ if trader is None:
82
+ # Initialize a new Trader Leaf
83
+ trader = Trader.default()
84
+
85
+ trader.avail_ddx_balance += self.amount
86
+ elif self.update_kind == TraderUpdateKind.WithdrawDDX:
87
+ # If TraderUpdate is of withdrawal (claimed) type
88
+ if trader is None or trader.locked_ddx_balance < self.amount:
89
+ raise Exception(
90
+ "Trader leaf either non-existent or insufficiently capitalized to facilitate withdrawal"
91
+ )
92
+
93
+ # Adjust the existing Trader leaf by decrementing the
94
+ # free collateral by the amount in the withdrawal event
95
+ trader.locked_ddx_balance -= self.amount
96
+ elif self.update_kind == TraderUpdateKind.Profile:
97
+ # If TraderUpdate is of profile type
98
+ if trader is None:
99
+ raise Exception("Trader leaf non-existent")
100
+
101
+ # Adjust the existing Trader leaf by setting the
102
+ # flag to pay fees in DDX
103
+ trader.pay_fees_in_ddx = self.pay_fees_in_ddx
104
+
105
+ smt.store_trader(trader_key, trader)
@@ -0,0 +1,91 @@
1
+ """
2
+ Withdraw module
3
+ """
4
+
5
+ from attrs import define, field
6
+ from ddx.common.item_utils import update_avail_collateral, update_locked_collateral
7
+ from ddx.common.transactions.event import Event
8
+ from ddx._rust.common import TokenSymbol
9
+ from ddx._rust.common.state import DerivadexSMT, Strategy, Trader
10
+ from ddx._rust.common.state.keys import StrategyKey
11
+ from ddx._rust.decimal import Decimal
12
+
13
+
14
+ @define
15
+ class Withdraw(Event):
16
+ """
17
+ Defines a Withdraw Update
18
+
19
+ A Withdraw Update is when a withdrawal of collateral is **signaled**.
20
+
21
+ Attributes:
22
+ recipient_address (str): Trader address DDX is being withdrawn to
23
+ strategy_id_hash (str): Cross-margined strategy ID hash for which this withdrawal applies
24
+ collateral_address (str): Collateral ERC-20 token address being withdrawn
25
+ amount (Decimal): The amount of DDX being withdrawn
26
+ request_index (int): Sequenced request index of transaction
27
+ """
28
+
29
+ recipient_address: str = field(eq=str.lower)
30
+ strategy_id_hash: str = field(eq=str.lower)
31
+ collateral_address: str = field(eq=str.lower)
32
+ amount: Decimal
33
+ request_index: int = field(default=-1, eq=False)
34
+
35
+ @classmethod
36
+ def decode_value_into_cls(cls, raw_tx_log_event: dict):
37
+ """
38
+ Decode a raw transaction log event (dict) into a Withdraw
39
+ instance.
40
+
41
+ Parameters
42
+ ----------
43
+ raw_tx_log_event : dict
44
+ Raw transaction log event being processed
45
+ """
46
+
47
+ withdraw_tx_event = raw_tx_log_event["event"]["c"]
48
+
49
+ return cls(
50
+ withdraw_tx_event["recipientAddress"],
51
+ withdraw_tx_event["strategy"],
52
+ withdraw_tx_event["currency"],
53
+ Decimal(withdraw_tx_event["amount"]),
54
+ raw_tx_log_event["requestIndex"],
55
+ )
56
+
57
+ def process_tx(
58
+ self,
59
+ smt: DerivadexSMT,
60
+ **kwargs,
61
+ ):
62
+ """
63
+ Process a Withdraw transaction. A Withdraw event consists
64
+ of consists of information relating to withdrawal of collateral.
65
+
66
+ Parameters
67
+ ----------
68
+ smt: DerivadexSMT
69
+ DerivaDEX Sparse Merkle Tree
70
+ **kwargs
71
+ Additional args specific to Withdraw transactions
72
+ """
73
+
74
+ strategy_key: StrategyKey = StrategyKey(
75
+ self.recipient_address, self.strategy_id_hash
76
+ )
77
+ strategy: Strategy = smt.strategy(strategy_key)
78
+
79
+ # Decrement the free balance by the withdrawn amount
80
+ symbol = TokenSymbol.from_address(self.collateral_address)
81
+ update_avail_collateral(
82
+ strategy,
83
+ symbol,
84
+ strategy.avail_collateral[symbol] - self.amount,
85
+ )
86
+ # Increment the frozen balance by the withdrawn amount
87
+ update_locked_collateral(
88
+ strategy, symbol, strategy.locked_collateral[symbol] + self.amount
89
+ )
90
+
91
+ smt.store_strategy(strategy_key, strategy)
@@ -0,0 +1,74 @@
1
+ """
2
+ WithdrawDDX module
3
+ """
4
+
5
+ from attrs import define, field
6
+ from ddx.common.transactions.event import Event
7
+ from ddx._rust.common.state import DerivadexSMT
8
+ from ddx._rust.common.state.keys import TraderKey
9
+ from ddx._rust.decimal import Decimal
10
+
11
+
12
+ @define
13
+ class WithdrawDDX(Event):
14
+ """
15
+ Defines a WithdrawDDX Update
16
+
17
+ A WithdrawDDX is when a withdrawal of DDX is signaled.
18
+
19
+ Attributes:
20
+ recipient_address (str): Ethereum address DDX is being withdrawn to
21
+ amount (Decimal): The amount of DDX being withdrawn
22
+ request_index (int): Sequenced request index of transaction
23
+ """
24
+
25
+ recipient_address: str = field(eq=str.lower)
26
+ amount: Decimal
27
+ request_index: int = field(default=-1, eq=False)
28
+
29
+ @classmethod
30
+ def decode_value_into_cls(cls, raw_tx_log_event: dict):
31
+ """
32
+ Decode a raw transaction log event (dict) into a WithdrawDDX
33
+ instance.
34
+
35
+ Parameters
36
+ ----------
37
+ raw_tx_log_event : dict
38
+ Raw transaction log event being processed
39
+ """
40
+
41
+ withdraw_ddx_tx_event = raw_tx_log_event["event"]["c"]
42
+
43
+ return cls(
44
+ withdraw_ddx_tx_event["recipientAddress"],
45
+ Decimal(withdraw_ddx_tx_event["amount"]),
46
+ raw_tx_log_event["requestIndex"],
47
+ )
48
+
49
+ def process_tx(
50
+ self,
51
+ smt: DerivadexSMT,
52
+ **kwargs,
53
+ ):
54
+ """
55
+ Process a WithdrawDDX transaction. A WithdrawDDX event consists
56
+ of consists of information relating to withdrawal of DDX.
57
+
58
+ Parameters
59
+ ----------
60
+ smt: DerivadexSMT
61
+ DerivaDEX Sparse Merkle Tree
62
+ **kwargs
63
+ Additional args specific to WithdrawDDX transactions
64
+ """
65
+
66
+ trader_key: TraderKey = TraderKey(self.recipient_address)
67
+ trader = smt.trader(trader_key)
68
+
69
+ # Decrement the free balance by the withdrawn amount
70
+ trader.avail_ddx_balance -= self.amount
71
+ # Increment the frozen balance by the withdrawn amount
72
+ trader.locked_ddx_balance += self.amount
73
+
74
+ smt.store_trader(trader_key, trader)