cic-stack/apps/cic-eth/tests/fixtures_bancor.py

235 lines
8.4 KiB
Python
Raw Normal View History

2021-02-01 18:12:51 +01:00
# standard imports
import os
import logging
import json
# third-party imports
import pytest
from cic_registry.bancor import contract_ids
from cic_registry import bancor
# local imports
from cic_eth.eth import rpc
script_dir = os.path.dirname(os.path.realpath(__file__))
root_dir = os.path.dirname(script_dir)
logg = logging.getLogger(__file__)
class BancorContractLoader:
bancor_path = os.path.join(root_dir, 'bancor')
registry_contract = None
@staticmethod
def build_path():
return BancorContractLoader.bancor_path
# return os.path.join(BancorContractLoader.bancor_path, 'solidity', 'build', 'contracts')
@staticmethod
def contract(w3, bundle_id, registry_id=None):
if registry_id == None:
registry_id = bundle_id
contract_id_hex = w3.toHex(text=registry_id)
contract_address = BancorContractLoader.registry_contract.functions.addressOf(contract_id_hex).call()
contract_build_file = os.path.join(
BancorContractLoader.build_path(),
'{}.json'.format(bundle_id),
)
f = open(os.path.join(contract_build_file))
j = json.load(f)
f.close()
contract_abi = j['abi']
logg.debug('creating contract interface {} ({}) at address {}'.format(registry_id, bundle_id, contract_address))
contract = w3.eth.contract(abi=contract_abi, address=contract_address)
return contract
# TODO: DRY
@pytest.fixture(scope='session')
def bancor_deploy(
load_config,
init_w3_conn,
):
bancor_dir_default = os.path.join(root_dir, 'bancor')
logg.debug('bancor deploy "{}"'.format(bancor_dir_default))
BancorContractLoader.bancor_path = load_config.get('BANCOR_DIR', bancor_dir_default)
bancor_build_dir = BancorContractLoader.build_path()
# deploy registry
registry_build_file = os.path.join(bancor_build_dir, 'ContractRegistry.json')
f = open(os.path.join(registry_build_file))
j = json.load(f)
f.close()
registry_constructor = init_w3_conn.eth.contract(abi=j['abi'], bytecode=j['bytecode'])
tx = registry_constructor.constructor().transact()
rcpt = init_w3_conn.eth.getTransactionReceipt(tx)
registry_address = rcpt['contractAddress']
registry_contract = init_w3_conn.eth.contract(abi=j['abi'], address=registry_address)
BancorContractLoader.registry_contract = registry_contract
# deply reserve token
reservetoken_build_file = os.path.join(bancor_build_dir, 'EtherToken.json')
f = open(os.path.join(reservetoken_build_file))
j = json.load(f)
f.close()
reservetoken_constructor = init_w3_conn.eth.contract(abi=j['abi'], bytecode=j['bytecode'])
tx = reservetoken_constructor.constructor('Reserve', 'RSV').transact()
rcpt = init_w3_conn.eth.getTransactionReceipt(tx)
reservetoken_address = rcpt['contractAddress']
reservetoken_contract = init_w3_conn.eth.contract(abi=j['abi'], address=reservetoken_address)
# register reserve token as bancor hub token
key_hex = init_w3_conn.toHex(text='BNTToken')
registry_contract.functions.registerAddress(key_hex, reservetoken_address).transact()
# deposit balances for minting liquid tokens with reserve
init_w3_conn.eth.sendTransaction({
'from': init_w3_conn.eth.accounts[1],
'to': reservetoken_address,
'value': init_w3_conn.toWei('101', 'ether'),
'nonce': 0,
})
init_w3_conn.eth.sendTransaction({
'from': init_w3_conn.eth.accounts[2],
'to': reservetoken_address,
'value': init_w3_conn.toWei('101', 'ether'),
'nonce': 0,
})
# deploy converter factory contract for creating liquid token exchanges
build_file = os.path.join(bancor_build_dir, 'LiquidTokenConverterFactory.json')
f = open(build_file)
j = json.load(f)
f.close()
converterfactory_constructor = init_w3_conn.eth.contract(abi=j['abi'], bytecode=j['bytecode'])
tx = converterfactory_constructor.constructor().transact()
rcpt = init_w3_conn.eth.getTransactionReceipt(tx)
converter_factory_address = rcpt['contractAddress']
# deploy the remaining contracts managed by the registry
for k in contract_ids.keys():
build_file = os.path.join(bancor_build_dir, '{}.json'.format(k))
f = open(build_file)
j = json.load(f)
f.close()
contract_constructor = init_w3_conn.eth.contract(abi=j['abi'], bytecode=j['bytecode'])
tx = None
# include the registry address as constructor parameters for the contracts that require it
if k in ['ConverterRegistry', 'ConverterRegistryData', 'BancorNetwork', 'ConversionPathFinder']:
tx = contract_constructor.constructor(registry_address).transact()
else:
tx = contract_constructor.constructor().transact()
rcpt = init_w3_conn.eth.getTransactionReceipt(tx)
contract_address = rcpt['contractAddress']
# register contract in registry
key_hex = init_w3_conn.toHex(text=contract_ids[k])
registry_contract.functions.registerAddress(key_hex, contract_address).transact()
contract = init_w3_conn.eth.contract(abi=j['abi'], address=contract_address)
# bancor formula needs to be initialized before use
if k == 'BancorFormula':
logg.debug('init bancor formula {}'.format(contract_address))
contract.functions.init().transact()
# converter factory needs liquid token converter factory to be able to issue our liquid tokens
if k == 'ConverterFactory':
logg.debug('register converter factory {}'.format(converter_factory_address))
contract.functions.registerTypedConverterFactory(converter_factory_address).transact()
logg.info('deployed registry at address {}'.format(registry_address))
return registry_contract
def __create_converter(w3, converterregistry_contract, reserve_address, owner_address, token_name, token_symbol):
converterregistry_contract.functions.newConverter(
0,
token_name,
token_symbol,
18,
100000,
[reserve_address],
[250000],
).transact({
'from': owner_address,
})
@pytest.fixture(scope='session')
def tokens_to_deploy(
):
return [
(1, 'Bert Token', 'BRT'), # account_index, token name, token symbol
(2, 'Ernie Token', 'RNI'),
]
@pytest.fixture(scope='session')
def bancor_tokens(
init_w3_conn,
bancor_deploy,
tokens_to_deploy,
):
registry_contract = bancor_deploy
reserve_contract = BancorContractLoader.contract(init_w3_conn, 'ERC20Token', 'BNTToken')
reserve_address = reserve_contract.address
network_id = init_w3_conn.toHex(text='BancorNetwork')
network_address = registry_contract.functions.addressOf(network_id).call()
converterregistry_contract = BancorContractLoader.contract(init_w3_conn, 'ConverterRegistry', 'BancorConverterRegistry')
for p in tokens_to_deploy:
__create_converter(init_w3_conn, converterregistry_contract, reserve_address, init_w3_conn.eth.accounts[p[0]], p[1], p[2])
tokens = converterregistry_contract.functions.getAnchors().call()
network_contract = BancorContractLoader.contract(init_w3_conn, 'BancorNetwork')
mint_amount = init_w3_conn.toWei('100', 'ether')
i = 0
for token in tokens:
i += 1
owner = init_w3_conn.eth.accounts[i]
logg.debug('owner {} is {}'.format(owner, token))
reserve_contract.functions.approve(network_address, 0).transact({
'from': owner
})
reserve_contract.functions.approve(network_address, mint_amount).transact({
'from': owner
})
logg.debug('convert {} {} {} {}'.format(reserve_address, token, mint_amount, owner))
network_contract.functions.convert([
reserve_address,
token,
token,
],
mint_amount,
mint_amount,
).transact({
'from': owner,
})
return tokens
@pytest.fixture(scope='session')
def bancor_load(
load_config,
init_w3_conn,
bancor_deploy,
bancor_tokens,
):
registry_address = bancor_deploy.address
bancor_dir_default = os.path.join(root_dir, 'bancor')
bancor_dir = load_config.get('BANCOR_DIR', bancor_dir_default)
bancor.load(init_w3_conn, registry_address, bancor_dir)