示例#1
0
def get_escrow(escrow_addr: str) -> Contract:
    """Retrieve the Escrow contract from a given address.

    >>> credentials = {
    ... 	"gas_payer": "0x1413862C2B7054CDbfdc181B83962CB0FC11fD92",
    ... 	"gas_payer_priv": "28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5"
    ... }
    >>> rep_oracle_pub_key = b"2dbc2c2c86052702e7c219339514b2e8bd4687ba1236c478ad41b43330b08488c12c8c1797aa181f3a4596a1bd8a0c18344ea44d6655f61fa73e56e743f79e0d"
    >>> job = Job(credentials=credentials, escrow_manifest=manifest)

    Deploying a new Job to the ethereum network succeeds.

    >>> job.launch(rep_oracle_pub_key)
    True
    >>> type(get_escrow(job.job_contract.address))
    <class 'web3._utils.datatypes.Contract'>

    Args:
        escrow_addr (str): an ethereum address of the escrow contract.

    Returns:
        Contract: returns the Escrow solidity contract.

    """

    w3 = get_w3()
    contract_interface = get_contract_interface(
        "{}/Escrow.sol:Escrow".format(CONTRACT_FOLDER))
    escrow = w3.eth.contract(
        address=ChecksumAddress(HexAddress(HexStr(escrow_addr))),
        abi=contract_interface["abi"],
    )
    return escrow
示例#2
0
def get_factory(factory_addr: str) -> Contract:
    """Retrieve the EscrowFactory contract from a given address.

    >>> credentials = {
    ... 	"gas_payer": "0x1413862C2B7054CDbfdc181B83962CB0FC11fD92",
    ... 	"gas_payer_priv": "28e516f1e2f99e96a48a23cea1f94ee5f073403a1c68e818263f0eb898f1c8e5"
    ... }
    >>> job = Job(credentials=credentials, escrow_manifest=manifest)
    >>> type(get_factory(job.factory_contract.address))
    <class 'web3._utils.datatypes.Contract'>

    Args:
        factory_addr (str): the ethereum address of the Escrow contract.

    Returns:
        Contract: returns the EscrowFactory solidity contract.

    """
    w3 = get_w3()
    contract_interface = get_contract_interface(
        "{}/EscrowFactory.sol:EscrowFactory".format(CONTRACT_FOLDER))
    escrow_factory = w3.eth.contract(
        address=ChecksumAddress(HexAddress(HexStr(factory_addr))),
        abi=contract_interface["abi"],
    )
    return escrow_factory
示例#3
0
def build_etherscan_manifest(uri: URI, package_name: str,
                             version: str) -> Iterable[Tuple[str, Any]]:
    address, chain_id = parse.urlparse(uri).netloc.split(":")
    network = get_etherscan_network(chain_id)
    body = make_etherscan_request(address, network)
    contract_type = body["ContractName"]
    w3 = setup_w3(to_int(text=chain_id))
    block_uri = create_latest_block_uri(w3)
    runtime_bytecode = to_hex(
        w3.eth.getCode(ChecksumAddress(HexAddress(HexStr(address)))))

    yield "package_name", package_name
    yield "version", version
    yield "manifest_version", "2"
    yield "sources", {f"./{contract_type}.sol": body["SourceCode"]}
    yield "contract_types", {
        contract_type: {
            "abi": json.loads(body["ABI"]),
            "runtime_bytecode": {
                "bytecode": runtime_bytecode
            },
            "compiler": generate_compiler_info(body),
        }
    }
    yield "deployments", {
        block_uri: {
            contract_type: {
                "contract_type": contract_type,
                "address": address
            }
        }
    }
示例#4
0
 def _get_user_identity(address: ChecksumAddress) -> ChecksumEthAddress:
     """Given an address (signer) returns its protocol user identity"""
     return generate_address_via_create2(
         address=IDENTITY_FACTORY_ADDR,
         salt=CREATE2_SALT,
         init_code=IDENTITY_PROXY_INIT_CODE.format(signer_address=address.removeprefix('0x')),
     )
