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

Create OmenMarket out of blockchain events #441

Merged
merged 21 commits into from
Oct 1, 2024
Merged

Create OmenMarket out of blockchain events #441

merged 21 commits into from
Oct 1, 2024

Conversation

kongzii
Copy link
Contributor

@kongzii kongzii commented Sep 26, 2024

No description provided.

Copy link

coderabbitai bot commented Sep 26, 2024

Walkthrough

The pull request introduces several modifications across multiple files within the prediction market agent tooling. Key changes include updates to the .gitignore file to manage test files, enhancements to the data_models.py, omen.py, and omen_contracts.py files for market creation and trading functionalities, and the addition of new utility functions and classes. Tests have also been added or modified to ensure the correctness of new features and functionalities, particularly regarding question formatting and market interactions.

Changes

File(s) Change Summary
.gitignore Added entry to ignore all files in tests_files except for .gitkeep.
prediction_market_agent_tooling/markets/omen/... Enhanced data_models.py with new methods and classes for market creation, question handling, and liquidity calculations. Updated omen.py for improved market creation and transaction processes. Modified omen_contracts.py for event handling and contract interactions.
prediction_market_agent_tooling/tools/... Introduced new methods for contract handling and asset management. Updated utility functions for better interaction with collateral tokens.
scripts/create_market_omen.py Renamed variables related to market fees for clarity.
tests/... Added new tests for question formatting and market creation. Updated existing tests to reflect changes in market fee handling and data structure.
tests_integration/... Introduced integration tests for market creation and interaction with the Omen subgraph. Updated existing tests to accommodate new variable names and structures.

Possibly related PRs

Suggested reviewers

  • evangriffiths

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

