Skip to content

Commit

Permalink
more formatting (live with michael)
Browse files Browse the repository at this point in the history
  • Loading branch information
liav-certora committed Jan 6, 2025
1 parent cc4dcac commit ef711fc
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 34 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ CustomerClones/
**.DS_Store
!**cached_llm.py
quorum_project/
dist/
4 changes: 2 additions & 2 deletions Quorum/apis/git_api/git_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def __clone_or_update_for_repo(repo_name: str, repo_url: str, to_path: Path):
repo.git.pull()
repo.git.submodule('update', '--init', '--recursive')
else:
pp.pprint(f"Cloning {repo_name} from URL: {repo_url} to {repo_path}...", pp.Colors.INFO)
pp.pprint(f'Cloning {repo_name} from URL: {repo_url} to {repo_path}...', pp.Colors.INFO)
Repo.clone_from(repo_url, repo_path, multi_options=["--recurse-submodules"])


Expand All @@ -68,7 +68,7 @@ def clone_or_update(self) -> None:
If the repository already exists locally, it will update the repository and its submodules.
Otherwise, it will clone the repository and initialize submodules.
"""
pp.pprint('Cloning and updating preliminaries', pp.Colors.INFO)
pp.pprint('Cloning and updating preliminaries', pp.Colors.INFO, pp.Heading.HEADING_2)
for repo_name, repo_url in self.repos.items():
GitManager.__clone_or_update_for_repo(repo_name, repo_url, self.modules_path)

Expand Down
2 changes: 1 addition & 1 deletion Quorum/checks/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def __print_diffs_results(self, missing_files: list[SourceCode], files_with_diff
num_identical = num_total_files - num_missing_files - num_diff_files

# Identical files message.
pp.pprint(f'Files found identical: {num_identical}/{num_total_files}', pp.Colors.SUCCESS)
pp.pprint(f'Files found identical: {num_identical}/{num_total_files}\n', pp.Colors.SUCCESS)

# Diffs files message.
if num_diff_files > 0:
Expand Down
27 changes: 15 additions & 12 deletions Quorum/checks/new_listing.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,35 @@ def new_listing_check(self) -> None:
"""
functions = self._get_functions_from_source_codes()
if functions.get('newListings', functions.get('newListingsCustom')):
pp.pprint(f"New listings detected for {self.proposal_address}", pp.Colors.WARNING)
pp.pprint(f'New listings detected for payload {self.proposal_address}', pp.Colors.WARNING)

# Check if Anthropic API key is configured
if not config.ANTHROPIC_API_KEY:
proposal_code = self.source_codes[0].file_content
proposal_code_str = '\n'.join(proposal_code)
try:
listings: ListingArray | None = FirstDepositChain().execute(proposal_code_str)
except:
pp.pprint(
'New listings were detected in payload but first deposit check is skipped.\n'
'If you have a LLM API key, you can add it to your environment variables to enable this check',
pp.Colors.WARNING
)
return

proposal_code = self.source_codes[0].file_content
proposal_code_str = '\n'.join(proposal_code)
listings: ListingArray | None = FirstDepositChain().execute(proposal_code_str)
if listings is None:
pp.pprint('New listings were detected in payload but LLM failed to retrieve them.',
pp.Colors.FAILURE)
return

msg = f'{len(listings.listings)} new asset listings were detected:\n'
pp.pprint(f'{len(listings.listings)} new asset listings were detected:', pp.Colors.INFO)
for i, listing in enumerate(listings.listings, 1):
if listing.approve_indicator and listing.supply_indicator:
msg += f'\t{i}. New listing detected for {listing.asset_symbol}\n'
else:
msg += f'\t{i}. New listing detected for {listing.asset_symbol} but no approval or supply detected\n'
pp.pprint(msg, pp.Colors.INFO)
pp.pprint(f'\t{i}. Variable: {listing.asset_symbol}\n'
f'\t Asset address: {listing.asset_address}\n'
f'\t Approve indicator: {listing.approve_indicator}\n'
f'\t Supply seed amount: {listing.supply_seed_amount}\n'
f'\t Supply indicator: {listing.supply_indicator}',
(pp.Colors.SUCCESS if listing.approve_indicator and listing.supply_indicator
else pp.Colors.FAILURE))

self._write_to_file('new_listings.json', listings.model_dump())

else:
Expand Down
6 changes: 3 additions & 3 deletions Quorum/checks/price_feed.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,14 @@ def verify_price_feed(self) -> None:
self._write_to_file(verified_sources_path, verified_variables)

num_addresses = len(all_addresses)
pp.pprint(f'{num_addresses} addresses identified in the payload.', pp.Colors.INFO)
pp.pprint(f'{num_addresses} addresses identified in the payload.\n', pp.Colors.INFO)

coingecko_name = CoinGeckoAPI().get_name()
token_validation_res = {r for r in overall_verified_vars if r.found_on == coingecko_name}
price_feed_validation_res = overall_verified_vars - token_validation_res

# Print price feed validation
pp.pprint('Price feed validation', pp.Colors.INFO)
pp.pprint('Price Feed Validation', pp.Colors.INFO, pp.Heading.HEADING_3)
msg = (f'{len(price_feed_validation_res)}/{num_addresses} '
'were identified as price feeds of the configured providers:\n')
for i, var_res in enumerate(price_feed_validation_res, 1):
Expand All @@ -119,7 +119,7 @@ def verify_price_feed(self) -> None:
pp.pprint(msg, pp.Colors.SUCCESS)

