Exemple #1
0
    async def test_deposit_withdraw(self, real_weth: Weth, dummy_address):
        real_weth.set_owner_address(dummy_address)
        real_weth.deposit(2)
        assert await real_weth.balance_of(dummy_address) == BigNumber(2)

        real_weth.withdraw(2)
        assert await real_weth.balance_of(dummy_address) == BigNumber(0)
Exemple #2
0
 def _swap_transaction(self, trade):
     path = list(map(lambda t: t.address, trade.path))
     return self.contract.functions.swapExactTokensForTokens(
         BigNumber(trade.amount_in).value,
         BigNumber(trade.amount_in).value,
         path,
         self._get_account(),
         self.w3.eth.getBlock("latest").timestamp + self.timeout,
     )
Exemple #3
0
def dummy_account(w3, empty_account) -> Account:
    balance = w3.eth.getBalance(empty_account.address)
    required = 11 - BigNumber.from_value(balance).to_number()
    required = max(0, required)

    tx_recip = w3.eth.sendTransaction({
        "from": w3.eth.accounts[2],
        "to": empty_account.address,
        "value": BigNumber(required).value,
    })
    w3.eth.waitForTransactionReceipt(tx_recip)
    return empty_account
Exemple #4
0
async def pool_factory(
    dai: GenericToken,
    weth: GenericToken,
    yam: GenericToken,
    wbtc: GenericToken,
    bad,
    w3,
    deploy_address,
) -> BalancerFactory:
    factory = ContractFactory(w3,
                              BalancerFactory).deploy_contract(deploy_address)

    f1 = factory.setup_pool(
        [weth, dai, yam],
        [5, 5, 5],
        [
            BigNumber(small / 303.0),
            BigNumber(small / 0.9),
            BigNumber(small / 0.1),
        ],
    )
    f2 = factory.setup_pool(
        [bad, dai],
        [5, 5],
        [
            BigNumber(100),
            BigNumber(small / 0.9),
        ],
        approve_owner=False,
    )
    factory.new_pool()

    f3 = factory.setup_pool(
        [weth, wbtc],
        [5, 1],
        [
            BigNumber(5 * large / 301.0),
            BigNumber(large / 10000),
        ],  # noqa: WPS221
    )
    f4 = factory.setup_pool(
        [weth, dai, wbtc],
        [2, 1, 1],
        [
            BigNumber(2 * medium / 301.0),
            BigNumber(medium / 1.1),
            BigNumber(large / 10020),
        ],
    )

    await asyncio.gather(f1, f2, f3, f4)

    return factory
Exemple #5
0
async def pair_factory(  # noqa: WPS210, WPS217
    factory,
    dai: GenericToken,
    weth: GenericToken,
    yam: GenericToken,
    wbtc: GenericToken,
    paused_token: GenericToken,
    bad,
    w3,
    deploy_address,
) -> UniswapFactory:
    await factory.setup_pair(
        [wbtc, dai],
        [
            BigNumber(medium / 20000.0),
            BigNumber(medium),
        ],
    )
    await factory.setup_pair(
        [dai, yam],
        [
            BigNumber(medium / 1.1),
            BigNumber(medium / 0.1),
        ],  # noqa: WPS221
    )
    await factory.setup_pair(
        [weth, dai],
        [BigNumber(medium / 310), BigNumber(medium)],
    )
    await factory.setup_pair(
        [wbtc, weth],
        [
            BigNumber(medium / 10000),
            BigNumber(medium / 285),
        ],
    )

    await factory.setup_pair(
        [paused_token, weth],
        [
            BigNumber(medium / 10000),
            BigNumber(medium / 285),
        ],
    )

    paused_token.pause()

    await factory.create_pair(weth, bad)
    await factory.create_pair(weth, yam)
    return factory
Exemple #6
0
async def create_reserve(result: Tuple[float, GenericToken]):
    (value, token) = result
    try:
        exp = await token.decimals()
    except Exception:
        raise IERC20TokenError("Token doesn't contain decimals.")
    return BigNumber.from_value(value, exp)
Exemple #7
0
def send_eth(web3, from_address, to_address, value):
    tx_hash = web3.eth.sendTransaction({
        "to": to_address,
        "from": from_address,
        "value": BigNumber(value).value
    })
    return web3.eth.waitForTransactionReceipt(tx_hash, 180)
