Skip to content

Commit

Permalink
feat: added Uniswap v2 Factory contract (and sketch of Pool)
Browse files Browse the repository at this point in the history
  • Loading branch information
fubuloubu authored and johnson2427 committed Jul 26, 2024
1 parent 4418bfd commit b8eacd4
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 4 deletions.
8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,17 @@
url="https://github.com/ApeWorX/uniswap-sdk",
include_package_data=True,
install_requires=[
"eth-ape>=0.8,<1",
"ethpm-types>=0.6.11", # higher peer dep of `eth-ape`, solves typing issue
"importlib-metadata ; python_version<'3.8'",
"eth-ape>=0.5.3,<1.0",
], # NOTE: Add 3rd party libraries here
python_requires=">=3.8,<4",
python_requires=">=3.8,<3.11",
extras_require=extras_require,
py_modules=["uniswap_sdk"],
license="Apache-2.0",
zip_safe=False,
keywords="ethereum",
packages=find_packages(exclude=["tests", "tests.*"]),
package_data={"uniswap_sdk": ["py.typed", "*.json"]},
package_data={"uniswap_sdk": ["py.typed", "v2.json"]},
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
Expand Down
1 change: 1 addition & 0 deletions uniswap_sdk/v2.json

Large diffs are not rendered by default.

74 changes: 74 additions & 0 deletions uniswap_sdk/v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import pkgutil
from typing import Iterator

from ape import Contract
from ape.contracts import ContractInstance
from ape.types import AddressType
from ape.utils import ManagerAccessMixin
from ethpm_types import PackageManifest

# TODO: Figure out better way to load this using `Project`
_manifest = pkgutil.get_data(__package__, "v2.json")
CONTRACT_TYPES = PackageManifest.parse_raw(_manifest).contract_types # type: ignore

ADDRESSES = {
"ethereum": {
"mainnet": "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
"rospten": "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
"rinkeby": "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
"kovan": "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
"goerli": "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
},
"bsc": {
"mainnet": "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
},
"polygon": {
"mainnet": "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
"mumbai": "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
},
"fantom": {
"opera": "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
"testnet": "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f",
},
}


class Factory(ManagerAccessMixin):
@property
def address(self) -> AddressType:
ecosystem_name = self.provider.network.ecosystem.name
network_name = self.provider.network.name.replace("-fork", "")

if ecosystem_name not in ADDRESSES or network_name not in ADDRESSES[ecosystem_name]:
raise ValueError(f"No Uniswap deployment on '{ecosystem_name}:{network_name}'")

return AddressType(ADDRESSES[ecosystem_name][network_name]) # type: ignore

@property
def contract(self) -> ContractInstance:
return Contract(
self.address,
contract_type=CONTRACT_TYPES["UniswapV2Factory"], # type: ignore
)

def get_pools(self, token: AddressType) -> Iterator["Pool"]:
# TODO: Use query manager to search once topic filtering is available
for log in self.contract.PairCreated:
if token in (log.token0, log.token1): # `token` is either one in the pool's pair
yield Pool(log.pair)

def get_all_pools(self) -> Iterator["Pool"]:
for address in self.contract.PairCreated.query("pair").pair:
yield Pool(address)


class Pool(ManagerAccessMixin):
def __init__(self, address: AddressType):
self.address = address

@property
def contract(self) -> ContractInstance:
return Contract(
self.address,
contract_type=CONTRACT_TYPES["UniswapV2Pair"], # type: ignore
)

0 comments on commit b8eacd4

Please sign in to comment.