示例#5
0
async def get_uniswap_v3_range_liquidity_points(
    network: str,
    tick_lower: int,
    tick_upper: int,
    pool_address: ChecksumAddress,
    block_number: BlockNumber,
) -> Balances:
    """Fetches users' liquidity points of the Uniswap V3 pool in the specific range."""
    lowered_pool_address = pool_address.lower()

    last_id = ""
    result: Dict = await execute_uniswap_v3_gql_query(
        network=network,
        query=UNISWAP_V3_RANGE_POSITIONS_QUERY,
        variables=dict(
            block_number=block_number,
            tick_lower=tick_lower,
            tick_upper=tick_upper,
            pool_address=lowered_pool_address,
            last_id=last_id,
        ),
    )
    positions_chunk = result.get("positions", [])
    positions = positions_chunk

    # accumulate chunks of positions
    while len(positions_chunk) >= 1000:
        last_id = positions_chunk[-1]["id"]
        result: Dict = await execute_uniswap_v3_gql_query(
            network=network,
            query=UNISWAP_V3_RANGE_POSITIONS_QUERY,
            variables=dict(
                block_number=block_number,
                tick_lower=tick_lower,
                tick_upper=tick_upper,
                pool_address=lowered_pool_address,
                last_id=last_id,
            ),
        )
        positions_chunk = result.get("positions", [])
        positions.extend(positions_chunk)

    # process positions
    balances: Dict[ChecksumAddress, int] = {}
    total_supply = 0
    for position in positions:
        account = Web3.toChecksumAddress(position["owner"])
        if account == EMPTY_ADDR_HEX:
            continue

        liquidity = int(position.get("liquidity", "0"))
        if liquidity <= 0:
            continue

        balances[account] = balances.setdefault(account, 0) + liquidity

        total_supply += liquidity

    return Balances(total_supply=total_supply, balances=balances)
示例#6
0
    def test_solidityKeccak_ens(
        self, web3: "Web3", types: Sequence[TypeStr], values: Sequence[str], expected: HexBytes
    ) -> None:
        with ens_addresses(web3, {
            'one.eth': ChecksumAddress(
                HexAddress(HexStr("0x49EdDD3769c0712032808D86597B84ac5c2F5614"))
            ),
            'two.eth': ChecksumAddress(
                HexAddress(HexStr("0xA6b759bBbf4B59D24acf7E06e79f3a5D104fdCE5"))
            ),
        }):
            # when called as class method, any name lookup attempt will fail
            with pytest.raises(InvalidAddress):
                Web3.solidityKeccak(types, values)

            # when called as instance method, ens lookups can succeed
            actual = web3.solidityKeccak(types, values)
            assert actual == expected
 def get_token_price(self, token_address: ChecksumAddress) -> float:
     """
     :param token_address:
     :return: usd price for token address, 0. if not found
     """
     token_address = token_address.lower()
     url = urljoin(self.base_url,
                   f'api/v3/simple/token_price/ethereum?contract_addresses={token_address}&vs_currencies=usd')
     return self._get_price(url, token_address)
示例#8
0
    def test_eth_getBalance(self, web3: "Web3") -> None:
        coinbase = web3.eth.coinbase

        with pytest.raises(InvalidAddress):
            web3.eth.getBalance(ChecksumAddress(HexAddress(HexStr(coinbase.lower()))))

        balance = web3.eth.getBalance(coinbase)

        assert is_integer(balance)
        assert balance >= 0
示例#9
0
 def test_trace_raw_transaction(
     self,
     web3: "Web3",
     raw_transaction: HexStr,
     funded_account_for_raw_txn: ChecksumAddress,
 ) -> None:
     trace = web3.parity.traceRawTransaction(raw_transaction)
     assert trace['stateDiff'] is None
     assert trace['vmTrace'] is None
     assert trace['trace'][0]['action']['from'] == funded_account_for_raw_txn.lower()
示例#10
0
 def get_token_info(
         self, token_address: ChecksumAddress) -> Optional[Dict[str, Any]]:
     token_address = token_address.lower()
     url = urljoin(
         self.base_url,
         f"api/v3/coins/{self.asset_platform}/contract/{token_address}",
     )
     try:
         return self._do_request(url)
     except Coingecko404:
         return None
示例#11
0
def to_checksum_address(value: AnyStr) -> ChecksumAddress:
    """
    Makes a checksum address given a supported format.
    """
    norm_address = to_normalized_address(value)
    address_hash = encode_hex(
        keccak(text=remove_0x_prefix(HexStr(norm_address))))

    checksum_address = add_0x_prefix(
        HexStr("".join((norm_address[i].upper(
        ) if int(address_hash[i], 16) > 7 else norm_address[i])
                       for i in range(2, 42))))
    return ChecksumAddress(HexAddress(checksum_address))
示例#12
0
    def setup_owner(self,
                    name: str,
                    new_owner: ChecksumAddress = cast(ChecksumAddress,
                                                      default),
                    transact: Optional["TxParams"] = None) -> ChecksumAddress:
        """
        Set the owner of the supplied name to `new_owner`.

        For typical scenarios, you'll never need to call this method directly,
        simply call :meth:`setup_name` or :meth:`setup_address`. This method does *not*
        set up the name to point to an address.

        If `new_owner` is not supplied, then this will assume you
        want the same owner as the parent domain.

        If the caller owns ``parentname.eth`` with no subdomains
        and calls this method with ``sub.parentname.eth``,
        then ``sub`` will be created as part of this call.

        :param str name: ENS name to set up
        :param new_owner: account that will own `name`. If ``None``, set owner to empty addr.
            If not specified, name will point to the parent domain owner's address.
        :param dict transact: the transaction configuration, like in
            :meth:`~web3.eth.Eth.send_transaction`
        :raises InvalidName: if `name` has invalid syntax
        :raises UnauthorizedError: if ``'from'`` in `transact` does not own `name`
        :returns: the new owner's address
        """
        if not transact:
            transact = {}
        transact = deepcopy(transact)
        (super_owner, unowned, owned) = self._first_owner(name)
        if new_owner is default:
            new_owner = super_owner
        elif not new_owner:
            new_owner = ChecksumAddress(EMPTY_ADDR_HEX)
        else:
            new_owner = to_checksum_address(new_owner)
        current_owner = self.owner(name)
        if new_owner == EMPTY_ADDR_HEX and not current_owner:
            return None
        elif current_owner == new_owner:
            return current_owner
        else:
            self._assert_control(super_owner, name, owned)
            self._claim_ownership(new_owner,
                                  unowned,
                                  owned,
                                  super_owner,
                                  transact=transact)
            return new_owner
class ZerionTokenAdapterClient:
    """
    Client for Zerion Token Adapter
    https://github.com/zeriontech/defi-sdk
    """
    ABI = [{'inputs': [{'internalType': 'address', 'name': 'token', 'type': 'address'}],
            'name': 'getComponents',
            'outputs': [{'components': [{'internalType': 'address',
                                         'name': 'token',
                                         'type': 'address'},
                                        {'internalType': 'string', 'name': 'tokenType', 'type': 'string'},
                                        {'internalType': 'uint256', 'name': 'rate', 'type': 'uint256'}],
                         'internalType': 'struct Component[]',
                         'name': '',
                         'type': 'tuple[]'}],
            'stateMutability': 'view',
            'type': 'function'},
           {'inputs': [{'internalType': 'address', 'name': 'token', 'type': 'address'}],
            'name': 'getMetadata',
            'outputs': [{'components': [{'internalType': 'address',
                                         'name': 'token',
                                         'type': 'address'},
                                        {'internalType': 'string', 'name': 'name', 'type': 'string'},
                                        {'internalType': 'string', 'name': 'symbol', 'type': 'string'},
                                        {'internalType': 'uint8', 'name': 'decimals', 'type': 'uint8'}],
                         'internalType': 'struct TokenMetadata',
                         'name': '',
                         'type': 'tuple'}],
            'stateMutability': 'view',
            'type': 'function'}]
    ADAPTER_ADDRESS: ChecksumAddress = ChecksumAddress(NULL_ADDRESS)

    def __init__(self, ethereum_client: EthereumClient, adapter_address: Optional[ChecksumAddress] = None):
        self.ethereum_client = ethereum_client
        self.adapter_address = adapter_address if adapter_address else self.ADAPTER_ADDRESS
        self.contract = ethereum_client.w3.eth.contract(self.adapter_address, abi=self.ABI)

    def get_components(self, token_address: ChecksumAddress) -> Optional[List[UniswapComponent]]:
        try:
            return [UniswapComponent(*component) for component
                    in self.contract.functions.getComponents(token_address).call()]
        except ContractLogicError:
            return None

    def get_metadata(self, token_address: ChecksumAddress) -> Optional[ZerionPoolMetadata]:
        try:
            return ZerionPoolMetadata(*self.contract.functions.getMetadata(token_address).call())
        except ContractLogicError:
            return None