language = "en"
distribution_hint = [
omen_outcome_type(xdai_to_wei(xdai_type(0.05))), # 75% for yes
omen_outcome_type(xdai_to_wei(xdai_type(0.15))), # 25% for now
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I needed to check if I calculated outcome tokens correctly, so this was a good opportunity to test out market creation with skewed odds: https://presagio.pages.dev/markets?id=0x21f2c0d28c760378282ade8bff1209e22ead59d9

json.dump(from_subgraph_market.model_dump(), f, indent=2)

# Compare!
assert from_created_market == from_subgraph_market
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's 100% 1:1

Screenshot by Dropbox Capture

Comment on lines 391 to 394
outcome_token_marginal_prices = [
xDai((total_amount - amount) / total_amount)
for amount in outcome_token_amounts
]
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm unsure if the order here matters or not.
If a market has outcomes [Yes,No] or [No,Yes], would this still work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is just an ordered list of outcome tokens as retrieved from the event. It doesn't care about what outcomes are at these indices. If you switch Yes,No order, it needs to be handled at different places.

Copy link
Contributor

Choose a reason for hiding this comment

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

What I guess I'm suggesting here is
-> Fetch the 2 outcomes (Yes, No) from the question.
-> Find the indices of Yes, No in the outcomes.
-> Having the indices, you can create a correctly-ordered list of outcomeTokenMarginalPrices with Yes, No in a known order.

It's also possible to find out downstream the order of outcomes, I just find that doing it here is a good spot.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just find that doing it here is a good spot

I disagree here. This here is doing the same thing that subgraph is doing, it's meant to be 1:1 OmenMarket that you'd get from subgraph otherwise (which it is). Subgraph also won't re-order these outcome tokens according to your specific needs.

That's why we have methods like get_outcome_index, so the right way to go about it, if you need outcome tokens for a specific outcome, is something like

x.outcome_token_marginal_prices[x.get_outcome_index("Yes")]

and then you don't need to care about the order of [Yes, No].

Copy link
Contributor Author

@kongzii kongzii Sep 26, 2024

Choose a reason for hiding this comment

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

Which we are actually alredy doing for example here

1 - self.outcomeTokenAmounts[self.yes_index] / sum(self.outcomeTokenAmounts)

or here

Wei(omen_market.outcomeTokenAmounts[omen_market.yes_index])

so the codebase is ready for this 👌 (problem would be if we change the order of it now)

@evangriffiths
Copy link
Contributor

Looks like a couple of CI tests need fixing

Base automatically changed from peter/new-timezone-validator to main September 30, 2024 14:05
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 17

🧹 Outside diff range and nitpick comments (19)
tests/markets/omen/test_reality.py (1)

8-19: LGTM: Test function is well-structured, but could be more comprehensive.

The test function test_format_and_decode_question effectively checks the basic functionality of formatting and parsing a question. It creates a ParsedQuestion instance, formats it, parses it back, and verifies that the result matches the original.

However, consider the following suggestions to improve the test coverage:

  1. Add more test cases with different question types, outcomes, languages, and categories to ensure the functions work correctly for various inputs.
  2. Include an explicit check for the formatted string's content to verify the formatting logic.
  3. Consider parameterizing the numeric identifier (currently hardcoded as 2) to test different scenarios.
  4. Add edge cases, such as empty outcomes or long question strings, to ensure robust handling of various inputs.

Here's an example of how you could expand the test:

import pytest

@pytest.mark.parametrize("question_text, outcomes, language, category, identifier", [
    ("How are you?", ["Cool", "Not cool"], "en", "life", 2),
    ("What's the weather?", ["Sunny", "Rainy", "Cloudy"], "es", "weather", 5),
    ("", ["Yes", "No"], "fr", "general", 10),  # Edge case: empty question
    ("A" * 1000, ["Long", "Short"], "de", "text", 7),  # Edge case: very long question
])
def test_format_and_decode_question(question_text, outcomes, language, category, identifier):
    question = ParsedQuestion(
        question=question_text,
        outcomes=outcomes,
        language=language,
        category=category,
    )
    formatted = format_realitio_question(
        question.question, question.outcomes, question.category, question.language, identifier
    )
    
    # Check the formatted string content
    assert question_text in formatted
    assert all(outcome in formatted for outcome in outcomes)
    assert language in formatted
    assert category in formatted
    
    parsed = parse_realitio_question(formatted, identifier)
    assert parsed == question

This expanded test uses pytest.mark.parametrize to test multiple scenarios and includes checks for the formatted string's content.

scripts/create_market_omen.py (2)

28-28: LGTM: Parameter renamed and default value updated correctly

The fee parameter has been appropriately renamed to fee_perc, which better reflects its purpose as a percentage. The default value has been correctly updated to use OMEN_DEFAULT_MARKET_FEE_PERC.

Consider adding a type hint to explicitly indicate that fee_perc is a percentage:

fee_perc: float = typer.Option(OMEN_DEFAULT_MARKET_FEE_PERC, min=0, max=100)

This would provide additional clarity and validation for the input.


Line range hint 1-71: Summary: Changes align with PR objectives and improve code clarity

The modifications in this file contribute to the PR objective of creating OmenMarket out of blockchain events. The renaming of fee to fee_perc throughout the script enhances code clarity by explicitly indicating that the value represents a percentage. This change is consistently applied in imports, function parameters, and function calls.

To fully complete this PR:

  1. Ensure that the omen_create_market_tx function signature has been updated to use fee_perc instead of fee.
  2. Update any documentation or comments that may reference the old fee parameter.
  3. Consider adding type hints and value range checks for the fee_perc parameter to prevent potential misuse.

As this change affects a core parameter, ensure that all other parts of the system that interact with Omen market creation are updated to use the new fee_perc terminology. This may include:

  • Other scripts or functions that call create_market_omen.py
  • Any API endpoints that expose market creation functionality
  • User-facing documentation or interfaces that allow setting the market fee

Maintaining consistency across the entire system will prevent confusion and potential bugs in the future.

tests_integration/markets/omen/test_reality.py (3)

42-42: LGTM: Updated logging statement

The logging statement has been correctly updated to use question_event.question_id.hex(). This change is consistent with the variable renaming and maintains the functionality.

Consider adding a log message about the entire question_event object, as it might contain other useful information for debugging:

logger.info(f"Question event: {question_event}")
logger.info(f"Question ID: {question_event.question_id.hex()}")

Line range hint 51-65: Fix inconsistency in submit_answer call

There's an inconsistency in how question_id is passed to the submit_answer method.

Please update line 51 as follows:

-            question_id=question_event.question_id,
+            question_id=question_event.question_id,

The change on lines 64-65 looks good and is consistent with the variable renaming.


Line range hint 32-65: Overall feedback on changes

The renaming of question_id to question_event improves code clarity and suggests that the variable contains more information about the question event. Most changes are consistent with this renaming, which is good.

However, there are a few points to consider:

  1. There's an inconsistency on line 51 that needs to be addressed (as mentioned in a previous comment).
  2. Consider adding more logging or assertions to take advantage of the additional information in question_event. This could improve the test's ability to catch potential issues.
  3. It might be helpful to add a comment explaining the structure of question_event for future maintainers.

Here's an example of how you could add more logging and a comment:

# question_event contains information about the asked question,
# including its ID, content, and metadata
logger.info(f"Question event: {question_event}")
logger.info(f"Question content: {question_event.question}")
logger.info(f"Question ID: {question_event.question_id.hex()}")

# Add an assertion to ensure the question content is correct
assert question_event.question == "Will GNO be above $1000 in 1 second from now?", "Unexpected question content"

These changes would make the test more robust and easier to understand.

tests_integration/markets/omen/test_markets.py (1)

50-68: LGTM: Market creation and conversion are correctly implemented.

The market creation and conversion to OmenMarket are well-implemented, using all the previously defined parameters.

Consider using a logging framework instead of a print statement for better control over debug output. You could replace line 67 with:

import logging
logging.debug(f"Market created at {from_created_market.url}")

This allows for more flexible control over log levels and output destinations.

tests_integration_with_local_chain/markets/omen/test_omen.py (1)

Line range hint 148-164: Ensure created_market.market_event is valid before accessing attributes

When accessing created_market.market_event.fixed_product_market_maker_checksummed, please verify that created_market.market_event is not None to prevent potential AttributeError. Adding a check can enhance the robustness of the test.

Consider adding a check like:

assert created_market.market_event is not None, "Market event is None."
prediction_market_agent_tooling/tools/contract.py (4)

Line range hint 75-77: Avoid mutable default class attributes to prevent shared state issues

Defining _cache as a mutable class attribute can lead to shared state across all instances of ContractBaseClass, causing unintended side effects. It's recommended to use PrivateAttr with a default_factory to ensure each instance has its own cache.

Apply this change to modify _cache:

-from pydantic import BaseModel, field_validator
+from pydantic import BaseModel, field_validator, PrivateAttr

 class ContractBaseClass(BaseModel):
     """
     Base class holding the basic requirements and tools used for every contract.
     """
     CHAIN_ID: t.ClassVar[ChainID]
     CHAIN_RPC_URL: t.ClassVar[str]

     abi: ABI
     address: ChecksumAddress

     _abi_field_validator = field_validator("abi", mode="before")(abi_field_validator)
-    _cache: dict[str, t.Any] = {}
+    _cache: dict[str, t.Any] = PrivateAttr(default_factory=dict)

Line range hint 196-206: Ensure robust error handling in deposit_asset_token method

While the deposit_asset_token method correctly handles asset token approval and deposit, consider adding error handling to manage potential exceptions during the approval or deposit process. This will improve the reliability and user feedback of the method.

For example, you might wrap the approval and deposit calls in try-except blocks:

def deposit_asset_token(
    self, asset_value: Wei, api_keys: APIKeys, web3: Web3 | None = None
) -> TxReceipt:
    for_address = api_keys.bet_from_address
    web3 = web3 or self.get_web3()

    asset_token_contract = self.get_asset_token_contract(web3=web3)
    try:
        # Approve vault to withdraw the ERC-20 token from the user.
        asset_token_contract.approve(api_keys, self.address, asset_value, web3=web3)
    except Exception as e:
        raise Exception(f"Token approval failed: {e}")

    try:
        # Deposit asset token (ERC-20) and receive shares in the vault.
        receipt = self.deposit(api_keys, asset_value, for_address, web3=web3)
    except Exception as e:
        raise Exception(f"Token deposit failed: {e}")

    return receipt

Line range hint 246-258: Avoid hardcoding contract addresses for flexibility

Hardcoding the contract address in the DebuggingContract class limits flexibility and can cause issues when deploying to different environments or networks. Consider making the address configurable via environment variables or configuration files.

For example, modify the class to accept the address as an argument:

 class DebuggingContract(ContractOnGnosisChain):
     # Contract ABI taken from the contract source.
     abi: ABI = abi_field_validator(
         os.path.join(
             os.path.dirname(os.path.realpath(__file__)),
             "../abis/debuggingcontract.abi.json",
         )
     )
-    address: ChecksumAddress = Web3.to_checksum_address(
-        "0x5Aa82E068aE6a6a1C26c42E5a59520a74Cdb8998"
-    )
+    address: ChecksumAddress

+    def __init__(self, address: ChecksumAddress, **data):
+        super().__init__(address=address, **data)

And instantiate it with the desired address:

debugging_contract = DebuggingContract(address=CONFIG.DEBUGGING_CONTRACT_ADDRESS)

Line range hint 260-278: Ensure consistent method naming conventions

The methods getNow and get_now in the DebuggingContract class use different naming styles. For consistency and adherence to Python's PEP 8 naming conventions, consider renaming getNow to get_now.

If getNow matches a function name in the smart contract ABI and must be called as such, you can keep the method name but alias it for Python conventions:

 def getNow(
     self,
     web3: Web3 | None = None,
 ) -> int:
     now: int = self.call(
         function_name="getNow",
         web3=web3,
     )
     return now

+ def get_now(
+     self,
+     web3: Web3 | None = None,
+ ) -> int:
+     return self.getNow(web3=web3)

Clients of the class can then use get_now for consistency.

prediction_market_agent_tooling/markets/omen/omen_contracts.py (4)

Line range hint 258-279: Handle potential empty event logs in prepareCondition.

In the prepareCondition method, you are accessing event_logs[0] without verifying if event_logs is not empty. If the event is not emitted, this will raise an IndexError.

Add a check to ensure that event_logs contains the expected event:

 receipt_tx = self.send(
     api_keys=api_keys,
     function_name="prepareCondition",
     function_params=[
         oracle_address,
         question_id,
         outcomes_slot_count,
     ],
     tx_params=tx_params,
     web3=web3,
 )

+if not event_logs:
+    raise ValueError("No ConditionPreparationEvent found in transaction receipt")
 event_logs = (
     self.get_web3_contract(web3=web3)
     .events.ConditionPreparation()
     .process_receipt(receipt_tx)
 )
 cond_event = ConditionPreparationEvent(**event_logs[0]["args"])

432-432: Improve constant naming for clarity.

The constant OMEN_DEFAULT_MARKET_FEE_PERC might cause confusion. The suffix _PERC suggests a percentage, but in the code, fees are sometimes treated as Wei values. Consistency in naming helps prevent misunderstandings.

Consider renaming the constant for clarity:

-OMEN_DEFAULT_MARKET_FEE_PERC = 0.02  # 2% fee from the buying shares amount.
+OMEN_DEFAULT_MARKET_FEE_PERCENTAGE = 0.02  # 2% fee from the buying shares amount.

Line range hint 453-471: Clarify the unit and type of the fee parameter.

In the create2FixedProductMarketMaker method, the fee parameter is annotated as Wei, but the comment indicates it's a percentage where "100% == 1 xDai". This discrepancy can lead to incorrect usage of the function.

Adjust the type annotation and clarify the expected value:

 def create2FixedProductMarketMaker(
     self,
     api_keys: APIKeys,
     condition_id: HexBytes,
     initial_funds_wei: Wei,
     collateral_token_address: ChecksumAddress,
-    fee: Wei,  # This is actually fee in %, 'where 100% == 1 xDai'.
+    fee: float,  # Fee percentage (e.g., 0.02 for 2%)
     distribution_hint: list[OmenOutcomeToken] | None = None,
     tx_params: t.Optional[TxParams] = None,
     web3: Web3 | None = None,
 ) -> tuple[
     OmenFixedProductMarketMakerCreationEvent, FPMMFundingAddedEvent, TxReceipt
 ]:

Ensure that when passing fee to the contract function, it is converted to the correct unit expected by the smart contract.


567-577: Consider validating inputs in askQuestion.

In the askQuestion method, the parameters question, category, outcomes, and language are critical for forming the realitio_question. To prevent issues at runtime, consider adding validation to ensure these inputs meet expected formats and constraints.

You could add checks to validate that:

  • question is a non-empty string.
  • outcomes is a non-empty list of strings.
  • language is a supported language code.
prediction_market_agent_tooling/markets/omen/omen.py (3)

333-334: Add docstring for the new from_created_market method

The newly added from_created_market method lacks a docstring. Adding a docstring would improve readability and maintainability by explaining the purpose and usage of this method.

Consider adding a docstring like:

@staticmethod
def from_created_market(model: "CreatedMarket") -> "OmenAgentMarket":
    """
    Create an OmenAgentMarket instance from a CreatedMarket model.

    :param model: The CreatedMarket model instance.
    :return: An instance of OmenAgentMarket.
    """
    return OmenAgentMarket.from_data_model(OmenMarket.from_created_market(model))

929-934: Unpack returned tuple with explicit variable names

While unpacking the returned tuple from create2FixedProductMarketMaker, ensure that the variable names accurately represent the returned values. Additionally, consider adding error handling to catch any exceptions during market creation.

Verify that the variables market_event, funding_event, and receipt_tx correctly correspond to the returned values.


Line range hint 843-959: Ensure consistent fee units throughout the code

In line 929, fee is calculated using xdai_to_wei, but in line 957, fee is passed directly without conversion. This could lead to inconsistencies if the units are not handled correctly.

Confirm whether fee should be in Wei or a float, and adjust accordingly. For example:

 fee = xdai_to_wei(xdai_type(fee_perc))
 return CreatedMarket(
     ...
-    fee=fee,
+    fee=fee_perc,
     ...
 )

Ensure that the fee field in CreatedMarket matches the expected unit and type.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 186aa5d and e10ab47.

📒 Files selected for processing (13)
  • .gitignore (1 hunks)
  • prediction_market_agent_tooling/markets/omen/data_models.py (4 hunks)
  • prediction_market_agent_tooling/markets/omen/omen.py (10 hunks)
  • prediction_market_agent_tooling/markets/omen/omen_contracts.py (12 hunks)
  • prediction_market_agent_tooling/tools/contract.py (2 hunks)
  • prediction_market_agent_tooling/tools/web3_utils.py (1 hunks)
  • scripts/create_market_omen.py (3 hunks)
  • tests/markets/omen/test_reality.py (1 hunks)
  • tests/markets/test_betting_strategies.py (0 hunks)
  • tests_integration/markets/omen/test_markets.py (1 hunks)
  • tests_integration/markets/omen/test_reality.py (4 hunks)
  • tests_integration_with_local_chain/markets/omen/test_omen.py (9 hunks)
  • tests_integration_with_local_chain/markets/omen/test_reality.py (1 hunks)
💤 Files with no reviewable changes (1)
  • tests/markets/test_betting_strategies.py
🧰 Additional context used
📓 Learnings (1)
tests_integration_with_local_chain/markets/omen/test_omen.py (1)
Learnt from: kongzii
PR: gnosis/prediction-market-agent-tooling#139
File: tests/markets/omen/test_omen.py:144-154
Timestamp: 2024-03-28T15:05:28.580Z
Learning: A GitHub issue was created to track the implementation of the `create_market_fund_market_remove_funding` test function in `test_omen.py` for the Gnosis prediction market agent tooling project. The issue number is 143.
🪛 Ruff
prediction_market_agent_tooling/markets/omen/omen.py

846-846: Do not perform function call WrappedxDaiContract in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

prediction_market_agent_tooling/markets/omen/omen_contracts.py

189-189: Do not perform function call build_parent_collection_id in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

🔇 Additional comments (24)
tests/markets/omen/test_reality.py (1)

1-5: LGTM: Imports are appropriate and well-structured.

The imported components (ParsedQuestion, format_realitio_question, and parse_realitio_question) are relevant to the test function and follow good import practices.

scripts/create_market_omen.py (2)

15-15: LGTM: Import statement updated correctly

The import statement has been updated to reflect the renaming of OMEN_DEFAULT_MARKET_FEE to OMEN_DEFAULT_MARKET_FEE_PERC. This change is consistent and appropriate.


58-58: LGTM: Function argument updated correctly

The fee argument has been correctly renamed to fee_perc in the omen_create_market_tx function call, maintaining consistency with the parameter renaming in the main function.

To ensure full consistency, let's verify that the omen_create_market_tx function signature has been updated accordingly:

✅ Verification successful

Action Required: Verify the omen_create_market_tx function signature correctly

The previous verification attempt failed because python was not recognized as a valid file type. Let's correct the file type and re-run the verification:


LGTM: Function argument and signature updated correctly

The fee argument has been correctly renamed to fee_perc in the omen_create_market_tx function call, and the function signature has been updated accordingly to reflect this change.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the signature of omen_create_market_tx function

# Test: Search for the function definition
rg --type python -A 10 'def omen_create_market_tx'

Length of output: 83


Script:

#!/bin/bash
# Description: Verify the signature of omen_create_market_tx function

# Correcting the file type from 'python' to 'py'
rg --type py -A 10 'def omen_create_market_tx'

Length of output: 949

tests_integration/markets/omen/test_reality.py (1)

Line range hint 32-41: LGTM: Improved variable naming

The change from question_id to question_event is a good improvement. It suggests that the variable contains more information about the question event, not just the ID. This naming is more descriptive and aligns better with the actual content of the variable.

.gitignore (3)

163-164: LGTM! Good practice for managing test files.

These changes improve the management of test-related files in version control:

  1. tests_files/* ignores all files within the tests_files directory, which is useful for excluding test-generated files that don't need to be tracked.
  2. !tests_files/.gitkeep ensures that the .gitkeep file is not ignored, allowing the tests_files directory structure to be maintained in the repository even if it's empty.

This approach keeps the repository clean while preserving the necessary directory structure for tests.


163-164: Please clarify the relationship between these changes and the PR objectives.

While the changes to .gitignore are good practices for managing test files, they seem tangential to the main objective of creating OmenMarket from blockchain events. Could you please clarify:

  1. Are these changes necessary for the OmenMarket implementation?
  2. Have there been changes to the test file structure as part of this PR?
  3. Could these .gitignore changes be related to the CI test failures mentioned in the comments?

Understanding the context will help ensure that these changes are intentional and not inadvertently causing issues with the CI process.


163-164: Ensure no sensitive data in tests_files

While updating .gitignore is generally safe, it's good practice to verify that the tests_files directory doesn't contain any sensitive information. Please confirm that no private keys, API tokens, or other confidential data are present in this directory.

To check for potential sensitive data, you can run the following command:

If this command returns any results, please review them carefully to ensure no sensitive data is being exposed.

tests_integration/markets/omen/test_markets.py (3)

1-30: LGTM: Imports and test function declaration are well-structured.

The imports are comprehensive and appropriate for the test's requirements. The @pytest.mark.skipif decorator is correctly used to prevent unintentional execution of paid tests.


33-48: LGTM: Market creation setup is comprehensive and well-documented.

The market parameters are clearly defined, including the intentionally skewed distribution hint. The assertion on line 46-48 provides a good safeguard to ensure the distribution hint is set up correctly.

As noted in a previous comment, this skewed distribution was intentionally set up to test market creation with uneven odds.


1-86: Overall, the integration test is well-structured and comprehensive.

This test effectively validates the creation of an Omen market and its correspondence with the subgraph data. The implementation covers all necessary steps, from market creation to data verification.

While the test is functional, the suggested improvements would enhance its reliability, debugging capabilities, and error reporting. These include:

  1. Implementing a more robust subgraph synchronization mechanism.
  2. Improving debug data management.
  3. Enhancing the final assertion for better error reporting.

These changes would make the test more resilient and easier to maintain in the long run.

prediction_market_agent_tooling/tools/web3_utils.py (2)

Line range hint 1-344: Summary of changes and suggestions

The addition of the get_receipt_block_timestamp function enhances the utility of this module by providing a way to retrieve block timestamps for transaction receipts. This aligns well with the existing functionality in the file.

Key points from the review:

  1. The new function has been implemented correctly but could benefit from improved error handling, type hinting, and documentation.
  2. The imports should be verified and potentially reorganized for clarity and maintainability.

Once these suggestions are addressed, the changes will be ready for approval. Great job on expanding the functionality of the web3_utils.py module!


Line range hint 1-27: Verify and organize imports

The new function get_receipt_block_timestamp uses types that are already imported. However, it's a good practice to review and organize the imports to ensure clarity and maintainability.

Please run the following script to check the imports:

This script will help you verify the current imports, check for any unused imports, and suggest an organized import structure. Please review the results and make any necessary adjustments to keep the imports clean and well-organized.

tests_integration_with_local_chain/markets/omen/test_omen.py (5)

44-44: LGTM!

The addition of OMEN_DEFAULT_MARKET_FEE_PERC to the import statement is appropriate and ensures that the constant is available for use in the code.


Line range hint 175-192: Ensure validity of created_market.market_event before attribute access

Similar to the previous comment, ensure that created_market.market_event is not None before accessing fixed_product_market_maker_checksummed. This will prevent potential exceptions if the market event is not properly initialized.


272-274: Confirm the availability of collateral_token_contract

Ensure that market.get_contract().get_collateral_token_contract(local_web3) returns a valid contract instance. If there's a possibility of it returning None, consider adding an assertion or handling the case to avoid exceptions.

You can verify the existence of the contract with:

assert collateral_token_contract is not None, "Collateral token contract is None."

377-379: Confirm the availability of collateral_token_contract

Same as the previous comment, ensure that market.get_contract().get_collateral_token_contract(local_web3) returns a valid contract instance in this context as well.


80-83: Verify the usage of fee_perc parameter in omen_create_market_tx

The inclusion of fee_perc=OMEN_DEFAULT_MARKET_FEE_PERC in the omen_create_market_tx function call is correct. Please ensure that the omen_create_market_tx function accepts the fee_perc parameter and handles it appropriately.

Run the following script to confirm that omen_create_market_tx supports the fee_perc parameter:

prediction_market_agent_tooling/tools/contract.py (3)

9-9: Importing Web3Contract is necessary for type hinting

The addition of the import statement for Web3Contract is appropriate, as it is used for type annotations in the get_web3_contract method.


81-83: Addition of get_web3_contract method enhances code reuse

The get_web3_contract method encapsulates the creation of a Web3 contract instance, improving code readability and reusability across the contract classes.


Line range hint 191-194: Method get_asset_token_balance correctly retrieves asset token balance

The get_asset_token_balance method is properly implemented to obtain the balance of the asset token for a given address, enhancing the functionality of ContractERC4626BaseClass.

prediction_market_agent_tooling/markets/omen/data_models.py (1)

380-433: Verify data consistency in from_created_market method

Ensure that all fields mapped from CreatedMarket to OmenMarket in the from_created_market method are correctly assigned and that the source data is consistent. Consider adding validation checks to ensure that critical fields such as IDs, timestamps, and outcome lists are not None and have expected values.

prediction_market_agent_tooling/markets/omen/omen_contracts.py (1)

91-92: ⚠️ Potential issue

Do not call functions in default argument values.

Using build_parent_collection_id() as a default value for the parent_collection_id parameter in redeemPositions is not recommended because default arguments are evaluated only once at function definition time. This can lead to unexpected behavior if the function has side effects or relies on mutable data.

Apply this diff to fix the issue:

 def redeemPositions(
     self,
     api_keys: APIKeys,
     collateral_token_address: HexAddress,
     condition_id: HexBytes,
     index_sets: t.List[int],
-    parent_collection_id: HexStr = build_parent_collection_id(),
+    parent_collection_id: HexStr = None,
     web3: Web3 | None = None,
 ) -> TxReceipt:
+    if parent_collection_id is None:
+        parent_collection_id = build_parent_collection_id()

Likely invalid or redundant comment.

prediction_market_agent_tooling/markets/omen/omen.py (2)

950-959: Include missing fields in CreatedMarket initialization if necessary

Verify that all necessary fields are included when creating a CreatedMarket instance. If the CreatedMarket class requires additional fields not provided here, this could lead to errors.

Check the CreatedMarket class definition to ensure all required fields are supplied.


843-848: Update documentation and downstream code for changed return type

The return type of omen_create_market_tx has changed from ChecksumAddress to CreatedMarket. Ensure that all calls to this function and any dependent code are updated to handle the new return type.

Run the following script to find all usages of omen_create_market_tx and check how the return value is used:

#!/bin/bash
# Description: Find all usages of 'omen_create_market_tx' and check return value handling.

rg --type py 'omen_create_market_tx' -A 3 -B 3

This will help identify any code that may need to be updated due to the changed return type.

🧰 Tools
🪛 Ruff

846-846: Do not perform function call WrappedxDaiContract in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

@@ -20,6 +20,7 @@ def test_ask_question(local_web3: Web3, test_keys: APIKeys) -> None:
language="en",
arbitrator=Arbitrator.KLEROS,
opening=utcnow() + timedelta(minutes=2),
timeout=timedelta(seconds=5),
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Potential issue

The askQuestion method does not support a timeout parameter.

Adding a timeout=timedelta(seconds=5) to the askQuestion method call in test_reality.py is inconsistent with the method's current implementation, which does not accept a timeout parameter. This can lead to runtime errors or unexpected behavior during tests.

Recommendations:

  1. Remove the timeout parameter from the askQuestion call in test_reality.py unless the method is updated to handle it.
  2. Update the method definition of askQuestion in omen_contracts.py to accept and properly handle the timeout parameter if it is necessary for your testing framework.
  3. Ensure consistency across the codebase by verifying that any new parameters added to method calls are supported by their definitions.
🔗 Analysis chain

Consider the implications of the short timeout value.

The addition of a timeout parameter to the askQuestion method is a good practice for controlling the duration of blockchain operations. However, the current value of 5 seconds might be too short for a blockchain transaction to complete, especially in a test environment where network conditions may vary.

Consider the following suggestions:

  1. Increase the timeout value to a more realistic duration, such as 30 seconds or 1 minute.
  2. Make the timeout value configurable, allowing it to be adjusted based on the test environment.

Example implementation:

timeout = timedelta(seconds=config.get('OMEN_ASK_QUESTION_TIMEOUT', 30))

To ensure this change doesn't affect other parts of the codebase, let's verify the OmenRealitioContract class implementation and its usage:

This will help us understand if the timeout parameter is consistently used across the codebase and if any adjustments are needed in other files.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the OmenRealitioContract class definition
echo "OmenRealitioContract class definition:"
rg --type python -A 10 "class OmenRealitioContract"

# Search for other usages of the askQuestion method
echo "\nOther usages of askQuestion method:"
rg --type python "askQuestion\(" --glob '!test_reality.py'

Length of output: 348


Script:

#!/bin/bash
# Search for the OmenRealitioContract class definition
echo "OmenRealitioContract class definition:"
rg "class OmenRealitioContract" --glob "*.py" -A 10

# Search for other usages of askQuestion method excluding test_reality.py
echo "\nOther usages of askQuestion method:"
rg "askQuestion\(" --glob "*.py" --glob "!tests_integration_with_local_chain/markets/omen/test_reality.py"

Length of output: 1771


Script:

#!/bin/bash
# Search for the OmenRealitioContract class definition
echo "OmenRealitioContract class definition:"
rg "class OmenRealitioContract" --glob "*.py" -A 10

# Search for other usages of askQuestion method excluding test_reality.py
echo "\nOther usages of askQuestion method:"
rg "askQuestion\(" --glob "*.py" --glob "!tests_integration/markets/omen/test_reality.py"

Length of output: 1768


Script:

#!/bin/bash
# Search for the OmenRealitioContract class definition
echo "OmenRealitioContract class definition:"
rg "class OmenRealitioContract" --glob "*.py" -A 10

# Search for other usages of askQuestion method excluding all test_reality.py files
echo "\nOther usages of askQuestion method:"
rg "askQuestion\(" --glob "*.py" --glob "!**/test_reality.py"

Length of output: 1627


Script:

#!/bin/bash
# Inspect the askQuestion method definition for the timeout parameter
echo "askQuestion method definition:"
rg "def askQuestion" --glob "*.py" prediction_market_agent_tooling/markets/omen/omen_contracts.py -A 5

# Search all calls to askQuestion to check for the timeout parameter
echo "\nCalls to askQuestion method with timeout parameter:"
rg "askQuestion\(" --glob "*.py" | grep "timeout="

# Check for configuration settings related to OMEN_ASK_QUESTION_TIMEOUT
echo "\nConfiguration settings for askQuestion timeout:"
rg "OMEN_ASK_QUESTION_TIMEOUT" --glob "*.py" .

Length of output: 636

Comment on lines +70 to +83
time.sleep(30)

# Load from subgraph.
from_subgraph_market = OmenSubgraphHandler().get_omen_market_by_market_id(
from_created_market.id
)

# Save because otherwise it's hard to debug
with open("tests_files/created_market.json", "w") as f:
json.dump(created_market.model_dump(), f, indent=2)
with open("tests_files/from_created_market.json", "w") as f:
json.dump(from_created_market.model_dump(), f, indent=2)
with open("tests_files/from_subgraph_market.json", "w") as f:
json.dump(from_subgraph_market.model_dump(), f, indent=2)
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider improving subgraph synchronization and debug data management.

While the current implementation works, there are a couple of areas that could be improved:

  1. Subgraph synchronization: The fixed 30-second sleep might not always be sufficient for the subgraph to update. Consider implementing a polling mechanism with a timeout instead.

  2. Debug data management: Saving data to files in the test directory is helpful for debugging but might lead to clutter. Consider using a temporary directory or a dedicated debug folder.

Here's a suggestion for implementing a polling mechanism:

import tempfile
from pathlib import Path

def wait_for_subgraph_update(market_id, timeout=60, interval=5):
    start_time = time.time()
    while time.time() - start_time < timeout:
        if OmenSubgraphHandler().get_omen_market_by_market_id(market_id):
            return True
        time.sleep(interval)
    return False

# Replace the sleep with:
if not wait_for_subgraph_update(from_created_market.id):
    pytest.fail("Subgraph did not update within the expected timeframe")

# Use a temporary directory for debug files:
with tempfile.TemporaryDirectory() as tmpdir:
    debug_dir = Path(tmpdir)
    (debug_dir / "created_market.json").write_text(json.dumps(created_market.model_dump(), indent=2))
    (debug_dir / "from_created_market.json").write_text(json.dumps(from_created_market.model_dump(), indent=2))
    (debug_dir / "from_subgraph_market.json").write_text(json.dumps(from_subgraph_market.model_dump(), indent=2))
    print(f"Debug files saved in {tmpdir}")

This approach provides more reliable subgraph synchronization and keeps your test directory clean.

json.dump(from_subgraph_market.model_dump(), f, indent=2)

# Compare!
assert from_created_market == from_subgraph_market
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider enhancing the final assertion for better error reporting.

While the current assertion is correct, it might not provide enough information if the test fails. To make debugging easier, consider using a more detailed assertion that shows the differences between the two objects.

Here's a suggestion for a more informative assertion:

import deepdiff

diff = deepdiff.DeepDiff(from_created_market.model_dump(), from_subgraph_market.model_dump(), ignore_order=True)
assert not diff, f"Differences found between created market and subgraph market:\n{diff.pretty()}"

This approach will provide a detailed breakdown of any differences between the two market objects, making it easier to identify and fix any discrepancies.

Comment on lines +340 to +344
def get_receipt_block_timestamp(receipt_tx: TxReceipt, web3: Web3) -> int:
block_number = receipt_tx["blockNumber"]
block = web3.eth.get_block(block_number)
block_timestamp: int = block["timestamp"]
return block_timestamp
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance the get_receipt_block_timestamp function with error handling, type hinting, and documentation.

The function looks good, but could benefit from the following improvements:

  1. Add error handling for potential exceptions during the Web3 call.
  2. Include explicit return type hinting.
  3. Add a docstring to explain the function's purpose and parameters.

Here's a suggested implementation with these improvements:

from web3.exceptions import BlockNotFound

def get_receipt_block_timestamp(receipt_tx: TxReceipt, web3: Web3) -> int:
    """
    Retrieve the block timestamp for a given transaction receipt.

    Args:
        receipt_tx (TxReceipt): The transaction receipt.
        web3 (Web3): The Web3 instance to use for blockchain interactions.

    Returns:
        int: The timestamp of the block containing the transaction.

    Raises:
        BlockNotFound: If the block associated with the transaction cannot be found.
        ValueError: If the block doesn't contain a timestamp.
    """
    block_number = receipt_tx["blockNumber"]
    try:
        block = web3.eth.get_block(block_number)
    except BlockNotFound:
        raise BlockNotFound(f"Block {block_number} not found")
    
    block_timestamp = block.get("timestamp")
    if block_timestamp is None:
        raise ValueError(f"Block {block_number} does not contain a timestamp")
    
    return int(block_timestamp)

This implementation includes error handling for potential issues, explicit type hinting for the return value, and a comprehensive docstring explaining the function's purpose, parameters, return value, and potential exceptions.

Comment on lines +92 to +96
logger.debug(f"Market created at address: {created_market.market_event}")
# ToDo - Fix call here (subgraph will not update on localchain). Retrieve data directly from contract.
market = omen_subgraph_handler.get_omen_market_by_market_id(market_address)
market = omen_subgraph_handler.get_omen_market_by_market_id(
created_market.market_event.fixed_product_market_maker_checksummed
)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Address the TODO: Retrieve data directly from the contract

There's a TODO comment indicating that the subgraph will not update on the local chain and that data should be retrieved directly from the contract. It's recommended to implement this change to ensure the test functions correctly in a local environment.

Do you need assistance in modifying the code to fetch market data directly from the contract? I can help implement this change or open a GitHub issue to track this task.

Comment on lines +899 to +907
cond_event: ConditionPreparationEvent | None = None
condition_id = conditional_token_contract.getConditionId(
question_id=question_id,
question_id=question_event.question_id,
oracle_address=oracle_contract.address,
outcomes_slot_count=len(outcomes),
web3=web3,
)
if not conditional_token_contract.does_condition_exists(condition_id, web3=web3):
conditional_token_contract.prepareCondition(
cond_event = conditional_token_contract.prepareCondition(
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle existing condition in omen_create_market_tx

In the omen_create_market_tx function, if the condition already exists, cond_event remains None. Ensure that subsequent code can handle this scenario without errors.

Consider adding a comment or handling to clarify this behavior:

# If the condition already exists, `cond_event` will be None.
if not conditional_token_contract.does_condition_exists(condition_id, web3=web3):
    cond_event = conditional_token_contract.prepareCondition(
        api_keys=api_keys,
        question_id=question_event.question_id,
        oracle_address=oracle_contract.address,
        outcomes_slot_count=len(outcomes),
        web3=web3,
    )
# Else, proceed knowing that `cond_event` is None.

Ensure that any code that uses cond_event can handle the None value appropriately.

@@ -751,7 +759,7 @@

market_contract: OmenFixedProductMarketMakerContract = market.get_contract()
conditional_token_contract = OmenConditionalTokenContract()
collateral_token_contract = market_contract.get_collateral_token_contract()
collateral_token_contract = market_contract.get_collateral_token_contract(web3)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle potential None value for web3 parameter

Similar to line 685, ensure that web3 is not None before calling get_collateral_token_contract(web3).

Add a check or initialize web3 if necessary:

 collateral_token_contract = market_contract.get_collateral_token_contract(web3)
+if web3 is None:
+    web3 = market_contract.get_web3()

Committable suggestion was skipped due to low confidence.

@@ -674,7 +682,7 @@
amount_wei = xdai_to_wei(amount)

market_contract: OmenFixedProductMarketMakerContract = market.get_contract()
collateral_token_contract = market_contract.get_collateral_token_contract()
collateral_token_contract = market_contract.get_collateral_token_contract(web3)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle potential None value for web3 parameter

The variable web3 may be None, which could lead to errors when calling get_collateral_token_contract(web3). Ensure that web3 is initialized before this call.

Consider adding a check or default initialization:

 collateral_token_contract = market_contract.get_collateral_token_contract(web3)
+if web3 is None:
+    web3 = market_contract.get_web3()

Alternatively, ensure that web3 is passed correctly when the function is called.

Committable suggestion was skipped due to low confidence.

Comment on lines +843 to 846
finalization_timeout: timedelta = timedelta(days=1),
fee_perc: float = OMEN_DEFAULT_MARKET_FEE_PERC,
distribution_hint: list[OmenOutcomeToken] | None = None,
collateral_token_address: ChecksumAddress = WrappedxDaiContract().address,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid function calls in default argument values

Using a function call WrappedxDaiContract() in the default value of the collateral_token_address parameter can lead to unintended behavior because the function is evaluated at function definition time, not at call time. This could cause issues if the function relies on runtime state.

To fix this, set the default value to None and initialize it within the function if it's None:

 def omen_create_market_tx(
     api_keys: APIKeys,
     initial_funds: xDai,
     question: str,
     closing_time: datetime,
     category: str,
     language: str,
     outcomes: list[str],
     auto_deposit: bool,
-    finalization_timeout: timedelta = timedelta(days=1),
-    fee_perc: float = OMEN_DEFAULT_MARKET_FEE_PERC,
-    distribution_hint: list[OmenOutcomeToken] | None = None,
-    collateral_token_address: ChecksumAddress = WrappedxDaiContract().address,
     web3: Web3 | None = None,
 ) -> CreatedMarket:
+    finalization_timeout: timedelta = timedelta(days=1),
+    fee_perc: float = OMEN_DEFAULT_MARKET_FEE_PERC,
+    distribution_hint: list[OmenOutcomeToken] | None = None,
+    collateral_token_address: ChecksumAddress | None = None,
+    web3: Web3 | None = None,
 ):
+    if collateral_token_address is None:
+        collateral_token_address = WrappedxDaiContract().address

This change ensures that WrappedxDaiContract() is called at runtime when the function is invoked.

[static analysis hint addressed]

Committable suggestion was skipped due to low confidence.

🧰 Tools
🪛 Ruff

846-846: Do not perform function call WrappedxDaiContract in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

Comment on lines +950 to +959
market_creation_timestamp=get_receipt_block_timestamp(receipt_tx, web3),
market_event=market_event,
funding_event=funding_event,
condition_id=condition_id,
question_event=question_event,
condition_event=cond_event,
initial_funds=initial_funds_wei,
fee=fee,
distribution_hint=distribution_hint,
)
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Missing Proper Handling for cond_event When It Is None

The analysis indicates that cond_event can be None, but there are no conditional checks handling this case. This may lead to potential issues when the CreatedMarket object is used elsewhere.

  • File: prediction_market_agent_tooling/markets/omen/omen.py
    • Lines: 950-959
🔗 Analysis chain

Ensure all required fields are correctly initialized in CreatedMarket

When returning the CreatedMarket instance, verify that all fields are properly initialized, especially cond_event, which may be None if the condition already exists. This could lead to issues when the CreatedMarket object is used elsewhere.

Run the following script to check where cond_event is used and ensure it can handle None values:

This script searches for all occurrences of cond_event in Python files and provides context to verify proper handling.


Please run the following corrected script to find usages of cond_event and verify None handling:


Please run the following script to verify that cond_event is properly handled when it is None:


Please run the following corrected script to verify that cond_event is properly handled when it is None:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find usages of 'cond_event' and check for None handling.

# Search for 'cond_event' assignments and usages.
rg --type py --py 'cond_event\s*='
rg --type py --py '\bcond_event\b' -A 5 -B 5

Length of output: 6863


Script:

#!/bin/bash
# Description: Corrected script to find usages of 'cond_event' and check for None handling.

# Search for 'cond_event' assignments
rg -t py 'cond_event\s*='

# Search for 'cond_event' usages with context lines
rg -t py '\bcond_event\b' -C 5

Length of output: 4320


Script:

#!/bin/bash
# Description: Check for conditional handling of 'cond_event' being None.

# Search for conditions where 'cond_event' is compared to None
rg -t py 'cond_event\s*is\s*None'
rg -t py 'cond_event\s*!\=\s*None'
rg -t py 'if\s+cond_event\b'
rg -t py '\bcond_event\b\s*\.'

Length of output: 240


Script:

#!/bin/bash
# Description: Corrected script to check conditional handling of 'cond_event' being None.

# Search for conditions where 'cond_event' is compared to None
rg -t py 'cond_event\s*is\s*None'
rg -t py 'cond_event\s*!=\s*None'

# Search for conditional statements involving 'cond_event'
rg -t py 'if\s+cond_event\b'
rg -t py '\bcond_event\b\s*\.'

Length of output: 135

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
tests/markets/omen/test_omen.py (1)

284-296: LGTM: Well-structured test function for calculate_marginal_prices.

The new test function test_calculate_marginal_prices is well-designed and covers multiple scenarios efficiently using pytest's parametrize decorator. It includes edge cases and provides clear type hints, enhancing code readability and maintainability.

Consider adding a test case for an invalid input scenario to ensure proper error handling.

Here's a suggested additional test case:

([100], None),  # Invalid input: less than 2 outcome token amounts

This case would test how the calculate_marginal_prices function handles invalid inputs, ensuring robust error handling.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between e10ab47 and b0ae234.

📒 Files selected for processing (2)
  • prediction_market_agent_tooling/markets/omen/data_models.py (4 hunks)
  • tests/markets/omen/test_omen.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • prediction_market_agent_tooling/markets/omen/data_models.py
🔇 Additional comments (3)
tests/markets/omen/test_omen.py (3)

9-21: LGTM: New imports added for enhanced functionality.

The new imports from the prediction_market_agent_tooling package are appropriate for the added test function and enhance the overall functionality of the test suite.


282-283: LGTM: Improved readability with empty lines.

The addition of empty lines enhances the readability of the test file by clearly separating the new test function from the existing ones.


Line range hint 1-296: Summary: Enhancements to the Omen market test suite.

The changes to this file improve the test coverage and readability of the Omen market test suite. Key improvements include:

  1. Addition of new imports to support enhanced functionality.
  2. Improved code structure with better separation between test functions.
  3. Implementation of a new test function test_calculate_marginal_prices that efficiently covers multiple scenarios for the calculate_marginal_prices function.

These changes contribute to a more robust and comprehensive test suite for the Omen market functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants