Introduction

With PAB, you quickstart your blockchain development and prototyping. After running pab init to create a new project, you can jump right into your strategy development.

With little more configuration, you can connect to any Web3 compatible network using an RPC, load contracts from the network, and use any account you have the Private Key of to authenticate against the network (if you need to make transactions).

PAB also comes with a pytest plugin that allows for easy strategy testing (see Testing).

Sample Strategy

Here’s a basic sample strategy to give you an idea of the Strategy API:

 1 import csv
 2 from datetime import datetime
 3 from pab.strategy import BaseStrategy
 4
 5 class CompoundAndLog(BaseStrategy):
 6     """ Finds pool in `controller` for `token`, compounds the given pool for
 7     `self.accounts[account_index]` and logs relevant data into a csv file. """
 8
 9     def __init__(self, *args, token: str, controller: str, filepath: str = "compound.csv", account_index: int = 0):
10         super().__init__(*args)
11         self.filepath = filepath
12         self.account = self.accounts[account_index]
13         self.token = self.contracts.get(token)
14         self.controller = self.contracts.get(controller)
15         self.pool_id = self.controller.functions.getPoolId(self.token.address).call()
16         if not self.pool_id:
17             raise Exception(f"Pool not found for {self.token} in {self.controller}")
18
19     def run(self):
20         """ Strategy entrypoint. """
21         balance = self.get_balance()
22         new_balance = self.compound()
23         self.write_to_file(balance, new_balance)
24         self.logger.info(f"Current balance is {balance}")
25
26     def compound(self) -> int:
27         """ Calls compound function of the `controller` contract to compound pending profits
28         on the `token` pool. """
29         self.transact(self.account, self.controller.functions.compound, (self.pool_id, ))
30         return self.get_balance()
31
32     def get_balance(self) -> int:
33         """ Returns accounts balance on `controller` for `token` pool. """
34         return self.controller.functions.balanceOf(
35             self.account.address,
36             self.pool_id
37         ).call()
38
39     def write_to_file(self, old_balance: int, new_balance: int):
40         """ Write some number to a file. """
41         now = datetime.now().strftime('%Y-%m-%d %I:%M:%S')
42         diff = new_balance - old_balance
43         with open(self.filepath, 'a') as fp:
44             writer = csv.writer(fp)
45             writer.writerow([now, new_balance, diff])

BaseStrategy childs can use self.accounts, self.contracts and self.transact. They also need to implement the run() method.

For more information on the Strategy API see Strategy API and Strategy Development docs.