示例#14
0
 def test_trace_raw_transaction(
     self,
     web3: "Web3",
     raw_transaction: HexStr,
     funded_account_for_raw_txn: ChecksumAddress,
 ) -> None:
     # address 0x39EEed73fb1D3855E90Cbd42f348b3D7b340aAA6
     raw_transaction = HexStr(
         '0xf8648085174876e8008252089439eeed73fb1d3855e90cbd42f348b3d7b340aaa601801ba0ec1295f00936acd0c2cb90ab2cdaacb8bf5e11b3d9957833595aca9ceedb7aada05dfc8937baec0e26029057abd3a1ef8c505dca2cdc07ffacb046d090d2bea06a'
     )  # noqa: E501
     trace = web3.parity.trace_raw_transaction(raw_transaction)
     assert trace['stateDiff'] is None
     assert trace['vmTrace'] is None
     assert trace['trace'][0]['action'][
         'from'] == funded_account_for_raw_txn.lower()
示例#15
0
    def test_eth_sendTransaction_addr_checksum_required(
            self, web3: "Web3", unlocked_account: ChecksumAddress) -> None:
        non_checksum_addr = unlocked_account.lower()
        txn_params = {
            'from': unlocked_account,
            'to': unlocked_account,
            'value': 1,
            'gas': 21000,
            'gasPrice': web3.eth.gasPrice,
        }

        with pytest.raises(InvalidAddress):
            invalid_params = dict(txn_params, **{'from': non_checksum_addr})
            web3.eth.sendTransaction(invalid_params)

        with pytest.raises(InvalidAddress):
            invalid_params = dict(txn_params, **{'to': non_checksum_addr})
            web3.eth.sendTransaction(invalid_params)
示例#16
0
def wait_for_token_network_discovery(
    node_endpoint: str, settings: SettingsConfig, session: Session
) -> ChecksumAddress:
    """Check for token network discovery with the given `node`.

    By default exit the wait if the token has not been discovered after `n` seconds,
    where `n` is the value of :attr:`.timeout`.

    :raises TokenNetworkDiscoveryTimeout:
        If we waited a set time for the token network to be discovered, but it wasn't.
    """
    started = time.monotonic()
    elapsed = 0.0
    while elapsed < settings.timeout:
        try:
            resp = session.get(node_endpoint)
            resp.raise_for_status()

        except HTTPError as e:
            # We explicitly handle 404 Not Found responses only - anything else is none
            # of our business.
            if e.response.status_code != 404:
                raise

            # Wait before continuing, no sense in spamming the node.
            gevent.sleep(1)

            # Update our elapsed time tracker.
            elapsed = time.monotonic() - started
            continue

        else:
            # The node appears to have discovered our token network.
            data = resp.json()

            if not is_checksum_address(data):
                # Something's amiss about this response. Notify a human.
                raise TypeError(f"Unexpected response type from API: {data!r}")

            return ChecksumAddress(data)

    # We could not assert that our token network was registered within an
    # acceptable time frame.
    raise TokenNetworkDiscoveryTimeout
示例#17
0
    label_to_hash,
    normal_name_to_hash,
    normalize_name,
    raw_name_to_hash,
)

if TYPE_CHECKING:
    from web3 import Web3  # noqa: F401
    from web3.contract import (  # noqa: F401
        Contract, )
    from web3.providers import (  # noqa: F401
        BaseProvider, )
    from web3.types import (  # noqa: F401
        TxParams, )

ENS_MAINNET_ADDR = ChecksumAddress(
    HexAddress(HexStr('0x314159265dD8dbb310642f98f50C066173C1259b')))


