Skip to content

Commit

Permalink
Merge pull request #26 from cowprotocol/coingecko-edits
Browse files Browse the repository at this point in the history
Coingecko Edits (from discussion)
  • Loading branch information
harisang authored Aug 8, 2024
2 parents 92b1a16 + e7e94e1 commit 25207fc
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 11 deletions.
39 changes: 31 additions & 8 deletions src/coingecko_pricing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import json
from web3 import Web3
from src.config import logger
from src.constants import NATIVE_ETH_TOKEN_ADDRESS
from src.helper_functions import get_finalized_block_number
from src.constants import NATIVE_ETH_TOKEN_ADDRESS, WETH_TOKEN_ADDRESS

coingecko_api_key = os.getenv("COINGECKO_API_KEY")

Expand All @@ -21,7 +22,7 @@ def get_token_id_by_address(cleaned_token_list, token_address):
return None


def get_api_price(
def fetch_api_price(
token_id: str, start_timestamp: int, end_timestamp: int
) -> Optional[float]:
"""
Expand Down Expand Up @@ -53,30 +54,52 @@ def get_api_price(
return None


def price_not_retrievable(web3: Web3, block_start_timestamp: int) -> bool:
"""
This function checks if the time elapsed between the latest block and block being processed
is less than 2 days, which is coingecko's time frame for fetching 5-minutely data.
"""
# Time in seconds of 45 hours.
COINGECKO_TIME_LIMIT = 162000
newest_block_timestamp = web3.eth.get_block(get_finalized_block_number(web3))[
"timestamp"
]
return (newest_block_timestamp - block_start_timestamp) > COINGECKO_TIME_LIMIT


def get_price(web3: Web3, block_number: int, token_address: str, tx_hash: str):
"""
Function returns coingecko price for a token address,
closest to and at least as large as the block timestamp for a given tx hash.
"""

block_start_timestamp = web3.eth.get_block(block_number)["timestamp"]
if price_not_retrievable(web3, block_start_timestamp):
return None

# Coingecko doesn't store ETH address, which occurs commonly in imbalances.
if Web3.to_checksum_address(token_address) == NATIVE_ETH_TOKEN_ADDRESS:
# Approximate WETH price as equal to ETH.
if Web3.to_checksum_address(token_address) in (
NATIVE_ETH_TOKEN_ADDRESS,
WETH_TOKEN_ADDRESS,
):
return 1.0

token_address = token_address.lower()
data = web3.eth.get_block(block_number)
start_timestamp = data["timestamp"]
# We need to provide a sufficient buffer time for fetching 5-minutely prices from coingecko.
# If too short, it's possible that no price may be returned. We use the first value returned,
# which would be closest to block timestamp
BUFFER_TIME = 600
end_timestamp = start_timestamp + BUFFER_TIME
block_end_timestamp = block_start_timestamp + BUFFER_TIME

token_address = token_address.lower()
token_id = get_token_id_by_address(cleaned_token_list, token_address)
if not token_id:
logger.warning(f"Token ID not found for the given address: {token_address}")
return None
try:
api_price = get_api_price(token_id, start_timestamp, end_timestamp)
api_price = fetch_api_price(
token_id, block_start_timestamp, block_end_timestamp
)
if api_price is None:
logger.warning(f"API returned None for token ID: {token_id}")
return None
Expand Down
3 changes: 0 additions & 3 deletions src/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,6 @@ def process_transactions(chain_name: str) -> None:
) = initialize_connections()
rt = RawTokenImbalances(web3, chain_name)
start_block = get_start_block(web3, chain_name, solver_slippage_db_connection)
## this is just saying that the start block should be hardcoded in case the script restarts a few hours after that specific block
if start_block - 12000 < 20420000:
start_block = 20420000
previous_block = start_block
unprocessed_txs: List[Tuple[str, int, int]] = []

Expand Down

0 comments on commit 25207fc

Please sign in to comment.