Skip to content

Commit

Permalink
feat(monitor): Optimize monitor for rpc and hermes usage (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
m30m authored Mar 28, 2024
1 parent 95ba434 commit d52e62f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 37 deletions.
1 change: 1 addition & 0 deletions per_multicall/src/TokenVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ contract TokenVault is IExpressRelayFeeReceiver {
_allowUndercollateralized = allowUndercollateralized;
}

//TODO: Fix function name/logic/documentation to match each other
/**
* @notice getLastVaultId function - getter function to get the id of the next vault to be created
* Ids are sequential and start from 0
Expand Down
69 changes: 34 additions & 35 deletions per_sdk/protocols/token_vault_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ def __init__(
)
self.price_feed_client = PriceFeedClient([])

async def get_accounts(self) -> list[ProtocolAccount]:
async def get_recent_accounts(self, count: int) -> list[ProtocolAccount]:
"""
Returns all the open accounts in the protocol in the form of a list of type ProtocolAccount.
Returns the last `count` accounts in the protocol in the form of a list of type ProtocolAccount.
Args:
rpc_url (str): The RPC URL of the chain
count: The number of most recent accounts to return.
Returns:
List of objects of type ProtocolAccount (defined above). Each ProtocolAccount object represents an account/vault in the protocol.
"""
Expand All @@ -83,31 +83,27 @@ async def get_accounts(self) -> list[ProtocolAccount]:
vault_struct = [x["name"] for x in get_vault_details]

accounts = []
done = False
account_number = 0

while not done:
last_account_number = await self.token_vault.functions.getLastVaultId().call()
for account_number in range(
max(0, last_account_number - count), last_account_number
):
vault = await self.token_vault.functions.getVault(account_number).call()
vault_dict = dict(zip(vault_struct, vault))

if int(vault_dict["tokenCollateral"], 16) == 0: # vault is not created yet
done = True
else:
account: ProtocolAccount = {
"account_number": account_number,
"token_address_collateral": vault_dict["tokenCollateral"],
"token_id_collateral": vault_dict["tokenIdCollateral"].hex(),
"token_address_debt": vault_dict["tokenDebt"],
"token_id_debt": vault_dict["tokenIdDebt"].hex(),
"amount_collateral": vault_dict["amountCollateral"],
"amount_debt": vault_dict["amountDebt"],
"min_health_ratio": vault_dict["minHealthRatio"],
"min_permissionless_health_ratio": vault_dict[
"minPermissionlessHealthRatio"
],
}
accounts.append(account)
account_number += 1
account: ProtocolAccount = {
"account_number": account_number,
"token_address_collateral": vault_dict["tokenCollateral"],
"token_id_collateral": vault_dict["tokenIdCollateral"].hex(),
"token_address_debt": vault_dict["tokenDebt"],
"token_id_debt": vault_dict["tokenIdDebt"].hex(),
"amount_collateral": vault_dict["amountCollateral"],
"amount_debt": vault_dict["amountDebt"],
"min_health_ratio": vault_dict["minHealthRatio"],
"min_permissionless_health_ratio": vault_dict[
"minPermissionlessHealthRatio"
],
}
accounts.append(account)
account_number += 1

return accounts

Expand Down Expand Up @@ -208,18 +204,21 @@ async def get_liquidation_opportunities(self) -> list[Opportunity]:
"""

liquidatable = []
accounts = await self.get_accounts()
# just get the last 5 accounts to optimize for rpc calls
accounts = await self.get_recent_accounts(5)
price_ids = set()
for account in accounts:
price_ids.add(account["token_id_collateral"])
price_ids.add(account["token_id_debt"])
price_ids = list(price_ids)
prices = await self.price_feed_client.get_pyth_prices_latest(price_ids)
price_dict = dict(zip(price_ids, prices))
for account in accounts:
# vault is already liquidated
if account["amount_collateral"] == 0 and account["amount_debt"] == 0:
continue
# TODO: optimize this to only query for the price feeds that are needed and only query once
(
price_collateral,
price_debt,
) = await self.price_feed_client.get_pyth_prices_latest(
[account["token_id_collateral"], account["token_id_debt"]]
)
price_collateral = price_dict.get(account["token_id_collateral"])
price_debt = price_dict.get(account["token_id_debt"])
if price_collateral is None:
raise Exception(
f"Price for collateral token {account['token_id_collateral']} not found"
Expand Down Expand Up @@ -350,7 +349,7 @@ async def main():
f"List of liquidatable accounts:\n{json.dumps(opportunities, indent=2)}"
)

await asyncio.sleep(1)
await asyncio.sleep(15)


if __name__ == "__main__":
Expand Down
3 changes: 1 addition & 2 deletions per_sdk/utils/pyth_prices.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import httpx

HERMES_ENDPOINT_HTTPS = "https://hermes.pyth.network/api/"
HERMES_ENDPOINT_HTTPS = "http://hermes-stable.hermes-stable:8080/api/"
HERMES_ENDPOINT_WSS = "wss://hermes.pyth.network/ws"


Expand Down Expand Up @@ -76,7 +76,6 @@ async def get_pyth_prices_latest(self, feedIds: list[str]) -> list[PriceFeed]:
"""
url = HERMES_ENDPOINT_HTTPS + "latest_price_feeds?"
params = {"ids[]": feedIds, "binary": "true"}

data = (await self.client.get(url, params=params)).json()

results = []
Expand Down

0 comments on commit d52e62f

Please sign in to comment.