class ENS:
    """
    Quick access to common Ethereum Name Service functions,
    like getting the address for a name.

    Unless otherwise specified, all addresses are assumed to be a `str` in
    `checksum format <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md>`_,
    like: ``"0x314159265dD8dbb310642f98f50C066173C1259b"``
    """

    labelhash = staticmethod(label_to_hash)
    namehash = staticmethod(raw_name_to_hash)
    nameprep = staticmethod(normalize_name)
示例#18
0
 def get_address_of(self, instance_name: str) -> ChecksumAddress:
     instance = self.get_instance(instance_name)
     return ChecksumAddress(instance.address)
示例#19
0
 def test_eth_getCode_invalid_address(self, web3: "Web3",
                                      math_contract: "Contract") -> None:
     with pytest.raises(InvalidAddress):
         web3.eth.getCode(
             ChecksumAddress(
                 HexAddress(HexStr(math_contract.address.lower()))))
示例#20
0
 def test_eth_getTransactionCount_invalid_address(self,
                                                  web3: "Web3") -> None:
     coinbase = web3.eth.coinbase
     with pytest.raises(InvalidAddress):
         web3.eth.getTransactionCount(
             ChecksumAddress(HexAddress(HexStr(coinbase.lower()))))
示例#21
0
LIBRARY_TOKEN_NETWORK_UTILS_LINK_KEY = "data/source/lib/TokenNetworkUtils.sol:TokenNetworkUtils"

# Timeouts
TEST_SETTLE_TIMEOUT_MIN = 5
TEST_SETTLE_TIMEOUT_MAX = 100000

DEPLOY_SETTLE_TIMEOUT_MIN = 500  # ~ 2 hours
DEPLOY_SETTLE_TIMEOUT_MAX = 555428  # ~ 3 months

# Temporary deposit limits for the Red Eyes release in WEI
MAX_ETH_CHANNEL_PARTICIPANT = int(0.075 * 10 ** 18)
MAX_ETH_TOKEN_NETWORK = int(250 * 10 ** 18)

# Special hashes
LOCKSROOT_OF_NO_LOCKS = Locksroot(keccak(b""))
EMPTY_ADDRESS = ChecksumAddress(HexAddress(HexStr("0x0000000000000000000000000000000000000000")))

# Event names
# TokenNetworkRegistry
EVENT_TOKEN_NETWORK_CREATED = "TokenNetworkCreated"

# TokenNetwork
EVENT_DEPRECATION_SWITCH = "DeprecationSwitch"

# SecretRegistry
EVENT_SECRET_REVEALED = "SecretRevealed"

# EndpointRegistry
EVENT_ADDRESS_REGISTERED = "AddressRegistered"