Exemple #8
0
 def bind(self, address: str, balance: BigNumber,
          denorm_weight: int) -> bool:
     if denorm_weight < 1:
         raise ValueError("Weight should be larger than 1")
     eth_safe_weight = BigNumber(denorm_weight)
     transaction = self.contract.functions.bind(address, balance.value,
                                                eth_safe_weight.value)
     return self._transact_info(transaction)
    async def test_swap(self, trade, router: UniswapV2Router,
                        weth: GenericToken, dummy_account):
        trade.amount_in = 1
        weth.transfer(dummy_account.address, BigNumber(2))
        weth.set_account(dummy_account)
        balance_before = await weth.balance_of(dummy_account.address)

        assert balance_before > 1

        weth.approve(router.get_address(), BigNumber(2))

        router.set_account(dummy_account)
        assert router.swap(trade)
        amount_out = router.check_out_given_in(trade)

        balance_after = await weth.balance_of(dummy_account.address)
        assert (balance_after.to_number() - balance_before.to_number() >
                amount_out - trade.amount_in - 0.001)
Exemple #10
0
 def deposit(self, amount, dry_run=False):
     transaction = self.contract.functions.deposit()
     # The gas amount 4249 was achieved by testing the contract and checking how much gas was needed.
     return self._transact_info(
         transaction,
         value=BigNumber(amount).value,
         gas=44249,  # noqa: WPS432
         dry_run=dry_run,
     )
Exemple #11
0
 async def get_balances(self) -> List[BigNumber]:
     tokens = await self.get_tokens()
     balances = []
     for token in tokens:
         b = self.contract.functions.getBalance(token.get_address()).call()
         try:
             decimals = await token.decimals()
         except Exception:
             raise IERC20TokenError("Bad token in balancer pool")
         balances.append(BigNumber.from_value(b, decimals))
     return balances
Exemple #12
0
    def _transact_info(self,
                       transaction,
                       value=None,
                       gas=None,
                       dry_run=False) -> Tuple[bool, float]:
        if gas is None:
            gas = self._estimate_gas(transaction)
        gas_amount = self.w3.eth.generateGasPrice()

        if gas_amount:
            gas_cost = BigNumber.from_value(gas * gas_amount).to_number()
        else:
            # No gas strategy specified
            gas_cost = None

        if dry_run:
            return False, gas_cost
        return self._transact(transaction, value, gas).status, gas_cost
Exemple #13
0
async def all_pairs(factory, weth, dai, wbtc, paused_token):
    """all_pairs set up a very specific arbitrage opportunity.

    We want a opportunity that requires less then 2 WETH and provides significant profit as
    to be able to separate profit from gas costs. If the numbers do not make sense it is because
    they are crafted to produce a high arbitrage opportunity  and high slippage.
    """
    p0 = await factory.setup_pair(
        [weth, dai],
        [
            BigNumber(small / 500 / 300.0),
            BigNumber(small / 500),
        ],
    )

    p1 = await factory.setup_pair(
        [wbtc, dai],
        [
            BigNumber(large / 10000.0),
            BigNumber(large / 10),
        ],
    )

    p2 = await factory.setup_pair(
        [wbtc, weth],
        [
            BigNumber(large / 10000.0),
            BigNumber(large / 300.0 + 31000),
        ],
    )

    p3 = await factory.setup_pair(
        [paused_token, weth],
        [
            BigNumber(large / 10000.0),
            BigNumber(large / 285.0),
        ],
    )

    paused_token.pause()

    return await async_map(create_pool, [p0, p1, p2, p3])
Exemple #14
0
 def approve(self, weth: GenericToken):
     if weth.allowance(self.get_address()) < BigNumber(10e6):  # noqa: WPS432
         return weth.approve(self.get_address(), BigNumber(10e8))  # noqa: WPS432
     return True
Exemple #15
0
 def trader(self, trader_config, weth: GenericToken, dummy_account):
     weth.transfer(dummy_account.address, BigNumber(4))
     config = yaml.safe_load(trader_config)
     app = App(config)
     yield app
     app.store.delete(Result.trader_profit)
