Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trading Seer markets using cow #612

Merged
merged 72 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
4b548df
WIP
gabrielfior Oct 31, 2024
05c64c3
Post order using cow-py
kongzii Jan 10, 2025
0ce94cb
refactor to newest cowpy
kongzii Jan 13, 2025
d16a7e5
remove unused stuff
kongzii Jan 13, 2025
9da31c5
up
kongzii Jan 13, 2025
ea544b0
change branch and add log
kongzii Jan 16, 2025
c87e583
Merge branch 'main' into peter/cowpyorder
kongzii Jan 21, 2025
5a26dd5
lint
kongzii Jan 21, 2025
5137ab0
Merge remote-tracking branch 'refs/remotes/origin/main' into 496-seer…
gabrielfior Feb 4, 2025
e47ad88
Added test for create Seer market
gabrielfior Feb 4, 2025
e1c2b73
Fixed Seer subgraph invocations
gabrielfior Feb 4, 2025
116a8df
Bumped version
gabrielfior Feb 4, 2025
513f95e
Added script for creating seer markets
gabrielfior Feb 4, 2025
3fc886d
Script working
gabrielfior Feb 5, 2025
8dedd33
Fixed isort
gabrielfior Feb 5, 2025
69e8689
Tried to fix tests
gabrielfior Feb 5, 2025
288bc45
Adding more logs to debug test
gabrielfior Feb 5, 2025
dbf833a
Fetching market from event logs
gabrielfior Feb 6, 2025
6ecbbd2
Adding PR comments
gabrielfior Feb 6, 2025
b8ef5f6
Trying magic for fixing tests
gabrielfior Feb 6, 2025
0440b0f
Trying to make test pass
gabrielfior Feb 6, 2025
28dcf42
Trying to make test pass (2)
gabrielfior Feb 6, 2025
95b5705
Sending to a differente agent
gabrielfior Feb 6, 2025
8092d5c
Trying test again
gabrielfior Feb 6, 2025
9ee97ab
Contract reverted to old state
gabrielfior Feb 6, 2025
f4e4c78
Merge remote-tracking branch 'refs/remotes/origin/main' into 496-seer…
gabrielfior Feb 7, 2025
5ac4f48
WIP
gabrielfior Feb 7, 2025
45d638d
WIP
gabrielfior Feb 7, 2025
b32a12d
Merge remote-tracking branch 'refs/remotes/origin/main' into 498-seer…
gabrielfior Feb 7, 2025
26b4da3
Small refactor
gabrielfior Feb 7, 2025
9f022f6
Removed attempt to add ABC methods to AgentMarket
gabrielfior Feb 7, 2025
bca2b0a
Merge branch 'refs/heads/peter/cowpyorder' into 498-seer---cow-py-or-…
gabrielfior Feb 7, 2025
c4ca551
Added cow for trade | implementing methods for new AgentMarket
gabrielfior Feb 7, 2025
373650c
Fixed unshelving
gabrielfior Feb 7, 2025
77157b0
Merge remote-tracking branch 'refs/remotes/origin/main' into 498-seer…
gabrielfior Feb 10, 2025
3e840c1
Test seer subgraph working
gabrielfior Feb 11, 2025
ede827c
DeployableCoinflip running for Seer
gabrielfior Feb 11, 2025
46ba913
Fixes mypy
gabrielfior Feb 11, 2025
b921c7c
Added `has_liquidity`
gabrielfior Feb 12, 2025
b6f14b9
Liquidity fetching from cow working
gabrielfior Feb 12, 2025
f92c76c
Implemented get_position
gabrielfior Feb 13, 2025
4af0dfd
Added some tests
gabrielfior Feb 13, 2025
d411bdc
Added test to seer_place_bet
gabrielfior Feb 13, 2025
7bef528
Fixed mypy
gabrielfior Feb 13, 2025
a298344
Update prediction_market_agent_tooling/markets/seer/data_models.py
gabrielfior Feb 13, 2025
e78d5ac
Refactored has_valid_answer
gabrielfior Feb 13, 2025
df236e8
Merge remote-tracking branch 'origin/498-seer---cow-py-or-swapr' into…
gabrielfior Feb 13, 2025
0053cda
Merge remote-tracking branch 'refs/remotes/origin/main' into 498-seer…
gabrielfior Feb 13, 2025
be1947a
Changes after merge
gabrielfior Feb 13, 2025
4657ac6
Reverted change get_outcome_index
gabrielfior Feb 13, 2025
803cb27
Added test
gabrielfior Feb 13, 2025
02618df
Removed "invalid" filter in SeerSubgraphHandler
gabrielfior Feb 14, 2025
1234a51
Update prediction_market_agent_tooling/markets/seer/seer.py
gabrielfior Feb 14, 2025
09bac9d
Added None description
gabrielfior Feb 14, 2025
5d87ee2
Merge remote-tracking branch 'origin/498-seer---cow-py-or-swapr' into…
gabrielfior Feb 14, 2025
e477e1f
Refactored test_seer_place_bet to check for insufficient balance exce…
gabrielfior Feb 14, 2025
a3929ba
Refactored Enum
gabrielfior Feb 14, 2025
d66b976
Moved log around | removed extra check
gabrielfior Feb 14, 2025
2e580d5
Avoiding zero-division errors
gabrielfior Feb 14, 2025
14e9130
Removed dependency Seer Omen ref outcome strings
gabrielfior Feb 14, 2025
47c0b14
Removed dependency Omen <> betting strategy | reverted Omen bool strings
gabrielfior Feb 14, 2025
19fd4e0
mypy magic
gabrielfior Feb 14, 2025
e9b18a5
Fixing CI
gabrielfior Feb 14, 2025
6ed70d1
fixing pre-commit
gabrielfior Feb 14, 2025
c761355
Fixing tests
gabrielfior Feb 14, 2025
a70b1c7
Removed Seer from monitor agents test
gabrielfior Feb 14, 2025
1634762
Deactivating tests for Seer
gabrielfior Feb 14, 2025
8fd98e5
Removed unnecessary test
gabrielfior Feb 14, 2025
2b1901f
try standard raising
kongzii Feb 20, 2025
0bd0ef1
Merge branch 'main' into 498-seer---cow-py-or-swapr
kongzii Feb 20, 2025
7146d38
poetry relock
kongzii Feb 20, 2025
0f8f252
lint
kongzii Feb 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
279 changes: 138 additions & 141 deletions poetry.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions prediction_market_agent_tooling/deploy/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,7 @@ class DeployableTraderAgent(DeployablePredictionAgent):
MarketType.OMEN,
MarketType.MANIFOLD,
MarketType.POLYMARKET,
MarketType.SEER,
]