# ServiceRegistry
示例#22
0
async def get_uniswap_v3_single_token_balances(
    network: str,
    pool_address: ChecksumAddress,
    token: ChecksumAddress,
    block_number: BlockNumber,
) -> Balances:
    """Fetches users' single token balances of the Uniswap V3 pair across all the ticks."""
    lowered_pool_address = pool_address.lower()
    result: Dict = await execute_uniswap_v3_gql_query(
        network=network,
        query=UNISWAP_V3_POOL_QUERY,
        variables=dict(block_number=block_number,
                       pool_address=lowered_pool_address),
    )
    pools = result.get("pools", [])
    if not pools:
        return Balances(total_supply=0, balances={})
    pool = pools[0]

    try:
        tick_current: int = int(pool["tick"])
    except TypeError:
        return Balances(total_supply=0, balances={})

    sqrt_price: int = pool.get("sqrtPrice", "")
    if not sqrt_price:
        return Balances(total_supply=0, balances={})
    sqrt_price = int(sqrt_price)

    token0_address: ChecksumAddress = Web3.toChecksumAddress(pool["token0"])
    token1_address: ChecksumAddress = Web3.toChecksumAddress(pool["token1"])

    last_id = ""
    result: Dict = await execute_uniswap_v3_gql_query(
        network=network,
        query=UNISWAP_V3_POSITIONS_QUERY,
        variables=dict(
            block_number=block_number,
            pool_address=lowered_pool_address,
            last_id=last_id,
        ),
    )
    positions_chunk = result.get("positions", [])
    positions = positions_chunk

    # TODO: calculated earned fees

    # accumulate chunks of positions
    while len(positions_chunk) >= 1000:
        last_id = positions_chunk[-1]["id"]
        result: Dict = await execute_uniswap_v3_gql_query(
            network=network,
            query=UNISWAP_V3_POSITIONS_QUERY,
            variables=dict(
                block_number=block_number,
                pool_address=lowered_pool_address,
                last_id=last_id,
            ),
        )
        positions_chunk = result.get("positions", [])
        positions.extend(positions_chunk)

    # process positions
    balances: Dict[ChecksumAddress, int] = {}
    total_supply = 0
    for position in positions:
        account = Web3.toChecksumAddress(position["owner"])
        if account == EMPTY_ADDR_HEX:
            continue

        liquidity: int = int(position["liquidity"])
        if liquidity <= 0:
            continue

        try:
            tick_lower: int = int(position["tickLower"])
            tick_upper: int = int(position["tickUpper"])
        except TypeError:
            continue

        if token0_address == token:
            token0_amount = get_amount0(
                tick_current=tick_current,
                sqrt_ratio_x96=sqrt_price,
                tick_lower=tick_lower,
                tick_upper=tick_upper,
                liquidity=liquidity,
            )
            balances[account] = balances.setdefault(account, 0) + token0_amount
            total_supply += token0_amount
        elif token1_address == token:
            token1_amount = get_amount1(
                tick_current=tick_current,
                sqrt_ratio_x96=sqrt_price,
                tick_lower=tick_lower,
                tick_upper=tick_upper,
                liquidity=liquidity,
            )

            balances[account] = balances.setdefault(account, 0) + token1_amount
            total_supply += token1_amount

    return Balances(total_supply=total_supply, balances=balances)
class BalancerTokenAdapterClient(ZerionTokenAdapterClient):
    ADAPTER_ADDRESS: ChecksumAddress = ChecksumAddress(
        "0xb45c5AE417F70E4C52DFB784569Ce843a45FE8ca"
    )
示例#24
0
    is_same_address,
    is_string,
)
from hexbytes import (
    HexBytes, )

from web3.exceptions import (
    BlockNotFound,
    InvalidAddress,
    TransactionNotFound,
)
from web3.types import (  # noqa: F401
    BlockData, FilterParams, LogReceipt, Nonce, SyncStatus, TxParams, Wei,
)

UNKNOWN_ADDRESS = ChecksumAddress(
    HexAddress(HexStr('0xdEADBEeF00000000000000000000000000000000')))
UNKNOWN_HASH = HexStr(
    '0xdeadbeef00000000000000000000000000000000000000000000000000000000')

if TYPE_CHECKING:
    from web3 import Web3  # noqa: F401
    from web3.contract import Contract  # noqa: F401


class EthModuleTest:
    def test_eth_protocolVersion(self, web3: "Web3") -> None:
        protocol_version = web3.eth.protocolVersion

        assert is_string(protocol_version)
        assert protocol_version.isdigit()
class ZerionUniswapV2TokenAdapterClient(ZerionTokenAdapterClient):
    ADAPTER_ADDRESS: ChecksumAddress = ChecksumAddress(
        "0x6C5D49157863f942A5E6115aaEAb7d6A67a852d3"
    )
