def __init__(self, args, **kwargs): parser = argparse.ArgumentParser("dsrdemo") parser.add_argument( "--eth-from", type=str, required=True, help= "Ethereum address from which to send transactions; checksummed (e.g. '0x12AebC')" ) parser.add_argument("--rpc-host", type=str, default="localhost", help="JSON-RPC host (default: `localhost')") parser.add_argument( "--network", type=str, required=True, help= "Network that you're running the Keeper on (options, 'mainnet', 'kovan', 'testnet')" ) parser.add_argument("--rpc-port", type=int, default=8545, help="JSON-RPC port (default: `8545')") parser.add_argument("--rpc-timeout", type=int, default=10, help="JSON-RPC timeout (in seconds, default: 10)") parser.add_argument( "--eth-key", type=str, nargs='*', help= "Ethereum private key(s) to use (e.g. 'key_file=/path/to/keystore.json,pass_file=/path/to/passphrase.txt')" ) self.arguments = parser.parse_args(args) self.web3 = kwargs['web3'] if 'web3' in kwargs else Web3( HTTPProvider( endpoint_uri= f"https://{self.arguments.rpc_host}:{self.arguments.rpc_port}", request_kwargs={"timeout": self.arguments.rpc_timeout})) self.web3.eth.defaultAccount = self.arguments.eth_from register_keys(self.web3, self.arguments.eth_key) self.our_address = Address(self.arguments.eth_from) # Instantiate the dss and dsr classes self.dss = DssDeployment.from_network(web3=self.web3, network=self.arguments.network) self.dsr = Dsr(self.dss, self.our_address)
def mcd(web3) -> DssDeployment: deployment = DssDeployment.from_network(web3=web3, network="testnet") validate_contracts_loaded(deployment) return deployment
def __init__(self, args: list, **kwargs): """Pass in arguements assign necessary variables/objects and instantiate other Classes""" parser = argparse.ArgumentParser("chief-keeper") parser.add_argument( "--rpc-host", type=str, default="https://localhost:8545", help="JSON-RPC host:port (default: 'localhost:8545')") parser.add_argument("--rpc-timeout", type=int, default=10, help="JSON-RPC timeout (in seconds, default: 10)") parser.add_argument( "--network", type=str, required=True, help= "Network that you're running the Keeper on (options, 'mainnet', 'kovan', 'testnet')" ) parser.add_argument( "--eth-from", type=str, required=True, help= "Ethereum address from which to send transactions; checksummed (e.g. '0x12AebC')" ) parser.add_argument( "--eth-key", type=str, nargs='*', help= "Ethereum private key(s) to use (e.g. 'key_file=/path/to/keystore.json,pass_file=/path/to/passphrase.txt')" ) parser.add_argument( "--dss-deployment-file", type=str, required=False, help= "Json description of all the system addresses (e.g. /Full/Path/To/configFile.json)" ) parser.add_argument( "--chief-deployment-block", type=int, required=False, default=0, help= " Block that the Chief from dss-deployment-file was deployed at (e.g. 8836668" ) parser.add_argument( "--max-errors", type=int, default=100, help= "Maximum number of allowed errors before the keeper terminates (default: 100)" ) parser.add_argument("--debug", dest='debug', action='store_true', help="Enable debug output") parser.add_argument("--ethgasstation-api-key", type=str, default=None, help="ethgasstation API key") parser.add_argument("--gas-initial-multiplier", type=str, default=1.0, help="ethgasstation API key") parser.add_argument("--gas-reactive-multiplier", type=str, default=2.25, help="gas strategy tuning") parser.add_argument("--gas-maximum", type=str, default=5000, help="gas strategy tuning") parser.set_defaults(cageFacilitated=False) self.arguments = parser.parse_args(args) self.web3: Web3 = kwargs['web3'] if 'web3' in kwargs else web3_via_http( endpoint_uri=self.arguments.rpc_host, timeout=self.arguments.rpc_timeout, http_pool_size=100) self.web3.eth.defaultAccount = self.arguments.eth_from register_keys(self.web3, self.arguments.eth_key) self.our_address = Address(self.arguments.eth_from) if self.arguments.dss_deployment_file: self.dss = DssDeployment.from_json( web3=self.web3, conf=open(self.arguments.dss_deployment_file, "r").read()) else: self.dss = DssDeployment.from_network( web3=self.web3, network=self.arguments.network) self.deployment_block = self.arguments.chief_deployment_block self.max_errors = self.arguments.max_errors self.errors = 0 self.confirmations = 0 # Create dynamic gas strategy if self.arguments.ethgasstation_api_key: self.gas_price = DynamicGasPrice(self.arguments, self.web3) else: self.gas_price = DefaultGasPrice() logging.basicConfig( format='%(asctime)-15s %(levelname)-8s %(message)s', level=(logging.DEBUG if self.arguments.debug else logging.INFO))
def mcd(web3): return DssDeployment.from_network(web3=web3, network="testnet")
from pymaker import Address from pymaker.auctions import Flipper, Flapper, Flopper from pymaker.deployment import DssDeployment from pymaker.keys import register_keys from pymaker.numeric import Wad web3 = Web3( HTTPProvider(endpoint_uri="http://0.0.0.0:8545", request_kwargs={"timeout": 10})) web3.eth.defaultAccount = sys.argv[ 1] # ex: 0x0000000000000000000000000000000aBcdef123 register_keys( web3, [sys.argv[2]] ) # ex: key_file=~keys/default-account.json,pass_file=~keys/default-account.pass mcd = DssDeployment.from_network(web3, "kovan") our_address = Address(web3.eth.defaultAccount) # Choose the desired collateral; in this case we'll wrap some Eth collateral = mcd.collaterals['ETH-A'] ilk = collateral.ilk collateral_amount = Wad.from_number(0.03) collateral.gem.deposit(collateral_amount).transact() # Add collateral and allocate the desired amount of Dai collateral.approve(our_address) assert collateral.adapter.join(our_address, collateral_amount).transact() dai_amount = Wad.from_number(0.153) mcd.vat.frob(ilk, our_address, dink=collateral_amount, dart=Wad(0)).transact() mcd.vat.frob(ilk, our_address, dink=Wad(0), dart=dai_amount).transact() print(f"CDP Dai balance before withdrawal: {mcd.vat.dai(our_address)}")
def __init__(self, args: list, **kwargs): """Pass in arguements assign necessary variables/objects and instantiate other Classes""" parser = argparse.ArgumentParser("cage-keeper") parser.add_argument("--rpc-host", type=str, default="localhost", help="JSON-RPC host (default: `localhost')") parser.add_argument("--rpc-port", type=int, default=8545, help="JSON-RPC port (default: `8545')") parser.add_argument("--rpc-timeout", type=int, default=10, help="JSON-RPC timeout (in seconds, default: 10)") parser.add_argument( "--network", type=str, required=True, help= "Network that you're running the Keeper on (options, 'mainnet', 'kovan', 'testnet')" ) parser.add_argument( '--previous-cage', dest='cageFacilitated', action='store_true', help= 'Include this argument if this keeper previously helped to facilitate the processing phase of ES' ) parser.add_argument( "--eth-from", type=str, required=True, help= "Ethereum address from which to send transactions; checksummed (e.g. '0x12AebC')" ) parser.add_argument( "--eth-key", type=str, nargs='*', help= "Ethereum private key(s) to use (e.g. 'key_file=/path/to/keystore.json,pass_file=/path/to/passphrase.txt')" ) parser.add_argument( "--dss-deployment-file", type=str, required=False, help= "Json description of all the system addresses (e.g. /Full/Path/To/configFile.json)" ) parser.add_argument( "--vat-deployment-block", type=int, required=False, default=0, help= " Block that the Vat from dss-deployment-file was deployed at (e.g. 8836668" ) parser.add_argument( "--max-errors", type=int, default=100, help= "Maximum number of allowed errors before the keeper terminates (default: 100)" ) parser.add_argument("--debug", dest='debug', action='store_true', help="Enable debug output") parser.set_defaults(cageFacilitated=False) self.arguments = parser.parse_args(args) self.web3 = kwargs['web3'] if 'web3' in kwargs else Web3( HTTPProvider( endpoint_uri= f"https://{self.arguments.rpc_host}:{self.arguments.rpc_port}", request_kwargs={"timeout": self.arguments.rpc_timeout})) self.web3.eth.defaultAccount = self.arguments.eth_from register_keys(self.web3, self.arguments.eth_key) self.our_address = Address(self.arguments.eth_from) if self.arguments.dss_deployment_file: self.dss = DssDeployment.from_json( web3=self.web3, conf=open(self.arguments.dss_deployment_file, "r").read()) else: self.dss = DssDeployment.from_network( web3=self.web3, network=self.arguments.network) self.deployment_block = self.arguments.vat_deployment_block self.max_errors = self.arguments.max_errors self.errors = 0 self.cageFacilitated = self.arguments.cageFacilitated self.confirmations = 0 logging.basicConfig( format='%(asctime)-15s %(levelname)-8s %(message)s', level=(logging.DEBUG if self.arguments.debug else logging.INFO))
def __init__(self, args: list, **kwargs): parser = argparse.ArgumentParser(prog='auction-keeper') parser.add_argument( "--rpc-host", type=str, default="http://localhost:8545", help= "JSON-RPC endpoint URI with port (default: `http://localhost:8545')" ) parser.add_argument("--rpc-timeout", type=int, default=10, help="JSON-RPC timeout (in seconds, default: 10)") parser.add_argument( "--eth-from", type=str, required=True, help="Ethereum account from which to send transactions") parser.add_argument( "--eth-key", type=str, nargs='*', help= "Ethereum private key(s) to use (e.g. 'key_file=aaa.json,pass_file=aaa.pass')" ) parser.add_argument('--type', type=str, choices=['flip', 'flap', 'flop'], help="Auction type in which to participate") parser.add_argument( '--ilk', type=str, help= "Name of the collateral type for a flip keeper (e.g. 'ETH-B', 'ZRX-A'); " "available collateral types can be found at the left side of the Oasis Borrow" ) parser.add_argument( '--bid-only', dest='create_auctions', action='store_false', help="Do not take opportunities to create new auctions") parser.add_argument('--kick-only', dest='bid_on_auctions', action='store_false', help="Do not bid on auctions") parser.add_argument( '--deal-for', type=str, nargs="+", help="List of addresses for which auctions will be dealt") parser.add_argument('--min-auction', type=int, default=0, help="Lowest auction id to consider") parser.add_argument( '--max-auctions', type=int, default=1000, help="Maximum number of auctions to simultaneously interact with, " "used to manage OS and hardware limitations") parser.add_argument( '--min-flip-lot', type=float, default=0, help="Minimum lot size to create or bid upon a flip auction") parser.add_argument( '--bid-check-interval', type=float, default=4.0, help= "Period of timer [in seconds] used to check bidding models for changes" ) parser.add_argument( '--bid-delay', type=float, default=0.0, help= "Seconds to wait between bids, used to manage OS and hardware limitations" ) parser.add_argument( '--shard-id', type=int, default=0, help= "When sharding auctions across multiple keepers, this identifies the shard" ) parser.add_argument( '--shards', type=int, default=1, help= "Number of shards; should be one greater than your highest --shard-id" ) parser.add_argument( '--from-block', type=int, help= "Starting block from which to find vaults to bite or debt to queue " "(set to block where MCD was deployed)") parser.add_argument( '--chunk-size', type=int, default=20000, help= "When batching chain history requests, this is the number of blocks for each request" ) parser.add_argument( "--tokenflow-url", type=str, help= "When specified, urn history will be initialized using the TokenFlow API" ) parser.add_argument("--tokenflow-key", type=str, help="API key for the TokenFlow endpoint") parser.add_argument( "--vulcanize-endpoint", type=str, help= "When specified, urn history will be initialized from a VulcanizeDB node" ) parser.add_argument("--vulcanize-key", type=str, help="API key for the Vulcanize endpoint") parser.add_argument( '--vat-dai-target', type=str, help= "Amount of Dai to keep in the Vat contract or ALL to join entire token balance" ) parser.add_argument( '--keep-dai-in-vat-on-exit', dest='exit_dai_on_shutdown', action='store_false', help= "Retain Dai in the Vat on exit, saving gas when restarting the keeper" ) parser.add_argument('--keep-gem-in-vat-on-exit', dest='exit_gem_on_shutdown', action='store_false', help="Retain collateral in the Vat on exit") parser.add_argument( '--return-gem-interval', type=int, default=300, help= "Period of timer [in seconds] used to check and exit won collateral" ) parser.add_argument( "--model", type=str, nargs='+', help="Commandline to use in order to start the bidding model") parser.add_argument( "--oracle-gas-price", action='store_true', help="Use a fast gas price aggregated across multiple oracles") parser.add_argument("--ethgasstation-api-key", type=str, default=None, help="EthGasStation API key") parser.add_argument("--etherscan-api-key", type=str, default=None, help="Etherscan API key") parser.add_argument("--blocknative-api-key", type=str, default=None, help="Blocknative API key") parser.add_argument( '--fixed-gas-price', type=float, default=None, help= "Uses a fixed value (in Gwei) instead of an external API to determine initial gas" ) parser.add_argument("--poanetwork-url", type=str, default=None, help="Alternative POANetwork URL") parser.add_argument( "--gas-initial-multiplier", type=float, default=1.0, help= "Adjusts the initial API-provided 'fast' gas price, default 1.0") parser.add_argument( "--gas-reactive-multiplier", type=float, default=1.125, help= "Increases gas price when transactions haven't been mined after some time" ) parser.add_argument( "--gas-maximum", type=float, default=2000, help= "Places an upper bound (in Gwei) on the amount of gas to use for a single TX" ) parser.add_argument("--debug", dest='debug', action='store_true', help="Enable debug output") parser.add_argument("--network", type=str, default='kovan', help="Network Name") self.arguments = parser.parse_args(args) # Configure connection to the chain self.web3: Web3 = kwargs['web3'] if 'web3' in kwargs else web3_via_http( endpoint_uri=self.arguments.rpc_host, timeout=self.arguments.rpc_timeout, http_pool_size=100) self.web3.eth.defaultAccount = self.arguments.eth_from self.web3.middleware_onion.inject(geth_poa_middleware, layer=0) register_keys(self.web3, self.arguments.eth_key) self.our_address = Address(self.arguments.eth_from) # Check configuration for retrieving urns/bites if self.arguments.type == 'flip' and self.arguments.create_auctions \ and self.arguments.from_block is None \ and self.arguments.tokenflow_url is None \ and self.arguments.vulcanize_endpoint is None: raise RuntimeError( "One of --from-block, --tokenflow_url, or --vulcanize-endpoint must be specified " "to bite and kick off new flip auctions") if self.arguments.type == 'flip' and not self.arguments.ilk: raise RuntimeError( "--ilk must be supplied when configuring a flip keeper") if self.arguments.type == 'flop' and self.arguments.create_auctions \ and self.arguments.from_block is None: raise RuntimeError( "--from-block must be specified to kick off flop auctions") # Configure core and token contracts #self.mcd = DssDeployment.from_node(web3=self.web3) self.mcd = DssDeployment.from_network(web3=self.web3, network=self.arguments.network) self.vat = self.mcd.vat self.cat = self.mcd.cat self.vow = self.mcd.vow self.mkr = self.mcd.mkr self.dai_join = self.mcd.dai_adapter logging.info("vat: {self.vat}, cat: {self.vat}, mkr: {self.mkr}") if self.arguments.type == 'flip': self.collateral = self.mcd.collaterals[self.arguments.ilk] self.ilk = self.collateral.ilk self.gem_join = self.collateral.adapter else: self.collateral = None self.ilk = None self.gem_join = None # Configure auction contracts self.flipper = self.collateral.flipper if self.arguments.type == 'flip' else None self.flapper = self.mcd.flapper if self.arguments.type == 'flap' else None self.flopper = self.mcd.flopper if self.arguments.type == 'flop' else None self.urn_history = None if self.flipper: self.min_flip_lot = Wad.from_number(self.arguments.min_flip_lot) self.strategy = FlipperStrategy(self.flipper, self.min_flip_lot) if self.arguments.create_auctions: if self.arguments.vulcanize_endpoint: self.urn_history = VulcanizeUrnHistoryProvider( self.mcd, self.ilk, self.arguments.vulcanize_endpoint, self.arguments.vulcanize_key) elif self.arguments.tokenflow_url: self.urn_history = TokenFlowUrnHistoryProvider( self.web3, self.mcd, self.ilk, self.arguments.tokenflow_url, self.arguments.tokenflow_key, self.arguments.chunk_size) else: self.urn_history = ChainUrnHistoryProvider( self.web3, self.mcd, self.ilk, self.arguments.from_block, self.arguments.chunk_size) elif self.flapper: self.strategy = FlapperStrategy(self.flapper, self.mkr.address) elif self.flopper: self.strategy = FlopperStrategy(self.flopper) else: raise RuntimeError("Please specify auction type") # Create the collection used to manage auctions relevant to this keeper if self.arguments.model: model_command = ' '.join(self.arguments.model) else: if self.arguments.bid_on_auctions: raise RuntimeError( "--model must be specified to bid on auctions") else: model_command = ":" self.auctions = Auctions( flipper=self.flipper.address if self.flipper else None, flapper=self.flapper.address if self.flapper else None, flopper=self.flopper.address if self.flopper else None, model_factory=ModelFactory(model_command)) self.auctions_lock = threading.Lock() # Since we don't want periodically-pollled bidding threads to back up, use a flag instead of a lock. self.is_joining_dai = False self.dead_since = {} self.lifecycle = None logging.basicConfig( format='%(asctime)-15s %(levelname)-8s %(message)s', level=(logging.DEBUG if self.arguments.debug else logging.INFO)) # Create gas strategy used for non-bids and bids which do not supply gas price self.gas_price = DynamicGasPrice(self.arguments, self.web3) # Configure account(s) for which we'll deal auctions self.deal_all = False self.deal_for = set() if self.arguments.deal_for is None: self.deal_for.add(self.our_address) elif len( self.arguments.deal_for ) == 1 and self.arguments.deal_for[0].upper() in ["ALL", "NONE"]: if self.arguments.deal_for[0].upper() == "ALL": self.deal_all = True # else no auctions will be dealt elif len(self.arguments.deal_for) > 0: for account in self.arguments.deal_for: self.deal_for.add(Address(account)) # reduce logspew # logging.getLogger('urllib3').addHandler(logging.StreamHandler()) # logging.getLogger('web3').addHandler(logging.StreamHandler()) # logging.getLogger('asyncio').addHandler(logging.StreamHandler()) # logging.getLogger('requests').addHandler(logging.StreamHandler()) logging.getLogger('urllib3').setLevel(logging.INFO) #logging.getLogger("web3").setLevel(logging.DEBUG if self.arguments.debug else logging.INFO) logging.getLogger("web3").setLevel(logging.INFO) logging.getLogger("asyncio").setLevel(logging.INFO) logging.getLogger("requests").setLevel(logging.INFO)
def test_from_network(self, web3: Web3): mcd_testnet = DssDeployment.from_network(web3, "testnet") validate_contracts_loaded(mcd_testnet) with pytest.raises(Exception): DssDeployment.from_network(web3, "bogus")
def __init__(self, args: list, **kwargs): parser = argparse.ArgumentParser(prog='auction-keeper') parser.add_argument("--rpc-host", type=str, default="localhost", help="JSON-RPC host (default: `localhost')") parser.add_argument("--rpc-port", type=int, default=8545, help="JSON-RPC port (default: `8545')") parser.add_argument("--rpc-timeout", type=int, default=10, help="JSON-RPC timeout (in seconds, default: 10)") parser.add_argument( "--eth-from", type=str, required=True, help="Ethereum account from which to send transactions") parser.add_argument( "--eth-key", type=str, nargs='*', help= "Ethereum private key(s) to use (e.g. 'key_file=aaa.json,pass_file=aaa.pass')" ) parser.add_argument( '--network', type=str, required=True, help="Ethereum network to connect (e.g. 'kovan' or 'testnet')") parser.add_argument('--type', type=str, choices=['flip', 'flap', 'flop'], help="Auction type in which to participate") parser.add_argument( '--ilk', type=str, help= "Name of the collateral type for a flip keeper (e.g. 'ETH-B', 'ZRX-A')" ) parser.add_argument( '--bid-only', dest='create_auctions', action='store_false', help="Do not take opportunities to create new auctions") parser.add_argument( '--vat-dai-target', type=float, help="Amount of Dai to keep in the Vat contract (e.g. 2000)") parser.add_argument( '--keep-dai-in-vat-on-exit', dest='exit_dai_on_shutdown', action='store_false', help= "Retain Dai in the Vat on exit, saving gas when restarting the keeper" ) parser.add_argument('--keep-gem-in-vat-on-exit', dest='exit_gem_on_shutdown', action='store_false', help="Retain collateral in the Vat on exit") parser.add_argument( "--model", type=str, required=True, help="Commandline to use in order to start the bidding model") parser.add_argument("--debug", dest='debug', action='store_true', help="Enable debug output") self.arguments = parser.parse_args(args) # Configure connection to the chain if self.arguments.rpc_host.startswith("http"): endpoint_uri = f"{self.arguments.rpc_host}:{self.arguments.rpc_port}" else: # Should probably default this to use TLS, but I don't want to break existing configs endpoint_uri = f"http://{self.arguments.rpc_host}:{self.arguments.rpc_port}" self.web3: Web3 = kwargs['web3'] if 'web3' in kwargs else Web3( HTTPProvider( endpoint_uri=endpoint_uri, request_kwargs={"timeout": self.arguments.rpc_timeout})) self.web3.eth.defaultAccount = self.arguments.eth_from register_keys(self.web3, self.arguments.eth_key) self.our_address = Address(self.arguments.eth_from) # Configure core and token contracts if self.arguments.type == 'flip' and not self.arguments.ilk: raise RuntimeError( "--ilk must be supplied when configuring a flip keeper") mcd = DssDeployment.from_network(web3=self.web3, network=self.arguments.network) self.vat = mcd.vat self.cat = mcd.cat self.vow = mcd.vow self.mkr = mcd.mkr self.dai_join = mcd.dai_adapter if self.arguments.type == 'flip': self.collateral = mcd.collaterals[self.arguments.ilk] self.ilk = self.collateral.ilk self.gem_join = self.collateral.adapter else: self.collateral = None self.ilk = None self.gem_join = None # Configure auction contracts self.flipper = self.collateral.flipper if self.arguments.type == 'flip' else None self.flapper = mcd.flapper if self.arguments.type == 'flap' else None self.flopper = mcd.flopper if self.arguments.type == 'flop' else None if self.flipper: self.strategy = FlipperStrategy(self.flipper) elif self.flapper: self.strategy = FlapperStrategy(self.flapper, self.mkr.address) elif self.flopper: self.strategy = FlopperStrategy(self.flopper) # Create the collection used to manage auctions relevant to this keeper self.auctions = Auctions( flipper=self.flipper.address if self.flipper else None, flapper=self.flapper.address if self.flapper else None, flopper=self.flopper.address if self.flopper else None, model_factory=ModelFactory(self.arguments.model)) self.auctions_lock = threading.Lock() self.vat_dai_target = Wad.from_number(self.arguments.vat_dai_target) if \ self.arguments.vat_dai_target is not None else None logging.basicConfig( format='%(asctime)-15s %(levelname)-8s %(message)s', level=(logging.DEBUG if self.arguments.debug else logging.INFO)) logging.getLogger('urllib3.connectionpool').setLevel(logging.INFO) logging.getLogger('requests.packages.urllib3.connectionpool').setLevel( logging.INFO)