Skip to content

Commit

Permalink
coingecko changes
Browse files Browse the repository at this point in the history
  • Loading branch information
shubhagarwal03 committed Aug 3, 2024
1 parent 92b1a16 commit 712e764
Showing 1 changed file with 32 additions and 8 deletions.
40 changes: 32 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,53 @@ def get_api_price(
return None


def price_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"
]
if (newest_block_timestamp - block_start_timestamp) > COINGECKO_TIME_LIMIT:
return True


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_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

0 comments on commit 712e764

Please sign in to comment.