Exemple #16
0
 async def check(self, address):
     amount_weth = await self.weth.balance_of(address)
     amount_eth = BigNumber.from_value(self.web3.eth.getBalance(address))
     return amount_eth.to_number(), amount_weth.to_number()
Exemple #17
0
"""Test uniswap contracts."""
import asyncio

import pytest

from Arbie import IERC20TokenError
from Arbie.Contracts.tokens import BadERC20Token, GenericToken
from Arbie.Contracts.uniswap import UniswapFactory, UniswapPair
from Arbie.Variables import BigNumber, PoolType

bg10 = BigNumber(10)
bg5 = BigNumber(5)

pytestmark = pytest.mark.asyncio


@pytest.fixture
async def factory_with_pair(factory, dai, weth) -> UniswapFactory:
    await factory.create_pair(dai, weth)
    return factory


async def test_get_all_pairs_length(factory):
    assert await factory.all_pairs_length() == 0


async def test_create_pair(factory_with_pair):
    assert await factory_with_pair.all_pairs_length() == 1


async def test_get_all_pairs(factory_with_pair):
Exemple #18
0
 def withdraw(self, amount, dry_run=False):
     transaction = self.contract.functions.withdraw(BigNumber(amount).value)
     return self._transact_info(transaction, dry_run=dry_run)
Exemple #19
0
def test_create_big_number():
    bg = BigNumber(5)
    assert bg.to_number() == 5
Exemple #20
0
"""Test uniswap contracts."""
import pytest

from Arbie.Contracts import ContractFactory
from Arbie.Contracts.tokens import GenericToken, Weth
from Arbie.Variables import BigNumber

bg10 = BigNumber(10)


@pytest.fixture
def token_factory(w3) -> ContractFactory:
    return ContractFactory(w3, GenericToken)


@pytest.fixture
def dai(deploy_address, token_factory) -> GenericToken:
    return token_factory.deploy_contract(deploy_address, "Dai", "DAI",
                                         bg10.value)


@pytest.mark.asyncio
async def test_decimals(dai: GenericToken):
    assert await dai.decimals() == 18


class TestToken(object):
    def test_equals(self, dai, token_factory):
        dai2 = token_factory.load_contract(owner_address=dai.owner_address,
                                           address=dai.get_address())
        assert dai == dai2
Exemple #21
0
def test_bind_weight(pool_factory):
    pool = pool_factory.new_pool()
    with pytest.raises(ValueError):
        amount = BigNumber(5)
        weight = 0.2
        pool.bind("", amount, weight)
Exemple #22
0
def trader_account(w3, weth: GenericToken, router, dummy_account):
    router.set_account(dummy_account)
    weth.transfer(dummy_account.address, BigNumber(2))
    weth.set_account(dummy_account)
    weth.approve(router.get_address(), BigNumber(2))
    return dummy_account
Exemple #23
0
def test_not_list_equals():
    assert [BigNumber(5)] != [BigNumber(6)]
Exemple #24
0
def setup_eth(amounts):
    mock = MagicMock()
    mock.eth = mock
    mock.getBalance.side_effect = list(
        map(lambda a: BigNumber(a).value, amounts))  # noqa: WPS221
    return mock
Exemple #25
0
def amount_to_future(amount):
    future = asyncio.Future()
    future.set_result(BigNumber(amount))
    return future
Exemple #26
0
def test_list_equals():
    assert [BigNumber(5)] == [BigNumber(5)]
Exemple #27
0
 def check_out_given_in(self, trade: Trade):
     path_address = list(map(lambda t: t.address, trade.path))
     amount_out = self.contract.functions.getAmountsOut(
         BigNumber(trade.amount_in).value, path_address
     ).call()
     return BigNumber.from_value(amount_out[-1]).to_number()
Exemple #28
0
 async def balance_of(self, owner: str) -> BigNumber:
     result = await asyncio.gather(
         self._call_async(self.contract.functions.balanceOf(owner)),
         self.decimals())
     return BigNumber.from_value(result[0], result[1])
Exemple #29
0
def test_not_equal():
    assert BigNumber(5) != BigNumber(6)
Exemple #30
0
 async def get_fee(self) -> float:
     fee = await self._call_async(self.contract.functions.getSwapFee())
     return BigNumber.from_value(fee).to_number()