Skip to content

Commit

Permalink
add example for redeeming withdrawal shares automatically (#1713)
Browse files Browse the repository at this point in the history
  • Loading branch information
dpaiton authored Oct 24, 2024
1 parent 5b6458b commit 6d69fa8
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 10 deletions.
52 changes: 52 additions & 0 deletions examples/redeem_withdrawal_shares.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Script automatically redeeming withdrwal shares.
The script iteratively checks all deployed testnet pools for events that would
trigger releasing idle liquidity, and then attempts to redeem withdrawal shares.
"""

import os
import time

from dotenv import load_dotenv

from agent0 import Chain, Hyperdrive

load_dotenv(".env")

RPC_URI = os.getenv("RPC_URI", "")
PRIVATE_KEY = os.getenv("PRIVATE_KEY")
# Address of Hyperdrive Sepolia registry
REGISTRY_ADDRESS = "0x03f6554299acf544ac646305800f57db544b837a"

with Chain(RPC_URI) as chain:
start_block = chain.block_number()

print("Scanning pools & redeeming withdrawal shares when possible...")
print(f"Start block: {start_block}")
while True:
with Chain(RPC_URI) as chain:
print(f"block number: {chain.block_number()}")
registered_pools = Hyperdrive.get_hyperdrive_pools_from_registry(
chain,
registry_address=REGISTRY_ADDRESS,
)
# Initialize agent with private key for transactions
agent = chain.init_agent(private_key=PRIVATE_KEY)
for pool in registered_pools:
# Withdraw all ready LP shares
events = pool.get_trade_events()
# Check if any recent events have occured that free up idle liquidity
idle_increase_events = not events[
(events["block_number"] >= start_block)
& events["event_type"].isin(
["AddLiquidity", "OpenLong", "OpenShort", "CloseLong", "CloseShort", "Checkpoint"]
)
].empty
if idle_increase_events:
start_block = chain.block_number()
withdrawal_shares = agent.get_withdrawal_shares(pool=pool)
if withdrawal_shares > 0:
print(f"Redeem {withdrawal_shares} withdrawal shares on {pool.name}")
agent.redeem_withdrawal_shares(withdrawal_shares, pool=pool)
# sleep for 1 minute
time.sleep(60)
5 changes: 5 additions & 0 deletions src/agent0/chainsync/db/hyperdrive/event_getters.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ def get_event_logs_for_db(
# If not in lookup, we default to `earliest`
from_block = EARLIEST_BLOCK_LOOKUP.get(chain_id, "earliest")

# If the from block specified is a specific block number, make sure it's not a pending block
# If it's past the latest block, no events to return
if isinstance(from_block, int) and from_block > hyperdrive_interface.web3.eth.block_number:
return []

out_events = [
_event_data_to_dict(e, numeric_args_as_str)
for e in event_class.get_logs(from_block=from_block, argument_filters=argument_filters)
Expand Down
4 changes: 0 additions & 4 deletions src/agent0/core/hyperdrive/interactive/hyperdrive.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,6 @@ def get_positions(
def get_trade_events(self, all_token_deltas: bool = False, coerce_float: bool = False) -> pd.DataFrame:
"""Gets the ticker history of all trades and the corresponding token deltas for each trade.
This function is not implemented for remote hyperdrive, as gathering this data
is expensive. In the future, we can explicitly make this call gather data from
the remote chain.
Arguments
---------
all_token_deltas: bool
Expand Down
2 changes: 1 addition & 1 deletion src/agent0/core/hyperdrive/interactive/hyperdrive_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ def remove_liquidity(self, shares: FixedPoint, pool: Hyperdrive | None = None) -
assert isinstance(hyperdrive_event, RemoveLiquidityEventFP)
return hyperdrive_event

def redeem_withdrawal_share(
def redeem_withdrawal_shares(
self, shares: FixedPoint, pool: Hyperdrive | None = None
) -> RedeemWithdrawalSharesEventFP:
"""Redeems withdrawal shares for this agent.
Expand Down
4 changes: 3 additions & 1 deletion src/agent0/core/hyperdrive/interactive/hyperdrive_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,9 @@ def test_remote_funding_and_trades(fast_chain_fixture: LocalChain):
# Redeem withdrawal shares
# Note that redeeming withdrawal shares for more than available in the pool
# will pull out as much withdrawal shares as possible
redeem_event = hyperdrive_agent0.redeem_withdrawal_share(shares=remove_liquidity_event.args.withdrawal_share_amount)
redeem_event = hyperdrive_agent0.redeem_withdrawal_shares(
shares=remove_liquidity_event.args.withdrawal_share_amount
)
assert (
hyperdrive_agent0.get_wallet().withdraw_shares
== remove_liquidity_event.args.withdrawal_share_amount - redeem_event.args.withdrawal_share_amount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ def remove_liquidity(self, shares: FixedPoint, pool: Hyperdrive | None = None) -
pool._maybe_run_blocking_data_pipeline() # pylint: disable=protected-access
return out

def redeem_withdrawal_share(
def redeem_withdrawal_shares(
self, shares: FixedPoint, pool: Hyperdrive | None = None
) -> RedeemWithdrawalSharesEventFP:
"""Redeems withdrawal shares for this agent.
Expand All @@ -408,7 +408,7 @@ def redeem_withdrawal_share(
raise ValueError("Remove withdrawal shares requires an active pool.")

self._ensure_approval_set(pool)
out = super().redeem_withdrawal_share(shares, pool)
out = super().redeem_withdrawal_shares(shares, pool)
pool._maybe_run_blocking_data_pipeline() # pylint: disable=protected-access
return out

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ def test_funding_and_trades(fast_chain_fixture: LocalChain, deploy_type: LocalHy

# Redeem withdrawal shares
wallet_before = hyperdrive_agent_0.get_wallet()
redeem_event_0 = hyperdrive_agent_0.redeem_withdrawal_share(
redeem_event_0 = hyperdrive_agent_0.redeem_withdrawal_shares(
shares=remove_liquidity_event_0.args.withdrawal_share_amount
)
wallet_after = hyperdrive_agent_0.get_wallet()
Expand All @@ -500,7 +500,7 @@ def test_funding_and_trades(fast_chain_fixture: LocalChain, deploy_type: LocalHy

# Redeem withdrawal shares
wallet_before = hyperdrive_agent_1.get_wallet()
redeem_event_1 = hyperdrive_agent_1.redeem_withdrawal_share(
redeem_event_1 = hyperdrive_agent_1.redeem_withdrawal_shares(
shares=remove_liquidity_event_1.args.withdrawal_share_amount
)
wallet_after = hyperdrive_agent_1.get_wallet()
Expand Down

0 comments on commit 6d69fa8

Please sign in to comment.