def __init__(
Expand Down
8 changes: 2 additions & 6 deletions prediction_market_agent_tooling/deploy/betting_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
Trade,
TradeType,
)
from prediction_market_agent_tooling.markets.omen.data_models import get_boolean_outcome
from prediction_market_agent_tooling.markets.omen.omen import (
get_buy_outcome_token_amount,
)
Expand Down Expand Up @@ -94,11 +93,8 @@ def _build_rebalance_trades_from_positions(
sell price is higher.
"""
trades = []
for outcome in [
market.get_outcome_str_from_bool(True),
market.get_outcome_str_from_bool(False),
]:
outcome_bool = get_boolean_outcome(outcome)
for outcome_bool in [True, False]:
outcome = market.get_outcome_str_from_bool(outcome_bool)
prev_amount: TokenAmount = (
existing_position.amounts[outcome]
if existing_position and outcome in existing_position.amounts
Expand Down
3 changes: 1 addition & 2 deletions prediction_market_agent_tooling/markets/agent_market.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,7 @@ def has_successful_resolution(self) -> bool:
def has_unsuccessful_resolution(self) -> bool:
return self.resolution in [Resolution.CANCEL, Resolution.MKT]

@staticmethod
def get_outcome_str_from_bool(outcome: bool) -> OutcomeStr:
def get_outcome_str_from_bool(self, outcome: bool) -> OutcomeStr:
raise NotImplementedError("Subclasses must implement this method")

def get_outcome_str(self, outcome_index: int) -> str:
Expand Down
82 changes: 82 additions & 0 deletions prediction_market_agent_tooling/markets/blockchain_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from web3 import Web3
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simply moved some common functions for Seer and Omen to this file.

from web3.constants import HASH_ZERO

from prediction_market_agent_tooling.config import APIKeys
from prediction_market_agent_tooling.gtypes import (
ChecksumAddress,
HexBytes,
HexStr,
xDai,
xdai_type,
)
from prediction_market_agent_tooling.loggers import logger
from prediction_market_agent_tooling.markets.agent_market import ProcessedTradedMarket
from prediction_market_agent_tooling.markets.omen.data_models import (
ContractPrediction,
IPFSAgentResult,
)
from prediction_market_agent_tooling.markets.omen.omen_contracts import (
OmenAgentResultMappingContract,
)
from prediction_market_agent_tooling.tools.balances import get_balances
from prediction_market_agent_tooling.tools.ipfs.ipfs_handler import IPFSHandler
from prediction_market_agent_tooling.tools.utils import BPS_CONSTANT
from prediction_market_agent_tooling.tools.web3_utils import ipfscidv0_to_byte32


def get_total_balance(
address: ChecksumAddress,
web3: Web3 | None = None,
sum_xdai: bool = True,
sum_wxdai: bool = True,
) -> xDai:
"""
Checks if the total balance of xDai and wxDai in the wallet is above the minimum required balance.
"""
current_balances = get_balances(address, web3)
# xDai and wxDai have equal value and can be exchanged for almost no cost, so we can sum them up.
total_balance = 0.0
if sum_xdai:
total_balance += current_balances.xdai
if sum_wxdai:
total_balance += current_balances.wxdai
return xdai_type(total_balance)


def store_trades(
market_id: str,
traded_market: ProcessedTradedMarket | None,
keys: APIKeys,
agent_name: str,
) -> None:
if traded_market is None:
logger.warning(f"No prediction for market {market_id}, not storing anything.")
return

reasoning = traded_market.answer.reasoning if traded_market.answer.reasoning else ""

ipfs_hash_decoded = HexBytes(HASH_ZERO)
if keys.enable_ipfs_upload:
logger.info("Storing prediction on IPFS.")
ipfs_hash = IPFSHandler(keys).store_agent_result(
IPFSAgentResult(reasoning=reasoning, agent_name=agent_name)
)
ipfs_hash_decoded = ipfscidv0_to_byte32(ipfs_hash)

tx_hashes = [
HexBytes(HexStr(i.id)) for i in traded_market.trades if i.id is not None
]
prediction = ContractPrediction(
publisher=keys.bet_from_address,
ipfs_hash=ipfs_hash_decoded,
tx_hashes=tx_hashes,
estimated_probability_bps=int(traded_market.answer.p_yes * BPS_CONSTANT),
)
tx_receipt = OmenAgentResultMappingContract().add_prediction(
api_keys=keys,
market_address=Web3.to_checksum_address(market_id),
prediction=prediction,
)
logger.info(
f"Added prediction to market {market_id}. - receipt {tx_receipt['transactionHash'].hex()}."
)
1 change: 1 addition & 0 deletions prediction_market_agent_tooling/markets/data_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

class Currency(str, Enum):
xDai = "xDai"
sDai = "sDai"
Mana = "Mana"
USDC = "USDC"

Expand Down
5 changes: 4 additions & 1 deletion prediction_market_agent_tooling/markets/markets.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from prediction_market_agent_tooling.markets.polymarket.polymarket import (
PolymarketAgentMarket,
)
from prediction_market_agent_tooling.markets.seer.seer import SeerAgentMarket
from prediction_market_agent_tooling.tools.utils import (
DatetimeUTC,
should_not_happen,
Expand All @@ -41,6 +42,7 @@ class MarketType(str, Enum):
MANIFOLD = "manifold"
POLYMARKET = "polymarket"
METACULUS = "metaculus"
SEER = "seer"

@property
def market_class(self) -> type[AgentMarket]:
Expand All @@ -56,14 +58,15 @@ def job_class(self) -> type[JobAgentMarket]:

@property
def is_blockchain_market(self) -> bool:
return self in [MarketType.OMEN, MarketType.POLYMARKET]
return self in [MarketType.OMEN, MarketType.POLYMARKET, MarketType.SEER]


MARKET_TYPE_TO_AGENT_MARKET: dict[MarketType, type[AgentMarket]] = {
MarketType.MANIFOLD: ManifoldAgentMarket,
MarketType.OMEN: OmenAgentMarket,
MarketType.POLYMARKET: PolymarketAgentMarket,
MarketType.METACULUS: MetaculusAgentMarket,
MarketType.SEER: SeerAgentMarket,
}

JOB_MARKET_TYPE_TO_JOB_AGENT_MARKET: dict[MarketType, type[JobAgentMarket]] = {
Expand Down
74 changes: 12 additions & 62 deletions prediction_market_agent_tooling/markets/omen/omen.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import tenacity
from web3 import Web3
from web3.constants import HASH_ZERO

from prediction_market_agent_tooling.config import APIKeys
from prediction_market_agent_tooling.gtypes import (
Expand All @@ -28,6 +27,10 @@
ProcessedTradedMarket,
SortBy,
)
from prediction_market_agent_tooling.markets.blockchain_utils import (
get_total_balance,
store_trades,
)
from prediction_market_agent_tooling.markets.data_models import (
Bet,
BetAmount,
Expand All @@ -42,9 +45,7 @@
PRESAGIO_BASE_URL,
Condition,
ConditionPreparationEvent,
ContractPrediction,
CreatedMarket,
IPFSAgentResult,
OmenBet,
OmenMarket,
OmenUserPosition,
Expand All @@ -55,7 +56,6 @@
OMEN_DEFAULT_MARKET_FEE_PERC,
REALITY_DEFAULT_FINALIZATION_TIMEOUT,
Arbitrator,
OmenAgentResultMappingContract,
OmenConditionalTokenContract,
OmenFixedProductMarketMakerContract,
OmenFixedProductMarketMakerFactoryContract,
Expand All @@ -74,23 +74,20 @@
)
from prediction_market_agent_tooling.tools.custom_exceptions import OutOfFundsError
from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes
from prediction_market_agent_tooling.tools.ipfs.ipfs_handler import IPFSHandler
from prediction_market_agent_tooling.tools.tokens.auto_deposit import (
auto_deposit_collateral_token,
)
from prediction_market_agent_tooling.tools.tokens.auto_withdraw import (
auto_withdraw_collateral_token,
)
from prediction_market_agent_tooling.tools.utils import (
BPS_CONSTANT,
DatetimeUTC,
calculate_sell_amount_in_collateral,
check_not_none,
)
from prediction_market_agent_tooling.tools.web3_utils import (
add_fraction,
get_receipt_block_timestamp,
ipfscidv0_to_byte32,
remove_fraction,
wei_to_xdai,
xdai_to_wei,
Expand Down Expand Up @@ -206,7 +203,7 @@ def place_bet(
self,
outcome: bool,
amount: BetAmount,
omen_auto_deposit: bool = True,
auto_deposit: bool = True,
web3: Web3 | None = None,
api_keys: APIKeys | None = None,
) -> str:
Expand All @@ -222,7 +219,7 @@ def place_bet(
amount=amount_xdai,
market=self,
binary_outcome=outcome,
auto_deposit=omen_auto_deposit,
auto_deposit=auto_deposit,
web3=web3,
)

Expand Down Expand Up @@ -434,38 +431,11 @@ def store_trades(
keys: APIKeys,
agent_name: str,
) -> None:
if traded_market is None:
logger.warning(f"No prediction for market {self.id}, not storing anything.")
return

reasoning = (
traded_market.answer.reasoning if traded_market.answer.reasoning else ""
)

ipfs_hash_decoded = HexBytes(HASH_ZERO)
if keys.enable_ipfs_upload:
logger.info("Storing prediction on IPFS.")
ipfs_hash = IPFSHandler(keys).store_agent_result(
IPFSAgentResult(reasoning=reasoning, agent_name=agent_name)
)
ipfs_hash_decoded = ipfscidv0_to_byte32(ipfs_hash)

tx_hashes = [
HexBytes(HexStr(i.id)) for i in traded_market.trades if i.id is not None
]
prediction = ContractPrediction(
publisher=keys.bet_from_address,
ipfs_hash=ipfs_hash_decoded,
tx_hashes=tx_hashes,
estimated_probability_bps=int(traded_market.answer.p_yes * BPS_CONSTANT),
)
tx_receipt = OmenAgentResultMappingContract().add_prediction(
api_keys=keys,
market_address=Web3.to_checksum_address(self.id),
prediction=prediction,
)
logger.info(
f"Added prediction to market {self.id}. - receipt {tx_receipt['transactionHash'].hex()}."
return store_trades(
market_id=self.id,
traded_market=traded_market,
keys=keys,
agent_name=agent_name,
)

@staticmethod
Expand Down Expand Up @@ -516,8 +486,7 @@ def index_set_to_outcome_str(cls, index_set: int) -> OutcomeStr:
cls.get_outcome_str(cls.index_set_to_outcome_index(index_set))
)

@staticmethod
def get_outcome_str_from_bool(outcome: bool) -> OutcomeStr:
def get_outcome_str_from_bool(self, outcome: bool) -> OutcomeStr:
return (
OutcomeStr(OMEN_TRUE_OUTCOME) if outcome else OutcomeStr(OMEN_FALSE_OUTCOME)
)
Expand Down Expand Up @@ -1302,25 +1271,6 @@ def get_binary_market_p_yes_history(market: OmenAgentMarket) -> list[Probability
return history


def get_total_balance(
address: ChecksumAddress,
web3: Web3 | None = None,
sum_xdai: bool = True,
sum_wxdai: bool = True,
) -> xDai:
"""
Checks if the total balance of xDai and wxDai in the wallet is above the minimum required balance.
"""
current_balances = get_balances(address, web3)
# xDai and wxDai have equal value and can be exchanged for almost no cost, so we can sum them up.
total_balance = 0.0
if sum_xdai:
total_balance += current_balances.xdai
if sum_wxdai:
total_balance += current_balances.wxdai
return xdai_type(total_balance)


def withdraw_wxdai_to_xdai_to_keep_balance(
api_keys: APIKeys,
min_required_balance: xDai,
Expand Down
Loading
Loading