Skip to content

Instantly share code, notes, and snippets.

@williamsfu99
Created February 2, 2022 20:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save williamsfu99/47657f09108a048fb95ae83663466ac1 to your computer and use it in GitHub Desktop.
Save williamsfu99/47657f09108a048fb95ae83663466ac1 to your computer and use it in GitHub Desktop.
Python example of Leveraged Index Strategy Rebalancing
import os
from web3 import Web3
# Populate these fields.
WEB3_PROVIDER = Web3(Web3.HTTPProvider('https://<your-provider-url>'))
LEVERAGE_STRATEGY_ADAPTER_ADDRESS = '<your-strategy-address-here>'
LEVERAGE_REBALANCE_VIEWER_ADDRESS = '<your-viewer-address-here>'
LEVERAGE_STRATEGY_ADAPTER_ABI = '[<your ABI>]'
LEVERAGE_REBALANCE_VIEWER_ABI = '[<your ABI>]'
# Store more sensitive values as environment variables.
KEEPER_WALLET_ADDRESS = 'KEEPER_WALLET_ADDRESS'
KEEPER_PRIVATE_KEY = 'KEEPER_PRIVATE_KEY'
class SetKeeper:
def __init__(self, provider, strategy_adapter_address, rebalance_viewer_address):
self.provider = provider
self.strategy_adapter_address = strategy_adapter_address
self.rebalance_viewer_address = rebalance_viewer_address
def get_account(self):
return (os.environ[KEEPER_WALLET_ADDRESS], os.environ[KEEPER_PRIVATE_KEY])
def get_rebalance_state_with_bounds(self, lower_bound, upper_bound):
from_address, _ = self.get_account()
contract_instance = self.provider.eth.contract(address=self.rebalance_viewer_address, abi=LEVERAGE_REBALANCE_VIEWER_ABI)
exchange_name, should_rebalance = contract_instance.functions.shouldRebalanceWithBounds(
Web3.toWei(lower_bound, 'ether'),
Web3.toWei(upper_bound, 'ether')
).call(
{
'from': from_address
}
)
return (exchange_name, should_rebalance)
def get_transaction_params(self, from_address, function_name, exchange_name):
nonce = self.provider.eth.get_transaction_count(from_address)
contract_instance = self.provider.eth.contract(address=self.strategy_adapter_address, abi=LEVERAGE_STRATEGY_ADAPTER_ABI)
encoded_data = contract_instance.encodeABI(fn_name=function_name, args=[exchange_name])
tx_data = {
'from': from_address,
'to': self.strategy_adapter_address,
'nonce': Web3.toHex(nonce),
'gasLimit': Web3.toHex(1000000),
'chainId': 10,
'data': encoded_data,
}
return tx_data
def rebalance(self, exchange_name):
from_address, private_key = self.get_account()
transaction = self.get_transaction_params(from_address, 'rebalance', exchange_name)
signed = self.provider.eth.account.signTransaction(transaction, private_key)
return self.provider.sendRawTransaction(signed.rawTransaction)
def iterate(self, exchange_name):
from_address, private_key = self.get_account()
transaction = self.get_transaction_params(from_address, 'iterateRebalance', exchange_name)
signed = self.provider.eth.account.signTransaction(transaction, private_key)
return self.provider.sendRawTransaction(signed.rawTransaction)
def ripcord(self, exchange_name):
from_address, private_key = self.get_account()
transaction = self.get_transaction_params(from_address, 'ripcord', exchange_name)
signed = self.provider.eth.account.signTransaction(transaction, private_key)
return self.provider.sendRawTransaction(signed.rawTransaction)
# Keeper runtime, repeat on a cronjob
keeper = SetKeeper(WEB3_PROVIDER, LEVERAGE_STRATEGY_ADAPTER_ADDRESS, LEVERAGE_REBALANCE_VIEWER_ADDRESS)
exchange_name, should_rebalance = keeper.get_rebalance_state_with_bounds(1.7, 2.3)
if should_rebalance == 1:
keeper.rebalance(exchange_name)
elif should_rebalance == 2:
keeper.iterate(exchange_name)
elif should_rebalance == 3:
keeper.ripcord(exchange_name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment