prediction-market-agent-tooling 0.61.1.dev463__py3-none-any.whl → 0.61.1.dev477__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.
Files changed (48) hide show
  1. prediction_market_agent_tooling/deploy/agent.py +5 -4
  2. prediction_market_agent_tooling/deploy/betting_strategy.py +69 -53
  3. prediction_market_agent_tooling/gtypes.py +27 -105
  4. prediction_market_agent_tooling/jobs/jobs_models.py +7 -5
  5. prediction_market_agent_tooling/jobs/omen/omen_jobs.py +17 -13
  6. prediction_market_agent_tooling/markets/agent_market.py +52 -96
  7. prediction_market_agent_tooling/markets/blockchain_utils.py +27 -1
  8. prediction_market_agent_tooling/markets/data_models.py +44 -40
  9. prediction_market_agent_tooling/markets/manifold/api.py +6 -2
  10. prediction_market_agent_tooling/markets/manifold/data_models.py +25 -33
  11. prediction_market_agent_tooling/markets/manifold/manifold.py +11 -8
  12. prediction_market_agent_tooling/markets/market_fees.py +2 -4
  13. prediction_market_agent_tooling/markets/omen/data_models.py +57 -66
  14. prediction_market_agent_tooling/markets/omen/omen.py +249 -214
  15. prediction_market_agent_tooling/markets/omen/omen_contracts.py +29 -31
  16. prediction_market_agent_tooling/markets/omen/omen_resolving.py +14 -7
  17. prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +14 -20
  18. prediction_market_agent_tooling/markets/polymarket/data_models.py +3 -3
  19. prediction_market_agent_tooling/markets/polymarket/data_models_web.py +4 -4
  20. prediction_market_agent_tooling/markets/polymarket/polymarket.py +5 -3
  21. prediction_market_agent_tooling/markets/seer/data_models.py +11 -8
  22. prediction_market_agent_tooling/markets/seer/seer.py +71 -85
  23. prediction_market_agent_tooling/markets/seer/seer_contracts.py +5 -10
  24. prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +7 -7
  25. prediction_market_agent_tooling/monitor/monitor.py +2 -2
  26. prediction_market_agent_tooling/tools/balances.py +11 -9
  27. prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py +10 -12
  28. prediction_market_agent_tooling/tools/betting_strategies/market_moving.py +24 -27
  29. prediction_market_agent_tooling/tools/betting_strategies/utils.py +1 -3
  30. prediction_market_agent_tooling/tools/contract.py +10 -14
  31. prediction_market_agent_tooling/tools/cow/cow_manager.py +4 -3
  32. prediction_market_agent_tooling/tools/cow/cow_order.py +4 -3
  33. prediction_market_agent_tooling/tools/langfuse_client_utils.py +1 -13
  34. prediction_market_agent_tooling/tools/omen/sell_positions.py +3 -6
  35. prediction_market_agent_tooling/tools/safe.py +6 -5
  36. prediction_market_agent_tooling/tools/tokens/auto_deposit.py +30 -32
  37. prediction_market_agent_tooling/tools/tokens/auto_withdraw.py +22 -5
  38. prediction_market_agent_tooling/tools/tokens/main_token.py +2 -2
  39. prediction_market_agent_tooling/tools/utils.py +8 -14
  40. prediction_market_agent_tooling/tools/web3_utils.py +41 -24
  41. {prediction_market_agent_tooling-0.61.1.dev463.dist-info → prediction_market_agent_tooling-0.61.1.dev477.dist-info}/METADATA +1 -2
  42. {prediction_market_agent_tooling-0.61.1.dev463.dist-info → prediction_market_agent_tooling-0.61.1.dev477.dist-info}/RECORD +45 -48
  43. prediction_market_agent_tooling/tools/_generic_value.py +0 -255
  44. prediction_market_agent_tooling/tools/tokens/token_utils.py +0 -46
  45. prediction_market_agent_tooling/tools/tokens/usd.py +0 -63
  46. {prediction_market_agent_tooling-0.61.1.dev463.dist-info → prediction_market_agent_tooling-0.61.1.dev477.dist-info}/LICENSE +0 -0
  47. {prediction_market_agent_tooling-0.61.1.dev463.dist-info → prediction_market_agent_tooling-0.61.1.dev477.dist-info}/WHEEL +0 -0
  48. {prediction_market_agent_tooling-0.61.1.dev463.dist-info → prediction_market_agent_tooling-0.61.1.dev477.dist-info}/entry_points.txt +0 -0
@@ -1,3 +1,4 @@
1
+ import sys
1
2
  import typing as t
2
3
  from datetime import timedelta
3
4
 
@@ -6,17 +7,16 @@ from web3 import Web3
6
7
 
7
8
  from prediction_market_agent_tooling.config import APIKeys
8
9
  from prediction_market_agent_tooling.gtypes import (
9
- USD,
10
10
  ChecksumAddress,
11
11
  HexAddress,
12
12
  HexStr,
13
+ OmenOutcomeToken,
13
14
  OutcomeStr,
14
- OutcomeToken,
15
- OutcomeWei,
16
15
  Probability,
17
- Token,
18
16
  Wei,
17
+ wei_type,
19
18
  xDai,
19
+ xdai_type,
20
20
  )
21
21
  from prediction_market_agent_tooling.loggers import logger