示例#26
0
async def get_token_liquidity_points(
    network: str,
    token_address: ChecksumAddress,
    from_block: BlockNumber,
    to_block: BlockNumber,
) -> Balances:
    """Fetches distributor token holders' balances."""
    lowered_token_address = token_address.lower()
    last_id = ""
    result: Dict = await execute_sw_gql_query(
        network=network,
        query=DISTRIBUTOR_TOKEN_HOLDERS_QUERY,
        variables=dict(
            token_address=lowered_token_address,
            block_number=to_block,
            last_id=last_id,
        ),
    )
    positions_chunk = result.get("distributorTokenHolders", [])
    positions = positions_chunk

    # accumulate chunks of positions
    while len(positions_chunk) >= 1000:
        last_id = positions_chunk[-1]["id"]
        result: Dict = await execute_sw_gql_query(
            network=network,
            query=DISTRIBUTOR_TOKEN_HOLDERS_QUERY,
            variables=dict(
                token_address=lowered_token_address,
                block_number=to_block,
                last_id=last_id,
            ),
        )
        positions_chunk = result.get("distributorTokenHolders", [])
        positions.extend(positions_chunk)

    # process balances
    points: Dict[ChecksumAddress, int] = {}
    total_points = 0
    for position in positions:
        account = Web3.toChecksumAddress(position["account"])
        if account == EMPTY_ADDR_HEX:
            continue

        principal = int(position["amount"])
        prev_account_points = int(position["distributorPoints"])
        updated_at_block = BlockNumber(int(position["updatedAtBlock"]))
        if from_block > updated_at_block:
            updated_at_block = from_block
            prev_account_points = 0

        account_points = prev_account_points + (
            principal * (to_block - updated_at_block)
        )
        if account_points <= 0:
            continue

        points[account] = points.get(account, 0) + account_points
        total_points += account_points

    return Balances(total_supply=total_points, balances=points)
class ZerionTokenAdapterClient:
    """
    Client for Zerion Token Adapter
    https://github.com/zeriontech/defi-sdk
    """

    ABI = [
        {
            "inputs": [{"internalType": "address", "name": "token", "type": "address"}],
            "name": "getComponents",
            "outputs": [
                {
                    "components": [
                        {"internalType": "address", "name": "token", "type": "address"},
                        {
                            "internalType": "string",
                            "name": "tokenType",
                            "type": "string",
                        },
                        {"internalType": "uint256", "name": "rate", "type": "uint256"},
                    ],
                    "internalType": "struct Component[]",
                    "name": "",
                    "type": "tuple[]",
                }
            ],
            "stateMutability": "view",
            "type": "function",
        },
        {
            "inputs": [{"internalType": "address", "name": "token", "type": "address"}],
            "name": "getMetadata",
            "outputs": [
                {
                    "components": [
                        {"internalType": "address", "name": "token", "type": "address"},
                        {"internalType": "string", "name": "name", "type": "string"},
                        {"internalType": "string", "name": "symbol", "type": "string"},
                        {"internalType": "uint8", "name": "decimals", "type": "uint8"},
                    ],
                    "internalType": "struct TokenMetadata",
                    "name": "",
                    "type": "tuple",
                }
            ],
            "stateMutability": "view",
            "type": "function",
        },
    ]
    ADAPTER_ADDRESS: ChecksumAddress = ChecksumAddress(NULL_ADDRESS)

    def __init__(
        self,
        ethereum_client: EthereumClient,
        adapter_address: Optional[ChecksumAddress] = None,
    ):
        self.ethereum_client = ethereum_client
        self.adapter_address = (
            adapter_address if adapter_address else self.ADAPTER_ADDRESS
        )
        self.contract = ethereum_client.w3.eth.contract(
            self.adapter_address, abi=self.ABI
        )

    def get_components(
        self, token_address: ChecksumAddress
    ) -> Optional[List[UniswapComponent]]:
        try:
            return [
                UniswapComponent(*component)
                for component in self.contract.functions.getComponents(
                    token_address
                ).call()
            ]
        except ContractLogicError:
            return None

    def get_metadata(
        self, token_address: ChecksumAddress
    ) -> Optional[ZerionPoolMetadata]:
        try:
            return ZerionPoolMetadata(
                *self.contract.functions.getMetadata(token_address).call()
            )
        except ContractLogicError:
            return None
示例#28
0
from eth_typing import (
    ChecksumAddress,
    HexAddress,
    HexStr,
)
from hexbytes import (
    HexBytes, )

ACCEPTABLE_STALE_HOURS = 48

AUCTION_START_GAS_CONSTANT = 25000
AUCTION_START_GAS_MARGINAL = 39000

EMPTY_SHA3_BYTES = HexBytes(b'\0' * 32)
EMPTY_ADDR_HEX = HexAddress(HexStr('0x' + '00' * 20))

REVERSE_REGISTRAR_DOMAIN = 'addr.reverse'

ENS_MAINNET_ADDR = ChecksumAddress(
    HexAddress(HexStr('0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e')))