Skip to content

Commit

Permalink
Merge pull request #300 from emarc99/standardized-interest-rate-and-d…
Browse files Browse the repository at this point in the history
…ebt-transfer-events

added interest_rate_model anddebt_transfer serializers
  • Loading branch information
djeck1432 authored Nov 23, 2024
2 parents eb28f16 + 13e7602 commit 720c420
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 17 deletions.
55 changes: 49 additions & 6 deletions apps/data_handler/handler_tools/data_parser/nostra.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,40 @@
from typing import Any
from data_handler.handler_tools.data_parser.serializers import (
DebtMintEventData,
DebtBurnEventData
DebtBurnEventData,
InterestRateModelEventData,
DebtTransferEventData,
)


class NostraDataParser:
"""
Parses the nostra data to human-readable format.
"""
def parse_interest_rate_model_event(self):
pass
def parse_interest_rate_model_event(
cls, event_data: List[Any]
) -> InterestRateModelEventData:
"""
Parses the interest rate model event data into a human-readable format.
The event data is fetched from on-chain logs and is structured in the following way:
- event_data[0]: The debt token address (as a hexadecimal string).
- event_data[5]: The lending interest rate index (as a hexadecimal in 18 decimal places).
- event_data[7]: The borrow interest rate index (as a hexadecimal in 18 decimal places).
Args:
event_data (List[Any]): A list containing the raw event data.
Expected order: [debt_token, lending_rate, _, borrow_rate, _,
lending_index, _, borrow_index, _]
Returns:
InterestRateModelEventData: A model with the parsed event data.
"""
return InterestRateModelEventData(
debt_token=event_data[0],
lending_index=event_data[5],
borrow_index=event_data[7]
)

def parse_non_interest_bearing_collateral_mint_event(self):
pass
Expand All @@ -27,8 +51,27 @@ def parse_interest_bearing_collateral_mint_event(self):
def parse_interest_bearing_collateral_burn_event(self):
pass

def parse_debt_transfer_event(self):
pass
def parse_debt_transfer_event(
cls, event_data: List[Any], from_address: str
) -> DebtTransferEventData:
"""
Parses the debt transfer event data into a human-readable format using the
DebtBurnEventData serializer.
Args:
event_data (List[Any]): A list containing the raw event data.
Expected order: [sender, recipient, value, _]
from_address (str): The address of the token contract
Returns:
DebtTransferEventData: A model with the parsed event data.
"""
return DebtTransferEventData(
sender=event_data[0],
recipient=event_data[1],
amount=event_data[2],
token=from_address
)

def parse_debt_mint_event(self, event_data: list[Any]) -> DebtMintEventData:
"""
Expand Down Expand Up @@ -62,4 +105,4 @@ def parse_debt_burn_event(self, event_data: list[Any]) -> DebtBurnEventData:
return DebtBurnEventData(
user=event_data[0],
amount=event_data[1]
)
)
73 changes: 72 additions & 1 deletion apps/data_handler/handler_tools/data_parser/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,4 +444,75 @@ def validate_numeric_string(cls, value: str, info: ValidationInfo) -> Decimal:
except ValueError:
raise ValueError(
f"{info.field_name} field is not a valid hexadecimal number"
)
)

class InterestRateModelEventData(BaseModel):
"""
Data model representing an interest rate model event in the Nostra protocol.
Attributes:
debt_token (str): The address of the debt token.
lending_index (Decimal): The lending index in hexadecimal.
borrow_index (Decimal): The borrow index in hexadecimal.
"""
debt_token: str
lending_index: Decimal
borrow_index: Decimal

@field_validator("debt_token")
def validate_address(cls, value: str, info: ValidationInfo) -> str:
"""
Validates and formats the token address.
"""
if not value.startswith("0x"):
raise ValueError(f"Invalid address provided for {info.field_name}")
return add_leading_zeros(value)

@field_validator("lending_index", "borrow_index")
def validate_numeric_string(cls, value: str, info: ValidationInfo) -> Decimal:
"""
Converts a hexadecimal string to a Decimal.
Validates that the provided value is numeric, and converts it to a proper Decimal number.
"""
try:
return Decimal(int(value, 16)) / Decimal("1e18")
except ValueError:
raise ValueError(
f"{info.field_name} field is not a valid hexadecimal number"
)

class DebtTransferEventData(BaseModel):
"""
Data model representing a debt transfer event.
Attributes:
sender (str): Address of the sender.
recipient (str): Address of the recipient.
amount (str): Transfer amount in hexadecimal.
token (str): Address of the debt token.
"""
sender: str
recipient: str
amount: Decimal

@field_validator("sender", "recipient")
def validate_address(cls, value: str, info: ValidationInfo) -> str:
"""
Validates and formats the address.
"""
if not value.startswith("0x"):
raise ValueError(f"Invalid address provided for {info.field_name}")
return add_leading_zeros(value)

@field_validator("amount")
def validate_numeric_string(cls, value: str, info: ValidationInfo) -> Decimal:
"""
Validates that the provided amount is numeric and converts it to a Decimal.
"""
try:
return Decimal(int(value, 16))
except ValueError:
raise ValueError(
f"{info.field_name} field is not a valid hexadecimal number"
)

21 changes: 11 additions & 10 deletions apps/data_handler/handlers/loan_states/nostra_alpha/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,16 +340,16 @@ def process_interest_rate_model_event(self, event: pd.Series) -> None:
# `lendIndex`, ``, `borrowIndex`, ``.
# Example:
# https://starkscan.co/event/0x05e95588e281d7cab6f89aa266057c4c9bcadf3ff0bb85d4feea40a4faa94b09_4.
debt_token = add_leading_zeros(event["data"][0])
collateral_interest_rate_index = decimal.Decimal(str(int(event["data"][5], base=16))
) / decimal.Decimal("1e18")
debt_interest_rate_index = decimal.Decimal(str(int(event["data"][7], base=16))
) / decimal.Decimal("1e18")
# Parse the event using the new serializer
data = NostraDataParser.parse_interest_rate_model_event(event["data"])
debt_token = parsed_event_data.debt_token
collateral_interest_rate_index = parsed_event_data.lending_index
debt_interest_rate_index = parsed_event_data.borrow_index
else:
raise ValueError("Event = {} has an unexpected structure.".format(event))

collateral_token = self.debt_token_addresses_to_interest_bearing_collateral_token_addresses.get(
debt_token, None
)
debt_token, None)
# The indices are saved under the respective collateral or debt token address.
if collateral_token:
self.interest_rate_models.collateral[collateral_token] = (
Expand Down Expand Up @@ -463,9 +463,10 @@ def process_debt_transfer_event(self, event: pd.Series) -> None:
# `from_`, `to`, `value`, ``.
# Example:
# https://starkscan.co/event/0x0786a8918c8897db760899ee35b43071bfd723fec76487207882695e4b3014a0_1.
sender = add_leading_zeros(event["data"][0])
recipient = add_leading_zeros(event["data"][1])
raw_amount = decimal.Decimal(str(int(event["data"][2], base=16)))
event_data = NostraDataParser.parse_debt_transfer_event(event["data"])
sender = event_data.sender
recipient = event_data.recipient
raw_amount = event_data.amount
else:
raise ValueError("Event = {} has an unexpected structure.".format(event))
if self.ZERO_ADDRESS in {sender, recipient}:
Expand Down

0 comments on commit 720c420

Please sign in to comment.