235 lines
8.4 KiB
Python
235 lines
8.4 KiB
Python
# 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)
|