22
22
  from prediction_market_agent_tooling.markets.agent_market import (
@@ -27,11 +27,17 @@ from prediction_market_agent_tooling.markets.agent_market import (
27
27
  ProcessedTradedMarket,
28
28
  SortBy,
29
29
  )
30
- from prediction_market_agent_tooling.markets.blockchain_utils import store_trades
30
+ from prediction_market_agent_tooling.markets.blockchain_utils import (
31
+ get_total_balance,
32
+ store_trades,
33
+ )
31
34
  from prediction_market_agent_tooling.markets.data_models import (
32
35
  Bet,
33
- ExistingPosition,
36
+ BetAmount,
37
+ Currency,
38
+ Position,
34
39
  ResolvedBet,
40
+ TokenAmount,
35
41
  )
36
42
  from prediction_market_agent_tooling.markets.omen.data_models import (
37
43
  OMEN_FALSE_OUTCOME,
@@ -59,7 +65,6 @@ from prediction_market_agent_tooling.markets.omen.omen_contracts import (
59
65
  build_parent_collection_id,
60
66
  )
61
67
  from prediction_market_agent_tooling.markets.omen.omen_subgraph_handler import (
62
- SAFE_COLLATERAL_TOKENS_ADDRESSES,
63
68
  OmenSubgraphHandler,
64
69
  )
65
70
  from prediction_market_agent_tooling.tools.balances import get_balances
@@ -76,20 +81,21 @@ from prediction_market_agent_tooling.tools.tokens.auto_withdraw import (
76
81
  auto_withdraw_collateral_token,
77
82
  )
78
83
  from prediction_market_agent_tooling.tools.tokens.main_token import KEEPING_ERC20_TOKEN
79
- from prediction_market_agent_tooling.tools.tokens.usd import (
80
- get_token_in_usd,
81
- get_usd_in_token,
82
- get_xdai_in_usd,
83
- )
84
84
  from prediction_market_agent_tooling.tools.utils import (
85
85
  DatetimeUTC,
86
86
  calculate_sell_amount_in_collateral,
87
87
  check_not_none,
88
88
  )
89
- from prediction_market_agent_tooling.tools.web3_utils import get_receipt_block_timestamp
89
+ from prediction_market_agent_tooling.tools.web3_utils import (
90
+ add_fraction,
91
+ get_receipt_block_timestamp,
92
+ remove_fraction,
93
+ wei_to_xdai,
94
+ xdai_to_wei,
95
+ )
90
96
 
91
- OMEN_DEFAULT_REALITIO_BOND_VALUE = xDai(0.01)
92
- OMEN_TINY_BET_AMOUNT = USD(0.00001)
97
+ OMEN_DEFAULT_REALITIO_BOND_VALUE = xdai_type(0.01)
98
+ OMEN_TINY_BET_AMOUNT = xdai_type(0.00001)
93
99
 
94
100
 
95
101
  class OmenAgentMarket(AgentMarket):
@@ -97,6 +103,7 @@ class OmenAgentMarket(AgentMarket):
97
103
  Omen's market class that can be used by agents to make predictions.
98
104
  """
99
105
 
106
+ currency: t.ClassVar[Currency] = Currency.xDai
100
107
  base_url: t.ClassVar[str] = PRESAGIO_BASE_URL
101
108
  creator: HexAddress
102
109
 
@@ -145,24 +152,25 @@ class OmenAgentMarket(AgentMarket):
145
152
  def get_liquidity_in_wei(self, web3: Web3 | None = None) -> Wei:
146
153
  return self.get_contract().totalSupply(web3)
147
154
 
148
- def get_liquidity(self, web3: Web3 | None = None) -> Token:
149
- return self.get_liquidity_in_wei(web3).as_token
150
-
151
- def get_tiny_bet_amount(self) -> Token:
152
- return self.get_in_token(OMEN_TINY_BET_AMOUNT)
155
+ def get_liquidity_in_xdai(self, web3: Web3 | None = None) -> xDai:
156
+ return wei_to_xdai(self.get_liquidity_in_wei(web3))
153
157
 
154
- def get_token_in_usd(self, x: Token) -> USD:
155
- return get_token_in_usd(x, self.collateral_token_contract_address_checksummed)
158
+ def get_liquidity(self) -> TokenAmount:
159
+ return TokenAmount(
160
+ amount=self.get_liquidity_in_xdai(),
161
+ currency=self.currency,
162
+ )
156
163
 
157
- def get_usd_in_token(self, x: USD) -> Token:
158
- return get_usd_in_token(x, self.collateral_token_contract_address_checksummed)
164
+ @classmethod
165
+ def get_tiny_bet_amount(cls) -> BetAmount:
166
+ return BetAmount(amount=OMEN_TINY_BET_AMOUNT, currency=cls.currency)
159
167
 
160
168
  def liquidate_existing_positions(
161
169
  self,
162
170
  bet_outcome: bool,
163
171
  web3: Web3 | None = None,
164
172
  api_keys: APIKeys | None = None,
165
- larger_than: OutcomeToken | None = None,
173
+ larger_than: float | None = None,
166
174
  ) -> None:
167
175
  """
168
176
  Liquidates all previously existing positions.
@@ -171,14 +179,16 @@ class OmenAgentMarket(AgentMarket):
171
179
  api_keys = api_keys if api_keys is not None else APIKeys()
172
180
  better_address = api_keys.bet_from_address
173
181
  larger_than = (
174
- larger_than if larger_than is not None else self.get_liquidatable_amount()
182
+ larger_than
183
+ if larger_than is not None
184
+ else self.get_liquidatable_amount().amount
175
185
  )
176
186
  prev_positions_for_market = self.get_positions(
177
187
  user_id=better_address, liquid_only=True, larger_than=larger_than
178
188
  )
179
189
 
180
190
  for prev_position in prev_positions_for_market:
181
- for position_outcome, token_amount in prev_position.amounts_ot.items():
191
+ for position_outcome, token_amount in prev_position.amounts.items():
182
192
  position_outcome_bool = get_boolean_outcome(position_outcome)
183
193
  if position_outcome_bool != bet_outcome:
184
194
  self.sell_tokens(
@@ -192,7 +202,7 @@ class OmenAgentMarket(AgentMarket):
192
202
  def place_bet(
193
203
  self,
194
204
  outcome: bool,
195
- amount: USD,
205
+ amount: BetAmount,
196
206
  auto_deposit: bool = True,
197
207
  web3: Web3 | None = None,
198
208
  api_keys: APIKeys | None = None,
@@ -201,9 +211,12 @@ class OmenAgentMarket(AgentMarket):
201
211
  raise ValueError(
202
212
  f"Market {self.id} is not open for trading. Cannot place bet."
203
213
  )
214
+ if amount.currency != self.currency:
215
+ raise ValueError(f"Omen bets are made in xDai. Got {amount.currency}.")
216
+ amount_xdai = xDai(amount.amount)
204
217
  return binary_omen_buy_outcome_tx(
205
218
  api_keys=api_keys if api_keys is not None else APIKeys(),
206
- amount=amount,
219
+ amount=amount_xdai,
207
220
  market=self,
208
221
  binary_outcome=outcome,
209
222
  auto_deposit=auto_deposit,
@@ -213,7 +226,7 @@ class OmenAgentMarket(AgentMarket):
213
226
  def buy_tokens(
214
227
  self,
215
228
  outcome: bool,
216
- amount: USD,
229
+ amount: TokenAmount,
217
230
  web3: Web3 | None = None,
218
231
  api_keys: APIKeys | None = None,
219
232
  ) -> str:
@@ -224,37 +237,28 @@ class OmenAgentMarket(AgentMarket):
224
237
  api_keys=api_keys,
225
238
  )
226
239
 
227
- def get_sell_value_of_outcome_token(
228
- self, outcome: str, amount: OutcomeToken, web3: Web3 | None = None
229
- ) -> Token:
230
- """
231
- Market can have as collateral token GNO for example.
232
- When you place bet, you buy shares with GNO. For example, you get 10 shares for 1 GNO.
233
- When selling, you need to provide the amount in GNO, which is cumbersome because you know how much shares you have, but you don't have the price of the shares in GNO.
234
- Use this to convert how much collateral token (GNO in our example) to sell, to get the amount of shares you want to sell.
235
- """
236
- outcome_bool = get_boolean_outcome(outcome)
237
-
240
+ def calculate_sell_amount_in_collateral(
241
+ self, amount: TokenAmount, outcome: bool, web3: Web3 | None = None
242
+ ) -> xDai:
238
243
  pool_balance = get_conditional_tokens_balance_for_market(
239
244
  self, self.market_maker_contract_address_checksummed, web3=web3
240
245
  )
241
246
 
242
- sell_str = self.outcomes[self.yes_index if outcome_bool else self.no_index]
243
- other_str = self.outcomes[self.no_index if outcome_bool else self.yes_index]
247
+ sell_str = self.outcomes[self.yes_index if outcome else self.no_index]
248
+ other_str = self.outcomes[self.no_index if outcome else self.yes_index]
244
249
 
245
250
  collateral = calculate_sell_amount_in_collateral(
246
- shares_to_sell=amount,
247
- holdings=pool_balance[self.get_index_set(sell_str)].as_outcome_token,
248
- other_holdings=pool_balance[self.get_index_set(other_str)].as_outcome_token,
251
+ shares_to_sell=amount.amount,
252
+ holdings=wei_to_xdai(pool_balance[self.get_index_set(sell_str)]),
253
+ other_holdings=wei_to_xdai(pool_balance[self.get_index_set(other_str)]),
249
254
  fees=self.fees,
250
255
  )
251
-
252
- return collateral
256
+ return xDai(collateral)
253
257
 
254
258
  def sell_tokens(
255
259
  self,
256
260
  outcome: bool,
257
- amount: USD | OutcomeToken,
261
+ amount: TokenAmount,
258
262
  auto_withdraw: bool = True,
259
263
  api_keys: APIKeys | None = None,
260
264
  web3: Web3 | None = None,
@@ -263,8 +267,16 @@ class OmenAgentMarket(AgentMarket):
263
267
  raise ValueError(
264
268
  f"Market {self.id} is not open for trading. Cannot sell tokens."
265
269
  )
266
- return binary_omen_sell_outcome_tx(
270
+
271
+ # Convert from token (i.e. share) number to xDai value of tokens, as
272
+ # this is the expected unit of the argument in the smart contract.
273
+ collateral = self.calculate_sell_amount_in_collateral(
267
274
  amount=amount,
275
+ outcome=outcome,
276
+ web3=web3,
277
+ )
278
+ return binary_omen_sell_outcome_tx(
279
+ amount=collateral,
268
280
  api_keys=api_keys if api_keys is not None else APIKeys(),
269
281
  market=self,
270
282
  binary_outcome=outcome,
@@ -312,7 +324,7 @@ class OmenAgentMarket(AgentMarket):
312
324
  better_address=user,
313
325
  position_id_in=[p.id for p in positions],
314
326
  # After redeem, this will became zero.
315
- total_balance_bigger_than=OutcomeWei(0),
327
+ total_balance_bigger_than=wei_type(0),
316
328
  )
317
329
  return len(user_positions) > 0
318
330
 
@@ -349,16 +361,16 @@ class OmenAgentMarket(AgentMarket):
349
361
  current_p_yes=model.current_p_yes,
350
362
  condition=model.condition,
351
363
  url=model.url,
352
- volume=model.collateralVolume.as_token,
364
+ volume=wei_to_xdai(model.collateralVolume),
353
365
  close_time=model.close_time,
354
366
  fees=MarketFees(
355
367
  bet_proportion=(
356
- model.fee.as_token.value if model.fee is not None else 0.0
368
+ float(wei_to_xdai(model.fee)) if model.fee is not None else 0.0
357
369
  ),
358
370
  absolute=0,
359
371
  ),
360
372
  outcome_token_pool={
361
- model.outcomes[i]: model.outcomeTokenAmounts[i].as_outcome_token
373
+ model.outcomes[i]: wei_to_xdai(Wei(model.outcomeTokenAmounts[i]))
362
374
  for i in range(len(model.outcomes))
363
375
  },
364
376
  )
@@ -395,24 +407,22 @@ class OmenAgentMarket(AgentMarket):
395
407
  redeem_from_all_user_positions(api_keys)
396
408
 
397
409
  @staticmethod
398
- def get_trade_balance(api_keys: APIKeys, web3: Web3 | None = None) -> USD:
399
- native_usd = get_xdai_in_usd(
400
- get_balances(api_keys.bet_from_address, web3=web3).xdai
401
- )
402
- keeping_usd = get_token_in_usd(
403
- KEEPING_ERC20_TOKEN.balance_of_in_tokens(
404
- api_keys.bet_from_address, web3=web3
405
- ),
406
- KEEPING_ERC20_TOKEN.address,
410
+ def get_trade_balance(api_keys: APIKeys, web3: Web3 | None = None) -> xDai:
411
+ native_token_balance = get_balances(api_keys.bet_from_address, web3=web3).xdai
412
+ return xdai_type(
413
+ wei_to_xdai(
414
+ KEEPING_ERC20_TOKEN.balanceOf(api_keys.bet_from_address, web3=web3)
415
+ )
416
+ + native_token_balance
407
417
  )
408
- return keeping_usd + native_usd
409
418
 
410
419
  @staticmethod
411
420
  def verify_operational_balance(api_keys: APIKeys) -> bool:
412
- return get_balances(
413
- # Use `public_key`, not `bet_from_address` because transaction costs are paid from the EOA wallet.
421
+ return get_total_balance(
414
422
  api_keys.public_key,
415
- ).xdai > xDai(0.001)
423
+ # Use `public_key`, not `bet_from_address` because transaction costs are paid from the EOA wallet.
424
+ sum_wxdai=False,
425
+ ) > xdai_type(0.001)
416
426
 
417
427
  def store_prediction(
418
428
  self, processed_market: ProcessedMarket | None, keys: APIKeys, agent_name: str
@@ -487,19 +497,22 @@ class OmenAgentMarket(AgentMarket):
487
497
 
488
498
  def get_token_balance(
489
499
  self, user_id: str, outcome: str, web3: Web3 | None = None
490
- ) -> OutcomeToken:
500
+ ) -> TokenAmount:
491
501
  index_set = self.get_index_set(outcome)
492
502
  balances = get_conditional_tokens_balance_for_market(
493
503
  self, Web3.to_checksum_address(user_id), web3=web3
494
504
  )
495
- return balances[index_set].as_outcome_token
505
+ return TokenAmount(
506
+ amount=wei_to_xdai(balances[index_set]),
507
+ currency=self.currency,
508
+ )
496
509
 
497
- def get_position(self, user_id: str) -> ExistingPosition | None:
510
+ def get_position(self, user_id: str) -> Position | None:
498
511
  liquidatable_amount = self.get_liquidatable_amount()
499
512
  existing_positions = self.get_positions(
500
513
  user_id=user_id,
501
514
  liquid_only=True,
502
- larger_than=liquidatable_amount,
515
+ larger_than=liquidatable_amount.amount,
503
516
  )
504
517
  existing_position = next(
505
518
  iter([i for i in existing_positions if i.market_id == self.id]), None
@@ -511,12 +524,12 @@ class OmenAgentMarket(AgentMarket):
511
524
  cls,
512
525
  user_id: str,
513
526
  liquid_only: bool = False,
514
- larger_than: OutcomeToken = OutcomeToken(0),
515
- ) -> t.Sequence[ExistingPosition]:
527
+ larger_than: float = 0,
528
+ ) -> list[Position]:
516
529
  sgh = OmenSubgraphHandler()
517
530
  omen_positions = sgh.get_user_positions(
518
531
  better_address=Web3.to_checksum_address(user_id),
519
- total_balance_bigger_than=larger_than.as_outcome_wei,
532
+ total_balance_bigger_than=xdai_to_wei(xDai(larger_than)),
520
533
  )
521
534
 
522
535
  # Sort positions and corresponding markets by condition_id
@@ -550,105 +563,142 @@ class OmenAgentMarket(AgentMarket):
550
563
  if liquid_only and not market.can_be_traded():
551
564
  continue
552
565
 
553
- amounts_ot: dict[OutcomeStr, OutcomeToken] = {}
554
-
566
+ amounts: dict[OutcomeStr, TokenAmount] = {}
555
567
  for omen_position in omen_positions:
556
568
  outecome_str = market.index_set_to_outcome_str(
557
569
  omen_position.position.index_set
558
570
  )
559
571
 
560
572
  # Validate that outcomes are unique for a given condition_id.
561
- if outecome_str in amounts_ot:
573
+ if outecome_str in amounts:
562
574
  raise ValueError(
563
- f"Outcome {outecome_str} already exists in {amounts_ot=}"
575
+ f"Outcome {outecome_str} already exists in {amounts=}"
564
576
  )
565
577
 
566
- amounts_ot[outecome_str] = omen_position.totalBalance.as_outcome_token
567
-
568
- amounts_current = {
569
- k: market.get_token_in_usd(
570
- # If the market is not open for trading anymore, then current value is equal to potential value.
571
- market.get_sell_value_of_outcome_token(k, v)
572
- if market.can_be_traded()
573
- else v.as_token
574
- )
575
- for k, v in amounts_ot.items()
576
- }
577
- amounts_potential = {
578
- k: market.get_token_in_usd(v.as_token) for k, v in amounts_ot.items()
579
- }
580
- positions.append(
581
- ExistingPosition(
582
- market_id=market.id,
583
- amounts_current=amounts_current,
584
- amounts_potential=amounts_potential,
585
- amounts_ot=amounts_ot,
578
+ amounts[outecome_str] = TokenAmount(
579
+ amount=wei_to_xdai(omen_position.totalBalance),
580
+ currency=cls.currency,
586
581
  )
587
- )
582
+
583
+ positions.append(Position(market_id=market.id, amounts=amounts))
588
584
 
589
585
  return positions
590
586
 
587
+ @classmethod
588
+ def get_positions_value(cls, positions: list[Position]) -> BetAmount:
589
+ # Two dicts to map from market ids to (1) positions and (2) market.
590
+ market_ids_positions = {p.market_id: p for p in positions}
591
+ # Check there is only one position per market.
592
+ if len(set(market_ids_positions.keys())) != len(positions):
593
+ raise ValueError(
594
+ f"Markets for positions ({market_ids_positions.keys()}) are not unique."
595
+ )
596
+ markets: list[OmenAgentMarket] = [
597
+ OmenAgentMarket.from_data_model(m)
598
+ for m in OmenSubgraphHandler().get_omen_binary_markets(
599
+ limit=sys.maxsize, id_in=list(market_ids_positions.keys())
600
+ )
601
+ ]
602
+ market_ids_markets = {m.id: m for m in markets}
603
+
604
+ # Validate that dict keys are the same.
605
+ if set(market_ids_positions.keys()) != set(market_ids_markets.keys()):
606
+ raise ValueError(
607
+ f"Market ids in {market_ids_positions.keys()} are not the same as in {market_ids_markets.keys()}"
608
+ )
609
+
610
+ # Initialise position value.
611
+ total_position_value = 0.0
612
+
613
+ for market_id in market_ids_positions.keys():
614
+ position = market_ids_positions[market_id]
615
+ market = market_ids_markets[market_id]
616
+
617
+ yes_tokens = 0.0
618
+ no_tokens = 0.0
619
+ if OMEN_TRUE_OUTCOME in position.amounts:
620
+ yes_tokens = position.amounts[OutcomeStr(OMEN_TRUE_OUTCOME)].amount
621
+ if OMEN_FALSE_OUTCOME in position.amounts:
622
+ no_tokens = position.amounts[OutcomeStr(OMEN_FALSE_OUTCOME)].amount
623
+
624
+ # Account for the value of positions in resolved markets
625
+ if market.is_resolved() and market.has_successful_resolution():
626
+ valued_tokens = yes_tokens if market.boolean_outcome else no_tokens
627
+ total_position_value += valued_tokens
628
+
629
+ # Or if the market is open and trading, get the value of the position
630
+ elif market.can_be_traded():
631
+ total_position_value += yes_tokens * market.yes_outcome_price
632
+ total_position_value += no_tokens * market.no_outcome_price
633
+
634
+ # Or if the market is still open but not trading, estimate the value
635
+ # of the position
636
+ else:
637
+ if yes_tokens:
638
+ yes_price = check_not_none(
639
+ market.get_last_trade_yes_outcome_price()
640
+ )
641
+ total_position_value += yes_tokens * yes_price
642
+ if no_tokens:
643
+ no_price = check_not_none(market.get_last_trade_no_outcome_price())
644
+ total_position_value += no_tokens * no_price
645
+
646
+ return BetAmount(amount=total_position_value, currency=cls.currency)
647
+
591
648
  @classmethod
592
649
  def get_user_url(cls, keys: APIKeys) -> str:
593
650
  return get_omen_user_url(keys.bet_from_address)
594
651
 
595
652
  def get_buy_token_amount(
596
- self, bet_amount: USD | Token, direction: bool
597
- ) -> OutcomeToken:
653
+ self, bet_amount: BetAmount, direction: bool
654
+ ) -> TokenAmount:
598
655
  """
599
656
  Note: this is only valid if the market instance's token pool is
600
657
  up-to-date with the smart contract.
601
658
  """
602
659
  outcome_token_pool = check_not_none(self.outcome_token_pool)
603
660
  amount = get_buy_outcome_token_amount(
604
- investment_amount=self.get_in_token(bet_amount),
661
+ investment_amount=bet_amount.amount,
605
662
  buy_direction=direction,
606
663
  yes_outcome_pool_size=outcome_token_pool[OMEN_TRUE_OUTCOME],
607
664
  no_outcome_pool_size=outcome_token_pool[OMEN_FALSE_OUTCOME],
608
665
  fees=self.fees,
609
666
  )
610
- return amount
667
+ return TokenAmount(amount=amount, currency=self.currency)
611
668
 
612
669
  def _get_buy_token_amount_from_smart_contract(
613
- self, bet_amount: USD, direction: bool
614
- ) -> OutcomeToken:
615
- bet_amount_in_tokens = get_usd_in_token(
616
- bet_amount, self.collateral_token_contract_address_checksummed
617
- )
618
- received_token_amount_wei = self.get_contract().calcBuyAmount(
619
- investment_amount=bet_amount_in_tokens.as_wei,
620
- outcome_index=self.get_outcome_index(
621
- self.get_outcome_str_from_bool(direction)
622
- ),
670
+ self, bet_amount: BetAmount, direction: bool
671
+ ) -> TokenAmount:
672
+ received_token_amount_wei = Wei(
673
+ self.get_contract().calcBuyAmount(
674
+ investment_amount=xdai_to_wei(xDai(bet_amount.amount)),
675
+ outcome_index=self.get_outcome_index(
676
+ self.get_outcome_str_from_bool(direction)
677
+ ),
678
+ )
623
679
  )
624
- received_token_amount = received_token_amount_wei.as_outcome_token
625
- return received_token_amount
680
+ received_token_amount = float(wei_to_xdai(received_token_amount_wei))
681
+ return TokenAmount(amount=received_token_amount, currency=self.currency)
626
682
 
627
- def get_new_p_yes(self, bet_amount: USD, direction: bool) -> Probability:
683
+ def get_new_p_yes(self, bet_amount: BetAmount, direction: bool) -> Probability:
628
684
  """
629
685
  Calculate the new p_yes based on the bet amount and direction.
630
686
  """
631
687
  if not self.has_token_pool():
632
688
  raise ValueError("Outcome token pool is required to calculate new p_yes.")
633
689
 
634
- bet_amount_in_tokens = self.get_usd_in_token(bet_amount)
635
690
  outcome_token_pool = check_not_none(self.outcome_token_pool)
636
-
637
- yes_outcome_pool_size = outcome_token_pool[
638
- self.get_outcome_str_from_bool(True)
639
- ].value
640
- no_outcome_pool_size = outcome_token_pool[
641
- self.get_outcome_str_from_bool(False)
642
- ].value
691
+ yes_outcome_pool_size = outcome_token_pool[self.get_outcome_str_from_bool(True)]
692
+ no_outcome_pool_size = outcome_token_pool[self.get_outcome_str_from_bool(False)]
643
693
 
644
694
  new_yes_outcome_pool_size = yes_outcome_pool_size + (
645
- self.fees.get_after_fees(bet_amount_in_tokens).value
695
+ self.fees.get_bet_size_after_fees(bet_amount.amount)
646
696
  )
647
697
  new_no_outcome_pool_size = no_outcome_pool_size + (
648
- self.fees.get_after_fees(bet_amount_in_tokens).value
698
+ self.fees.get_bet_size_after_fees(bet_amount.amount)
649
699
  )
650
700
 
651
- received_token_amount = self.get_buy_token_amount(bet_amount, direction).value
701
+ received_token_amount = self.get_buy_token_amount(bet_amount, direction).amount
652
702
  if direction:
653
703
  new_yes_outcome_pool_size -= received_token_amount
654
704
  else:
@@ -687,18 +737,11 @@ def get_omen_user_url(address: ChecksumAddress) -> str:
687
737
 
688
738
 
689
739
  def pick_binary_market(
690
- sort_by: SortBy = SortBy.CLOSING_SOONEST,
691
- filter_by: FilterBy = FilterBy.OPEN,
692
- collateral_token_address_in: (
693
- tuple[ChecksumAddress, ...] | None
694
- ) = SAFE_COLLATERAL_TOKENS_ADDRESSES,
740
+ sort_by: SortBy = SortBy.CLOSING_SOONEST, filter_by: FilterBy = FilterBy.OPEN
695
741
  ) -> OmenMarket:
696
742
  subgraph_handler = OmenSubgraphHandler()
697
743
  return subgraph_handler.get_omen_binary_markets_simple(
698
- limit=1,
699
- sort_by=sort_by,
700
- filter_by=filter_by,
701
- collateral_token_address_in=collateral_token_address_in,
744
+ limit=1, sort_by=sort_by, filter_by=filter_by
702
745
  )[0]
703
746
 
704
747
 
@@ -709,7 +752,7 @@ def pick_binary_market(
709
752
  )
710
753
  def omen_buy_outcome_tx(
711
754
  api_keys: APIKeys,
712
- amount: USD | Token,
755
+ amount: xDai,
713
756
  market: OmenAgentMarket,
714
757
  outcome: str,
715
758
  auto_deposit: bool,
@@ -717,32 +760,35 @@ def omen_buy_outcome_tx(
717
760
  slippage: float = 0.01,
718
761
  ) -> str:
719
762
  """
720
- Bets the given amount for the given outcome in the given market.
763
+ Bets the given amount of xDai for the given outcome in the given market.
721
764
  """
765
+ amount_wei = xdai_to_wei(amount)
766
+
722
767
  market_contract: OmenFixedProductMarketMakerContract = market.get_contract()
723
768
  collateral_token_contract = market_contract.get_collateral_token_contract(web3)
724
769
 
725
- amount_token = market.get_in_token(amount)
726
- amount_wei = amount_token.as_wei
770
+ # In case of ERC4626, obtained (for example) sDai out of xDai could be lower than the `amount_wei`, so we need to handle it.
771
+ amount_wei_to_buy = collateral_token_contract.get_in_shares(amount_wei, web3)
727
772
 
728
773
  # Get the index of the outcome we want to buy.
729
774
  outcome_index: int = market.get_outcome_index(outcome)
730
775
 
731
776
  # Calculate the amount of shares we will get for the given investment amount.
732
777
  expected_shares = market_contract.calcBuyAmount(
733
- amount_wei, outcome_index, web3=web3
778
+ amount_wei_to_buy, outcome_index, web3=web3
734
779
  )
735
780
  # Allow small slippage.
736
- expected_shares = expected_shares.without_fraction(slippage)
781
+ expected_shares = remove_fraction(expected_shares, slippage)
737
782
  # Approve the market maker to withdraw our collateral token.
738
783
  collateral_token_contract.approve(
739
784
  api_keys=api_keys,
740
785
  for_address=market_contract.address,
741
- amount_wei=amount_wei,
786
+ amount_wei=amount_wei_to_buy,
742
787
  web3=web3,
743
788
  )
744
789
 
745
790
  if auto_deposit:
791
+ # In auto-depositing, we need to deposit the original `amount_wei`, e.g. we can deposit 2 xDai, but receive 1.8 sDai, so for the bet we will use `amount_wei_to_buy`.
746
792
  auto_deposit_collateral_token(
747
793
  collateral_token_contract, amount_wei, api_keys, web3
748
794
  )
@@ -750,7 +796,7 @@ def omen_buy_outcome_tx(
750
796
  # Buy shares using the deposited xDai in the collateral token.
751
797
  tx_receipt = market_contract.buy(
752
798
  api_keys=api_keys,
753
- amount_wei=amount_wei,
799
+ amount_wei=amount_wei_to_buy,
754
800
  outcome_index=outcome_index,
755
801
  min_outcome_tokens_to_buy=expected_shares,
756
802
  web3=web3,
@@ -761,7 +807,7 @@ def omen_buy_outcome_tx(
761
807
 
762
808
  def binary_omen_buy_outcome_tx(
763
809
  api_keys: APIKeys,
764
- amount: USD | Token,
810
+ amount: xDai,
765
811
  market: OmenAgentMarket,
766
812
  binary_outcome: bool,
767
813
  auto_deposit: bool,
@@ -779,7 +825,7 @@ def binary_omen_buy_outcome_tx(
779
825
 
780
826
  def omen_sell_outcome_tx(
781
827
  api_keys: APIKeys,
782
- amount: OutcomeToken | Token | USD,
828
+ amount: xDai, # The xDai value of shares to sell.
783
829
  market: OmenAgentMarket,
784
830
  outcome: str,
785
831
  auto_withdraw: bool,
@@ -793,18 +839,13 @@ def omen_sell_outcome_tx(
793
839
  The number of shares sold will depend on the share price at the time of the
794
840
  transaction.
795
841
  """
842
+ amount_wei = xdai_to_wei(amount)
843
+ amount_wei = remove_fraction(amount_wei, slippage)
844
+
796
845
  market_contract: OmenFixedProductMarketMakerContract = market.get_contract()
797
846
  conditional_token_contract = OmenConditionalTokenContract()
798
847
  collateral_token_contract = market_contract.get_collateral_token_contract(web3)
799
848
 
800
- amount_token = (
801
- market.get_sell_value_of_outcome_token(outcome, amount, web3)
802
- if isinstance(amount, OutcomeToken)
803
- else market.get_in_token(amount)
804
- )
805
- amount_wei = amount_token.as_wei
806
- amount_wei = amount_wei.without_fraction(slippage)
807
-
808
849
  # Verify, that markets uses conditional tokens that we expect.
809
850
  if (
810
851
  market_contract.conditionalTokens(web3=web3)
@@ -814,15 +855,15 @@ def omen_sell_outcome_tx(
814
855
  f"Market {market.id} uses conditional token that we didn't expect, {market_contract.conditionalTokens()} != {conditional_token_contract.address=}"
815
856
  )
816
857
 
817
- # Get the index of the outcome we want to sell.
858
+ # Get the index of the outcome we want to buy.
818
859
  outcome_index: int = market.get_outcome_index(outcome)
819
860
 
820
- # Calculate the amount of shares we will sell for the given selling amount of collateral.
861
+ # Calculate the amount of shares we will sell for the given selling amount of xdai.
821
862
  max_outcome_tokens_to_sell = market_contract.calcSellAmount(
822
863
  amount_wei, outcome_index, web3=web3
823
864
  )
824
865
  # Allow small slippage.
825
- max_outcome_tokens_to_sell = max_outcome_tokens_to_sell.with_fraction(slippage)
866
+ max_outcome_tokens_to_sell = add_fraction(max_outcome_tokens_to_sell, slippage)
826
867
 
827
868
  # Approve the market maker to move our (all) conditional tokens.
828
869
  conditional_token_contract.setApprovalForAll(
@@ -852,7 +893,7 @@ def omen_sell_outcome_tx(
852
893
 
853
894
  def binary_omen_sell_outcome_tx(
854
895
  api_keys: APIKeys,
855
- amount: OutcomeToken | Token | USD,
896
+ amount: xDai,
856
897
  market: OmenAgentMarket,
857
898
  binary_outcome: bool,
858
899
  auto_withdraw: bool,
@@ -870,16 +911,16 @@ def binary_omen_sell_outcome_tx(
870
911
 
871
912
  def omen_create_market_tx(
872
913
  api_keys: APIKeys,
873
- initial_funds: USD | Token,
914
+ initial_funds: xDai,
874
915
  question: str,
875
916
  closing_time: DatetimeUTC,
876
917
  category: str,
877
918
  language: str,
878
- outcomes: t.Sequence[str],
919
+ outcomes: list[str],
879
920
  auto_deposit: bool,
880
921
  finalization_timeout: timedelta = REALITY_DEFAULT_FINALIZATION_TIMEOUT,
881
922
  fee_perc: float = OMEN_DEFAULT_MARKET_FEE_PERC,
882
- distribution_hint: list[OutcomeWei] | None = None,
923
+ distribution_hint: list[OmenOutcomeToken] | None = None,
883
924
  collateral_token_address: ChecksumAddress = WrappedxDaiContract().address,
884
925
  arbitrator: Arbitrator = Arbitrator.KLEROS_31_JURORS_WITH_APPEAL,
885
926
  web3: Web3 | None = None,
@@ -890,12 +931,7 @@ def omen_create_market_tx(
890
931
  web3 = (
891
932
  web3 or OmenFixedProductMarketMakerFactoryContract.get_web3()
892
933
  ) # Default to Gnosis web3.
893
- initial_funds_in_collateral = (
894
- get_usd_in_token(initial_funds, collateral_token_address)
895
- if isinstance(initial_funds, USD)
896
- else initial_funds
897
- )
898
- initial_funds_in_collateral_wei = initial_funds_in_collateral.as_wei
934
+ initial_funds_wei = xdai_to_wei(initial_funds)
899
935
 
900
936
  realitio_contract = OmenRealitioContract()
901
937
  conditional_token_contract = OmenConditionalTokenContract()
@@ -919,9 +955,9 @@ def omen_create_market_tx(
919
955
 
920
956
  if auto_deposit:
921
957
  auto_deposit_collateral_token(
922
- collateral_token_contract,
923
- initial_funds_in_collateral_wei,
958
+ collateral_token_contract=collateral_token_contract,
924
959
  api_keys=api_keys,
960
+ amount_wei=initial_funds_wei,
925
961
  web3=web3,
926
962
  )
927
963
 
@@ -955,16 +991,21 @@ def omen_create_market_tx(
955
991
  web3=web3,
956
992
  )
957
993
 
994
+ # In case of ERC4626, obtained (for example) sDai out of xDai could be lower than the `amount_wei`, so we need to handle it.
995
+ initial_funds_in_shares = collateral_token_contract.get_in_shares(
996
+ amount=initial_funds_wei, web3=web3
997
+ )
998
+
958
999
  # Approve the market maker to withdraw our collateral token.
959
1000
  collateral_token_contract.approve(
960
1001
  api_keys=api_keys,
961
1002
  for_address=factory_contract.address,
962
- amount_wei=initial_funds_in_collateral_wei,
1003
+ amount_wei=initial_funds_in_shares,
963
1004
  web3=web3,
964
1005
  )
965
1006
 
966
1007
  # Create the market.
967
- fee = Token(fee_perc).as_wei
1008
+ fee = xdai_to_wei(xdai_type(fee_perc))
968
1009
  (
969
1010
  market_event,
970
1011
  funding_event,
@@ -974,7 +1015,7 @@ def omen_create_market_tx(
974
1015
  condition_id=condition_id,
975
1016
  fee=fee,
976
1017
  distribution_hint=distribution_hint,
977
- initial_funds_wei=initial_funds_in_collateral_wei,
1018
+ initial_funds_wei=initial_funds_in_shares,
978
1019
  collateral_token_address=collateral_token_contract.address,
979
1020
  web3=web3,
980
1021
  )
@@ -991,7 +1032,7 @@ def omen_create_market_tx(
991
1032
  condition_id=condition_id,
992
1033
  question_event=question_event,
993
1034
  condition_event=cond_event,
994
- initial_funds=initial_funds_in_collateral_wei,
1035
+ initial_funds=initial_funds_wei,
995
1036
  fee=fee,
996
1037
  distribution_hint=distribution_hint,
997
1038
  )
@@ -1000,28 +1041,27 @@ def omen_create_market_tx(
1000
1041
  def omen_fund_market_tx(
1001
1042
  api_keys: APIKeys,
1002
1043
  market: OmenAgentMarket,
1003
- funds: USD | Token,
1044
+ funds: Wei,
1004
1045
  auto_deposit: bool,
1005
1046
  web3: Web3 | None = None,
1006
1047
  ) -> None:
1007
- funds_in_collateral = market.get_in_token(funds)
1008
- funds_in_collateral_wei = funds_in_collateral.as_wei
1009
1048
  market_contract = market.get_contract()
1010
1049
  collateral_token_contract = market_contract.get_collateral_token_contract(web3=web3)
1011
1050
 
1051
+ amount_to_fund = collateral_token_contract.get_in_shares(funds, web3)
1052
+
1012
1053
  collateral_token_contract.approve(
1013
1054
  api_keys=api_keys,
1014
1055
  for_address=market_contract.address,
1015
- amount_wei=funds_in_collateral_wei,
1056
+ amount_wei=amount_to_fund,
1016
1057
  web3=web3,
1017
1058
  )
1018
1059
 
1019
1060
  if auto_deposit:
1020
- auto_deposit_collateral_token(
1021
- collateral_token_contract, funds_in_collateral_wei, api_keys, web3
1022
- )
1061
+ # In auto-depositing, we need to deposit the original `funds`, e.g. we can deposit 2 xDai, but receive 1.8 sDai, so for the funding we will use `amount_to_fund`.
1062
+ auto_deposit_collateral_token(collateral_token_contract, funds, api_keys, web3)
1023
1063
 
1024
- market_contract.addFunding(api_keys, funds_in_collateral_wei, web3=web3)
1064
+ market_contract.addFunding(api_keys, amount_to_fund, web3=web3)
1025
1065
 
1026
1066
 
1027
1067
  def omen_redeem_full_position_tx(
@@ -1054,7 +1094,7 @@ def omen_redeem_full_position_tx(
1054
1094
  amount_per_index = get_conditional_tokens_balance_for_market(
1055
1095
  market, from_address, web3
1056
1096
  )
1057
- amount_wei = sum(amount_per_index.values(), start=OutcomeWei.zero())
1097
+ amount_wei = sum(amount_per_index.values())
1058
1098
  if amount_wei == 0:
1059
1099
  logger.debug("No balance to claim. Exiting.")
1060
1100
  return
@@ -1072,10 +1112,10 @@ def omen_redeem_full_position_tx(
1072
1112
  web3=web3,
1073
1113
  )
1074
1114
  new_balance = collateral_token_contract.balanceOf(from_address, web3=web3)
1075
- balance_diff = new_balance - original_balance
1115
+ balance_diff = wei_type(new_balance - original_balance)
1076
1116
 
1077
1117
  logger.info(
1078
- f"Redeemed {balance_diff.as_token} {collateral_token_contract.symbol_cached(web3=web3)} from market {market.question=} ({market.url})."
1118
+ f"Redeemed {wei_to_xdai(balance_diff)} {collateral_token_contract.symbol_cached(web3=web3)} from market {market.question=} ({market.url})."
1079
1119
  )
1080
1120
 
1081
1121
  if auto_withdraw:
@@ -1091,12 +1131,12 @@ def get_conditional_tokens_balance_for_market(
1091
1131
  market: OmenAgentMarket,
1092
1132
  from_address: ChecksumAddress,
1093
1133
  web3: Web3 | None = None,
1094
- ) -> dict[int, OutcomeWei]:
1134
+ ) -> dict[int, Wei]:
1095
1135
  """
1096
1136
  We derive the withdrawable balance from the ConditionalTokens contract through CollectionId -> PositionId (which
1097
1137
  also serves as tokenId) -> TokenBalances.
1098
1138
  """
1099
- balance_per_index_set: dict[int, OutcomeWei] = {}
1139
+ balance_per_index_set: dict[int, Wei] = {}
1100
1140
  conditional_token_contract = OmenConditionalTokenContract()
1101
1141
  parent_collection_id = build_parent_collection_id()
1102
1142
 
@@ -1113,7 +1153,7 @@ def get_conditional_tokens_balance_for_market(
1113
1153
  balance_for_position = conditional_token_contract.balanceOf(
1114
1154
  from_address=from_address, position_id=position_id, web3=web3
1115
1155
  )
1116
- balance_per_index_set[index_set] = balance_for_position
1156
+ balance_per_index_set[index_set] = wei_type(balance_for_position)
1117
1157
 
1118
1158
  return balance_per_index_set
1119
1159
 
@@ -1174,11 +1214,11 @@ def omen_remove_fund_market_tx(
1174
1214
  )
1175
1215
 
1176
1216
  new_balance = market_collateral_token_contract.balanceOf(from_address, web3=web3)
1177
- balance_diff = new_balance - original_balance
1217
+ balance_diff = wei_type(new_balance - original_balance)
1178
1218
 
1179
1219
  logger.debug(f"Result from merge positions {result}")
1180
1220
  logger.info(
1181
- f"Withdrawn {balance_diff.as_token} {market_collateral_token_contract.symbol_cached(web3=web3)} from liquidity at {market.url=}."
1221
+ f"Withdrawn {wei_to_xdai(balance_diff)} {market_collateral_token_contract.symbol_cached(web3=web3)} from liquidity at {market.url=}."
1182
1222
  )
1183
1223
 
1184
1224
  if auto_withdraw:
@@ -1204,7 +1244,7 @@ def redeem_from_all_user_positions(
1204
1244
  user_positions = OmenSubgraphHandler().get_user_positions(
1205
1245
  public_key,
1206
1246
  # After redeem, this will became zero and we won't re-process it.
1207
- total_balance_bigger_than=OutcomeWei(0),
1247
+ total_balance_bigger_than=wei_type(0),
1208
1248
  )
1209
1249
 
1210
1250
  for index, user_position in enumerate(user_positions):
@@ -1232,10 +1272,10 @@ def redeem_from_all_user_positions(
1232
1272
  web3=web3,
1233
1273
  )
1234
1274
  new_balance = collateral_token_contract.balanceOf(public_key, web3=web3)
1235
- balance_diff = new_balance - original_balance
1275
+ balance_diff = wei_type(new_balance - original_balance)
1236
1276
 
1237
1277
  logger.info(
1238
- f"Redeemed {balance_diff.as_token} {collateral_token_contract.symbol_cached(web3=web3)} from position {user_position.id=}."
1278
+ f"Redeemed {wei_to_xdai(balance_diff)} {collateral_token_contract.symbol_cached(web3=web3)} from position {user_position.id=}."
1239
1279
  )
1240
1280
 
1241
1281
  if auto_withdraw:
@@ -1306,21 +1346,23 @@ def send_keeping_token_to_eoa_xdai(
1306
1346
  )
1307
1347
  return
1308
1348
 
1309
- need_to_withdraw = (min_required_balance - current_balances_eoa.xdai) * multiplier
1310
- need_to_withdraw_wei = need_to_withdraw.as_xdai_wei
1349
+ need_to_withdraw = xDai(
1350
+ (min_required_balance - current_balances_eoa.xdai) * multiplier
1351
+ )
1352
+ need_to_withdraw_wei = xdai_to_wei(need_to_withdraw)
1311
1353
 
1312
- if current_balances_eoa.wxdai >= need_to_withdraw.as_token:
1354
+ if current_balances_eoa.wxdai >= need_to_withdraw:
1313
1355
  # If EOA has enough of wxDai, simply withdraw it.
1314
1356
  logger.info(
1315
1357
  f"Withdrawing {need_to_withdraw} wxDai from EOA to keep the EOA's xDai balance above the minimum required balance {min_required_balance}."
1316
1358
  )
1317
1359
  wxdai_contract.withdraw(
1318
1360
  api_keys=api_keys.copy_without_safe_address(),
1319
- amount_wei=need_to_withdraw_wei.as_wei,
1361
+ amount_wei=need_to_withdraw_wei,
1320
1362
  web3=web3,
1321
1363
  )
1322
1364
 
1323
- elif current_balances_betting.wxdai >= need_to_withdraw.as_token:
1365
+ elif current_balances_betting.wxdai >= need_to_withdraw:
1324
1366
  # If Safe has enough of wxDai:
1325
1367
  # First send them to EOA's address.
1326
1368
  logger.info(
@@ -1330,7 +1372,7 @@ def send_keeping_token_to_eoa_xdai(
1330
1372
  api_keys=api_keys,
1331
1373
  sender=api_keys.bet_from_address,
1332
1374
  recipient=api_keys.public_key,
1333
- amount_wei=need_to_withdraw_wei.as_wei,
1375
+ amount_wei=need_to_withdraw_wei,
1334
1376
  web3=web3,
1335
1377
  )
1336
1378
  # And then simply withdraw it.
@@ -1339,7 +1381,7 @@ def send_keeping_token_to_eoa_xdai(
1339
1381
  )
1340
1382
  wxdai_contract.withdraw(
1341
1383
  api_keys=api_keys.copy_without_safe_address(),
1342
- amount_wei=need_to_withdraw_wei.as_wei,
1384
+ amount_wei=need_to_withdraw_wei,
1343
1385
  web3=web3,
1344
1386
  )
1345
1387
 
@@ -1350,37 +1392,30 @@ def send_keeping_token_to_eoa_xdai(
1350
1392
 
1351
1393
 
1352
1394
  def get_buy_outcome_token_amount(
1353
- investment_amount: Token,
1395
+ investment_amount: float,
1354
1396
  buy_direction: bool,
1355
- yes_outcome_pool_size: OutcomeToken,
1356
- no_outcome_pool_size: OutcomeToken,
1397
+ yes_outcome_pool_size: float,
1398
+ no_outcome_pool_size: float,
1357
1399
  fees: MarketFees,
1358
- ) -> OutcomeToken:
1400
+ ) -> float:
1359
1401
  """
1360
1402
  Calculates the amount of outcome tokens received for a given investment
1361
1403
 
1362
1404
  Taken from https://github.com/gnosis/conditional-tokens-market-makers/blob/6814c0247c745680bb13298d4f0dd7f5b574d0db/contracts/FixedProductMarketMaker.sol#L264
1363
1405
  """
1364
- investment_amount_minus_fees = fees.get_after_fees(investment_amount)
1365
- investment_amount_minus_fees_as_ot = OutcomeToken(
1366
- investment_amount_minus_fees.value
1367
- )
1406
+ investment_amount_minus_fees = fees.get_bet_size_after_fees(investment_amount)
1368
1407
  buy_token_pool_balance = (
1369
1408
  yes_outcome_pool_size if buy_direction else no_outcome_pool_size
1370
1409
  )
1371
1410
 
1372
1411
  pool_balance = no_outcome_pool_size if buy_direction else yes_outcome_pool_size
1373
- denominator = pool_balance + investment_amount_minus_fees_as_ot
1374
- ending_outcome_balance = OutcomeToken(
1375
- buy_token_pool_balance * pool_balance / denominator
1376
- )
1412
+ denominator = pool_balance + investment_amount_minus_fees
1413
+ ending_outcome_balance = buy_token_pool_balance * pool_balance / denominator
1377
1414
 
1378
1415
  if ending_outcome_balance <= 0:
1379
1416
  raise ValueError("must have non-zero balances")
1380
1417
 
1381
1418
  result = (
1382
- buy_token_pool_balance
1383
- + investment_amount_minus_fees_as_ot
1384
- - ending_outcome_balance
1419
+ buy_token_pool_balance + investment_amount_minus_fees - ending_outcome_balance
1385
1420
  )
1386
1421
  return result