# Print token validation
pp.pprint('Token validation', pp.Colors.INFO)
pp.pprint('Token Validation', pp.Colors.INFO, pp.Heading.HEADING_3)
msg = (f'{len(token_validation_res)}/{num_addresses} '
'were identified as tokens of the configured providers:\n')
for i, var_res in enumerate(token_validation_res, 1):
Expand Down
29 changes: 17 additions & 12 deletions Quorum/entry_points/check_proposal.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def proposals_check(customer: str, chain: Chain, proposal_addresses: list[str],
api = ChainAPI(chain)

for proposal_address in proposal_addresses:
pp.pprint(f'Analyzing payload {proposal_address} on {chain}', pp.Colors.INFO, is_heading=True)
pp.pprint(f'Analyzing payload {proposal_address} on {chain}', pp.Colors.INFO, pp.Heading.HEADING_1)

try:
source_codes = api.get_source_code(proposal_address)
Expand All @@ -82,38 +82,40 @@ def proposals_check(customer: str, chain: Chain, proposal_addresses: list[str],
continue

# Diff check
pp.pprint('Check 1 - Comparing payload contract and imports with the source of truth', pp.Colors.INFO)
pp.pprint('Check 1 - Comparing payload contract and imports with the source of truth',
pp.Colors.INFO, pp.Heading.HEADING_2)
missing_files = Checks.DiffCheck(customer, chain, proposal_address, source_codes).find_diffs()
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)

# Review diff check
pp.pprint(f'Check 2 - Verifying missing files against customer review repo', pp.Colors.INFO)
pp.pprint(f'Check 2 - Verifying missing files against customer review repo',
pp.Colors.INFO, pp.Heading.HEADING_2)
Checks.ReviewDiffCheck(customer, chain, proposal_address, missing_files).find_diffs()
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)

# Global variables check
pp.pprint('Check 3 - Global variables', pp.Colors.INFO)
pp.pprint('Check 3 - Global variables', pp.Colors.INFO, pp.Heading.HEADING_2)
Checks.GlobalVariableCheck(customer, chain, proposal_address, missing_files).check_global_variables()
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)

# Feed price check
pp.pprint('Check 4 - Explicit addresses validation', pp.Colors.INFO)
pp.pprint('Check 4 - Explicit addresses validation', pp.Colors.INFO, pp.Heading.HEADING_2)
Checks.PriceFeedCheck(customer, chain, proposal_address, missing_files, providers).verify_price_feed()
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)

# New listing check
pp.pprint('Check 5 - First deposit for new listing', pp.Colors.INFO)
pp.pprint('Check 5 - First deposit for new listing', pp.Colors.INFO, pp.Heading.HEADING_2)
Checks.NewListingCheck(customer, chain, proposal_address, missing_files).new_listing_check()
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)


def format_metadata(customer: str, chain_info: dict[str, list[str]]) -> str:
msg = f'Customer: {customer}\nChains and payloads:\n'
for chain, addresses in chain_info.items():
if len(addresses) == 0:
if len(addresses['Proposals']) == 0:
continue
msg += f'* {chain}:\n'
for address in addresses:
for address in addresses['Proposals']:
msg += f'\t- {address}\n'
return msg

Expand All @@ -130,13 +132,13 @@ def main() -> None:
if config_data:
# Multi-task mode using JSON configuration
for customer, chain_info in config_data.items():
pp.pprint('Run Preparation', pp.Colors.INFO, is_heading=True)
pp.pprint('Run Preparation', pp.Colors.INFO, pp.Heading.HEADING_1)
ground_truth_config = ConfigLoader.load_customer_config(customer)
GitManager(customer, ground_truth_config).clone_or_update()
price_feed_providers = ground_truth_config.get('price_feed_providers', [])
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)

pp.pprint('Run Metadata', pp.Colors.INFO, is_heading=True)
pp.pprint('Run Metadata', pp.Colors.INFO, pp.Heading.HEADING_2)
pp.pprint(format_metadata(customer, chain_info), pp.Colors.INFO)
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)
for chain, proposals in chain_info.items():
Expand All @@ -148,12 +150,15 @@ def main() -> None:
# Single-task mode using command line arguments
if not (customer and chain and proposal_address):
raise ValueError("Customer, chain, and proposal_address must be specified if not using a config file.")
pp.pprint('Run Preparation', pp.Colors.INFO)
pp.pprint('Run Preparation', pp.Colors.INFO, pp.Heading.HEADING_1)
ground_truth_config = ConfigLoader.load_customer_config(customer)
GitManager(customer, ground_truth_config).clone_or_update()
price_feed_providers = ground_truth_config.get("price_feed_providers", [])
pp.pprint('Run Metadata', pp.Colors.INFO)
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)

pp.pprint('Run Metadata', pp.Colors.INFO, pp.Heading.HEADING_2)
pp.pprint(f'Customer: {customer}\nChains and payloads:\n{chain}: {proposal_address}', pp.Colors.INFO)
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)
proposals_check(customer, chain, [proposal_address], price_feed_providers)


Expand Down
13 changes: 10 additions & 3 deletions Quorum/utils/pretty_printer.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
from enum import StrEnum
from typing import Optional


SEPARATOR_LINE = '\n' + '-' * 110 + '\n'


class Heading(StrEnum):
HEADING_1 = '='
HEADING_2 = '-'
HEADING_3 = '.'


class Colors(StrEnum):
SUCCESS = '\033[92m'
FAILURE = '\033[91m'
Expand All @@ -12,8 +19,8 @@ class Colors(StrEnum):
RESET = '\033[0m'


def pprint(message: str, status: Colors, is_heading: bool = False):
def pprint(message: str, status: Colors, heading: Optional[Heading]=None):
s = status + message + Colors.RESET
if is_heading:
s += '\n' + '-' * len(message)
if heading:
s += '\n' + heading * len(message) + '\n'
print(s)
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250105.235907.619968
20250106.181023.639435

0 comments on commit ef711fc

Please sign in to comment.