diff --git a/READMEs/key-value-flow.md b/READMEs/key-value-flow.md index fcfd7b38f..315b04223 100644 --- a/READMEs/key-value-flow.md +++ b/READMEs/key-value-flow.md @@ -24,7 +24,7 @@ Ensure that you've already (a) [installed Ocean](install.md), and (b) [set up lo In Python console: ```python -from ocean_lib.models.arguments import DataNFTArguments +from ocean_lib.models.data_nft import DataNFTArguments data_nft = ocean.data_nft_factory.create(DataNFTArguments('NFT1', 'NFT1'), alice) ``` diff --git a/READMEs/main-flow.md b/READMEs/main-flow.md index a44f43a5c..01733e62a 100644 --- a/READMEs/main-flow.md +++ b/READMEs/main-flow.md @@ -216,7 +216,7 @@ url_file = UrlFile( ) # Publish data asset -from ocean_lib.ocean.ocean_assets import DatatokenArguments +from ocean_lib.models.datatoken import DatatokenArguments _, _, ddo = ocean.assets.create( metadata, alice, @@ -239,7 +239,7 @@ You can control this during create(): Calling `create()` like above generates a data NFT, a datatoken for that NFT, and a ddo. This is the most common case. However, sometimes you may want _just_ the data NFT, e.g. if using a data NFT as a simple key-value store. Here's how: ```python -from ocean_lib.models.arguments import DataNFTArguments +from ocean_lib.models.data_nft import DataNFTArguments data_nft = ocean.data_nft_factory.create(DataNFTArguments('NFT1', 'NFT1'), alice) ``` @@ -250,7 +250,7 @@ If you call `create()` after this, you can pass in an argument `data_nft_address Calling `create()` like above generates a data NFT, a datatoken for that NFT, and a ddo object. However, we may want a second datatoken. Or, we may have started with _just_ the data NFT, and want to add a datatoken to it. Here's how: ```python -from ocean_lib.models.arguments import DatatokenArguments +from ocean_lib.models.datatoken import DatatokenArguments datatoken = data_nft.create_datatoken(DatatokenArguments("Datatoken 1", "DT1"), alice) ``` @@ -309,7 +309,7 @@ To learn more about the exchange status: ```python print(exchange.details) -print(exchange.fees_info) +print(exchange.exchange_fees_info) ``` It will output something like: @@ -329,8 +329,8 @@ ExchangeDetails: bt_decimals = 18 owner = 0x02354A1F160A3fd7ac8b02ee91F04104440B28E7 ->>> print(exchange.fees_info) -FeesInfo: +>>> print(exchange.exchange_fees_info) +ExchangeFeeInfo: publish_market_fee = 0.0 (0 wei) publish_market_fee_available = 0.0 (0 wei) publish_market_fee_collector = 0x02354A1F160A3fd7ac8b02ee91F04104440B28E7 diff --git a/READMEs/profile-nfts-flow.md b/READMEs/profile-nfts-flow.md index b8fa88adb..b6b9cd639 100644 --- a/READMEs/profile-nfts-flow.md +++ b/READMEs/profile-nfts-flow.md @@ -27,7 +27,7 @@ We publish a data NFT like elsewhere, except we set `transferable=False` (and sk In the Python console: ```python # Publish an NFT token. Note "transferable=False" -from ocean_lib.models.arguments import DataNFTArguments +from ocean_lib.models.data_nft import DataNFTArguments data_nft = ocean.data_nft_factory.create(DataNFTArguments('NFT1', 'NFT1', transferable=False), alice) ``` diff --git a/ocean_lib/assets/test/test_asset_downloader.py b/ocean_lib/assets/test/test_asset_downloader.py index 78a7f920e..cd69bf9ef 100644 --- a/ocean_lib/assets/test/test_asset_downloader.py +++ b/ocean_lib/assets/test/test_asset_downloader.py @@ -14,6 +14,7 @@ from ocean_lib.assets.asset_downloader import download_asset_files, is_consumable from ocean_lib.assets.ddo import DDO from ocean_lib.data_provider.data_service_provider import DataServiceProvider +from ocean_lib.models.datatoken import TokenFeeInfo from ocean_lib.services.service import Service from tests.resources.ddo_helpers import ( get_first_service_by_type, @@ -166,14 +167,16 @@ def test_ocean_assets_download_destination_file( ) provider_fees = initialize_response.json()["providerFee"] + consume_market_fees = TokenFeeInfo( + address=publisher_wallet.address, + token=datatoken.address, + ) receipt = datatoken.start_order( consumer=publisher_wallet.address, service_index=ddo.get_index_of_service(access_service), provider_fees=provider_fees, - consume_market_order_fee_address=publisher_wallet.address, - consume_market_order_fee_token=datatoken.address, - consume_market_order_fee_amount=0, + consume_market_fees=consume_market_fees, transaction_parameters={"from": publisher_wallet}, ) diff --git a/ocean_lib/models/arguments.py b/ocean_lib/models/arguments.py deleted file mode 100644 index 9a5d88281..000000000 --- a/ocean_lib/models/arguments.py +++ /dev/null @@ -1,166 +0,0 @@ -# -# Copyright 2022 Ocean Protocol Foundation -# SPDX-License-Identifier: Apache-2.0 -# -import logging -import warnings -from typing import Any, Dict, List, Optional - -from ocean_lib.models.data_nft import DataNFT -from ocean_lib.models.data_nft_factory import DataNFTFactoryContract -from ocean_lib.models.datatoken import Datatoken -from ocean_lib.models.datatoken_enterprise import DatatokenEnterprise -from ocean_lib.ocean.util import get_address_of_type, get_ocean_token_address -from ocean_lib.structures.file_objects import FilesType -from ocean_lib.web3_internal.constants import MAX_UINT256, ZERO_ADDRESS -from ocean_lib.web3_internal.contract_base import ContractBase - -logger = logging.getLogger("ocean") - - -class DataNFTArguments: - def __init__( - self, - name: str, - symbol: str, - template_index: Optional[int] = 1, - additional_datatoken_deployer: Optional[str] = None, - additional_metadata_updater: Optional[str] = None, - uri: Optional[str] = None, - transferable: Optional[bool] = None, - owner: Optional[str] = None, - ): - """ - :param name: str name of data NFT if creating a new one - :param symbol: str symbol of data NFT if creating a new one - :param template_index: int template index of the data NFT, by default is 1. - :param additional_datatoken_deployer: str address of an additional ERC20 deployer. - :param additional_metadata_updater: str address of an additional metadata updater. - :param uri: str URL of the data NFT. - """ - self.name = name - self.symbol = symbol or name - self.template_index = template_index - self.additional_datatoken_deployer = ( - additional_datatoken_deployer or ZERO_ADDRESS - ) - self.additional_metadata_updater = additional_metadata_updater or ZERO_ADDRESS - self.uri = uri or "https://oceanprotocol.com/nft/" - self.transferable = transferable or True - self.owner = owner - - def deploy_contract(self, config_dict, wallet) -> DataNFT: - address = get_address_of_type(config_dict, DataNFTFactoryContract.CONTRACT_NAME) - data_nft_factory = DataNFTFactoryContract(config_dict, address) - - receipt = data_nft_factory.deployERC721Contract( - self.name, - self.symbol, - self.template_index, - self.additional_metadata_updater, - self.additional_datatoken_deployer, - self.uri, - self.transferable, - self.owner or wallet.address, - {"from": wallet}, - ) - - with warnings.catch_warnings(): - warnings.filterwarnings( - "ignore", - message=".*Event log does not contain enough topics for the given ABI.*", - ) - registered_event = receipt.events["NFTCreated"] - - data_nft_address = registered_event["newTokenAddress"] - return DataNFT(config_dict, data_nft_address) - - -class DatatokenArguments: - def __init__( - self, - name: Optional[str] = "Datatoken 1", - symbol: Optional[str] = "DT1", - template_index: Optional[int] = 1, - minter: Optional[str] = None, - fee_manager: Optional[str] = None, - publish_market_order_fee_address: Optional[str] = None, - publish_market_order_fee_token: Optional[str] = None, - publish_market_order_fee_amount: Optional[int] = 0, - bytess: Optional[List[bytes]] = None, - services: Optional[list] = None, - files: Optional[List[FilesType]] = None, - consumer_parameters: Optional[List[Dict[str, Any]]] = None, - cap: Optional[int] = None, - ): - if template_index == 2 and not cap: - raise Exception("Cap is needed for Datatoken Enterprise token deployment.") - - self.cap = cap if template_index == 2 else MAX_UINT256 - - self.name = name - self.symbol = symbol - self.template_index = template_index - self.minter = minter - self.fee_manager = fee_manager - self.publish_market_order_fee_address = ( - publish_market_order_fee_address or ZERO_ADDRESS - ) - self.publish_market_order_fee_token = publish_market_order_fee_token - self.publish_market_order_fee_amount = publish_market_order_fee_amount - self.bytess = bytess or [b""] - self.services = services - self.files = files - self.consumer_parameters = consumer_parameters - - def create_datatoken(self, data_nft, wallet, with_services=False): - config_dict = data_nft.config_dict - OCEAN_address = get_ocean_token_address(config_dict) - initial_list = data_nft.getTokensList() - - data_nft.contract.createERC20( - self.template_index, - [self.name, self.symbol], - [ - ContractBase.to_checksum_address(self.minter or wallet.address), - ContractBase.to_checksum_address(self.fee_manager or wallet.address), - ContractBase.to_checksum_address(self.publish_market_order_fee_address), - ContractBase.to_checksum_address( - self.publish_market_order_fee_token or OCEAN_address - ), - ], - [self.cap, self.publish_market_order_fee_amount], - self.bytess, - {"from": wallet}, - ) - - new_elements = [ - item for item in data_nft.getTokensList() if item not in initial_list - ] - assert len(new_elements) == 1, "new data token has no address" - - datatoken = ( - Datatoken(config_dict, new_elements[0]) - if self.template_index == 1 - else DatatokenEnterprise(config_dict, new_elements[0]) - ) - - logger.info( - f"Successfully created datatoken with address " f"{datatoken.address}." - ) - - if with_services: - if not self.services: - self.services = [ - datatoken.build_access_service( - service_id="0", - service_endpoint=config_dict.get("PROVIDER_URL"), - files=self.files, - consumer_parameters=self.consumer_parameters, - ) - ] - else: - for service in self.services: - service.datatoken = datatoken.address - - return datatoken diff --git a/ocean_lib/models/data_nft.py b/ocean_lib/models/data_nft.py index c8a881b6d..571a02a50 100644 --- a/ocean_lib/models/data_nft.py +++ b/ocean_lib/models/data_nft.py @@ -2,11 +2,15 @@ # Copyright 2022 Ocean Protocol Foundation # SPDX-License-Identifier: Apache-2.0 # +import warnings from enum import IntEnum, IntFlag +from typing import Optional from enforce_typing import enforce_types from ocean_lib.models.datatoken import Datatoken +from ocean_lib.ocean.util import get_address_of_type +from ocean_lib.web3_internal.constants import ZERO_ADDRESS from ocean_lib.web3_internal.contract_base import ContractBase @@ -41,11 +45,64 @@ class DataNFT(ContractBase): def create_datatoken(self, datatoken_args, wallet) -> Datatoken: return datatoken_args.create_datatoken(self, wallet) - # TODO - # def ZERO ADDRESS - # if publish_market_order_fee_address is None: - # publish_market_order_fee_address = from_address - # def Ocean address - # if publish_market_order_fee_token is None: - # publish_market_order_fee_token = ZERO_ADDRESS +class DataNFTArguments: + def __init__( + self, + name: str, + symbol: str, + template_index: Optional[int] = 1, + additional_datatoken_deployer: Optional[str] = None, + additional_metadata_updater: Optional[str] = None, + uri: Optional[str] = None, + transferable: Optional[bool] = None, + owner: Optional[str] = None, + ): + """ + :param name: str name of data NFT if creating a new one + :param symbol: str symbol of data NFT if creating a new one + :param template_index: int template index of the data NFT, by default is 1. + :param additional_datatoken_deployer: str address of an additional ERC20 deployer. + :param additional_metadata_updater: str address of an additional metadata updater. + :param uri: str URL of the data NFT. + """ + self.name = name + self.symbol = symbol or name + self.template_index = template_index + self.additional_datatoken_deployer = ( + additional_datatoken_deployer or ZERO_ADDRESS + ) + self.additional_metadata_updater = additional_metadata_updater or ZERO_ADDRESS + self.uri = uri or "https://oceanprotocol.com/nft/" + self.transferable = transferable or True + self.owner = owner + + def deploy_contract(self, config_dict, wallet) -> DataNFT: + from ocean_lib.models.data_nft_factory import ( # isort:skip + DataNFTFactoryContract, + ) + + address = get_address_of_type(config_dict, DataNFTFactoryContract.CONTRACT_NAME) + data_nft_factory = DataNFTFactoryContract(config_dict, address) + + receipt = data_nft_factory.deployERC721Contract( + self.name, + self.symbol, + self.template_index, + self.additional_metadata_updater, + self.additional_datatoken_deployer, + self.uri, + self.transferable, + self.owner or wallet.address, + {"from": wallet}, + ) + + with warnings.catch_warnings(): + warnings.filterwarnings( + "ignore", + message=".*Event log does not contain enough topics for the given ABI.*", + ) + registered_event = receipt.events["NFTCreated"] + + data_nft_address = registered_event["newTokenAddress"] + return DataNFT(config_dict, data_nft_address) diff --git a/ocean_lib/models/data_nft_factory.py b/ocean_lib/models/data_nft_factory.py index e2614649d..6788c3ba7 100644 --- a/ocean_lib/models/data_nft_factory.py +++ b/ocean_lib/models/data_nft_factory.py @@ -12,7 +12,7 @@ from ocean_lib.models.datatoken_enterprise import DatatokenEnterprise from ocean_lib.models.erc721_token_factory_base import ERC721TokenFactoryBase from ocean_lib.models.fixed_rate_exchange import FixedRateExchange, OneExchange -from ocean_lib.ocean.util import get_address_of_type, get_ocean_token_address +from ocean_lib.ocean.util import get_address_of_type from ocean_lib.structures.abi_tuples import MetadataProof, OrderData from ocean_lib.web3_internal.contract_base import ContractBase @@ -73,8 +73,6 @@ def create_with_erc20( datatoken_args, wallet=None, ) -> str: - ocean_address = get_ocean_token_address(self.config_dict) - receipt = self.contract.createNftWithErc20( ( data_nft_args.name, @@ -95,13 +93,13 @@ def create_with_erc20( datatoken_args.fee_manager or wallet.address ), ContractBase.to_checksum_address( - datatoken_args.publish_market_order_fee_address + datatoken_args.publish_market_order_fees.address ), ContractBase.to_checksum_address( - datatoken_args.publish_market_order_fee_token or ocean_address + datatoken_args.publish_market_order_fees.token ), ], - [datatoken_args.cap, datatoken_args.publish_market_order_fee_amount], + [datatoken_args.cap, datatoken_args.publish_market_order_fees.amount], datatoken_args.bytess, ), {"from": wallet}, @@ -137,7 +135,6 @@ def create_with_erc20_and_fixed_rate( fixed_price_with_mint: int, wallet=None, ) -> str: - ocean_address = get_ocean_token_address(self.config_dict) fixed_price_address = get_address_of_type(self.config_dict, "FixedPrice") receipt = self.contract.createNftWithErc20WithFixedRate( @@ -160,13 +157,13 @@ def create_with_erc20_and_fixed_rate( datatoken_args.fee_manager or wallet.address ), ContractBase.to_checksum_address( - datatoken_args.publish_market_order_fee_address + datatoken_args.publish_market_order_fees.address ), ContractBase.to_checksum_address( - datatoken_args.publish_market_order_fee_token or ocean_address + datatoken_args.publish_market_order_fees.token ), ], - [datatoken_args.cap, datatoken_args.publish_market_order_fee_amount], + [datatoken_args.cap, datatoken_args.publish_market_order_fees.amount], datatoken_args.bytess, ), ( @@ -222,7 +219,6 @@ def create_with_erc20_and_dispenser( dispenser_allowed_swapper: str, wallet, ) -> str: - ocean_address = get_ocean_token_address(self.config_dict) dispenser_address = get_address_of_type(self.config_dict, "Dispenser") receipt = self.contract.createNftWithErc20WithDispenser( @@ -245,13 +241,13 @@ def create_with_erc20_and_dispenser( datatoken_args.fee_manager or wallet.address ), ContractBase.to_checksum_address( - datatoken_args.publish_market_order_fee_address + datatoken_args.publish_market_order_fees.address ), ContractBase.to_checksum_address( - datatoken_args.publish_market_order_fee_token or ocean_address + datatoken_args.publish_market_order_fees.token ), ], - [datatoken_args.cap, datatoken_args.publish_market_order_fee_amount], + [datatoken_args.cap, datatoken_args.publish_market_order_fees.amount], datatoken_args.bytess, ), ( diff --git a/ocean_lib/models/datatoken.py b/ocean_lib/models/datatoken.py index 5e4f72757..21f5f039b 100644 --- a/ocean_lib/models/datatoken.py +++ b/ocean_lib/models/datatoken.py @@ -2,8 +2,9 @@ # Copyright 2022 Ocean Protocol Foundation # SPDX-License-Identifier: Apache-2.0 # +import logging from enum import IntEnum -from typing import Any, List, Optional, Tuple, Union +from typing import Any, Dict, List, Optional, Tuple, Union from brownie.network.state import Chain from enforce_typing import enforce_types @@ -11,13 +12,141 @@ from ocean_lib.agreements.service_types import ServiceTypes from ocean_lib.models.fixed_rate_exchange import OneExchange -from ocean_lib.ocean.util import get_address_of_type +from ocean_lib.ocean.util import ( + get_address_of_type, + get_ocean_token_address, + str_with_wei, +) from ocean_lib.services.service import Service from ocean_lib.structures.file_objects import FilesType from ocean_lib.web3_internal.constants import MAX_UINT256, ZERO_ADDRESS from ocean_lib.web3_internal.contract_base import ContractBase checksum_addr = ContractBase.to_checksum_address +logger = logging.getLogger("ocean") + + +class TokenFeeInfo: + def __init__( + self, + address: Optional[str] = None, + token: Optional[str] = None, + amount: Optional[int] = 0, + ): + self.address = ( + Web3.toChecksumAddress(address.lower()) if address else ZERO_ADDRESS + ) + self.token = Web3.toChecksumAddress(token.lower()) if token else ZERO_ADDRESS + + self.amount = amount + + def to_tuple(self): + return (self.address, self.token, self.amount) + + @classmethod + def from_tuple(cls, tup): + address, token, amount = tup + return cls(address, token, amount) + + def __str__(self): + s = ( + f"TokenFeeInfo: \n" + f" address = {self.address}\n" + f" token = {self.token}\n" + f" amount = {str_with_wei(self.amount)}\n" + ) + return s + + +class DatatokenArguments: + def __init__( + self, + name: Optional[str] = "Datatoken 1", + symbol: Optional[str] = "DT1", + template_index: Optional[int] = 1, + minter: Optional[str] = None, + fee_manager: Optional[str] = None, + publish_market_order_fees: Optional = None, + bytess: Optional[List[bytes]] = None, + services: Optional[list] = None, + files: Optional[List[FilesType]] = None, + consumer_parameters: Optional[List[Dict[str, Any]]] = None, + cap: Optional[int] = None, + ): + if template_index == 2 and not cap: + raise Exception("Cap is needed for Datatoken Enterprise token deployment.") + + self.cap = cap if template_index == 2 else MAX_UINT256 + + self.name = name + self.symbol = symbol + self.template_index = template_index + self.minter = minter + self.fee_manager = fee_manager + self.bytess = bytess or [b""] + self.services = services + self.files = files + self.consumer_parameters = consumer_parameters + + self.publish_market_order_fees = publish_market_order_fees or TokenFeeInfo() + self.set_default_fees_at_deploy = not publish_market_order_fees + + def create_datatoken(self, data_nft, wallet, with_services=False): + config_dict = data_nft.config_dict + OCEAN_address = get_ocean_token_address(config_dict) + initial_list = data_nft.getTokensList() + + if self.set_default_fees_at_deploy: + self.publish_market_order_fees = TokenFeeInfo( + address=wallet.address, token=OCEAN_address + ) + + data_nft.contract.createERC20( + self.template_index, + [self.name, self.symbol], + [ + ContractBase.to_checksum_address(self.minter or wallet.address), + ContractBase.to_checksum_address(self.fee_manager or wallet.address), + self.publish_market_order_fees.address, + self.publish_market_order_fees.token, + ], + [self.cap, self.publish_market_order_fees.amount], + self.bytess, + {"from": wallet}, + ) + + new_elements = [ + item for item in data_nft.getTokensList() if item not in initial_list + ] + assert len(new_elements) == 1, "new data token has no address" + + from ocean_lib.models.datatoken_enterprise import DatatokenEnterprise + + datatoken = ( + Datatoken(config_dict, new_elements[0]) + if self.template_index == 1 + else DatatokenEnterprise(config_dict, new_elements[0]) + ) + + logger.info( + f"Successfully created datatoken with address " f"{datatoken.address}." + ) + + if with_services: + if not self.services: + self.services = [ + datatoken.build_access_service( + service_id="0", + service_endpoint=config_dict.get("PROVIDER_URL"), + files=self.files, + consumer_parameters=self.consumer_parameters, + ) + ] + else: + for service in self.services: + service.datatoken = datatoken.address + + return datatoken class DatatokenRoles(IntEnum): @@ -41,11 +170,13 @@ def start_order( consumer: str, service_index: int, provider_fees: dict, - consume_market_order_fee_address: str, - consume_market_order_fee_token: str, - consume_market_order_fee_amount: int, transaction_parameters: dict, + consume_market_fees=None, ) -> str: + + if not consume_market_fees: + consume_market_fees = TokenFeeInfo() + return self.contract.startOrder( checksum_addr(consumer), service_index, @@ -59,11 +190,7 @@ def start_order( provider_fees["validUntil"], provider_fees["providerData"], ), - ( - checksum_addr(consume_market_order_fee_address), - checksum_addr(consume_market_order_fee_token), - consume_market_order_fee_amount, - ), + consume_market_fees.to_tuple(), transaction_parameters, ) @@ -313,10 +440,11 @@ def dispense_and_order( service_index: int, provider_fees: dict, transaction_parameters: dict, - consume_market_order_fee_address: Optional[str] = None, - consume_market_order_fee_token: Optional[str] = None, - consume_market_order_fee_amount: Optional[int] = 0, + consume_market_fees=None, ) -> str: + if not consume_market_fees: + consume_market_fees = TokenFeeInfo() + buyer_addr = ( transaction_parameters["from"].address if hasattr(transaction_parameters["from"], "address") @@ -347,13 +475,7 @@ def dispense_and_order( consumer=ContractBase.to_checksum_address(consumer), service_index=service_index, provider_fees=provider_fees, - consume_market_order_fee_address=( - consume_market_order_fee_address or ZERO_ADDRESS - ), - consume_market_order_fee_token=( - consume_market_order_fee_token or ZERO_ADDRESS - ), - consume_market_order_fee_amount=consume_market_order_fee_amount, + consume_market_fees=consume_market_fees, transaction_parameters=transaction_parameters, ) @@ -363,27 +485,25 @@ def buy_DT_and_order( consumer: str, service_index: int, provider_fees: dict, - consume_market_order_fee_address: str, - consume_market_order_fee_token: str, - consume_market_order_fee_amount: int, exchange: Any, - max_base_token_amount: int, - consume_market_swap_fee_amount: int, - consume_market_swap_fee_address: str, transaction_parameters: dict, + consume_market_fees=None, ) -> str: fre_address = get_address_of_type(self.config_dict, "FixedPrice") # import now, to avoid circular import from ocean_lib.models.fixed_rate_exchange import OneExchange + if not consume_market_fees: + consume_market_fees = TokenFeeInfo() + if not isinstance(exchange, OneExchange): exchange = OneExchange(fre_address, exchange) exchange.buy_DT( datatoken_amt=Web3.toWei(1, "ether"), - consume_market_fee_addr=consume_market_order_fee_address, - consume_market_fee=consume_market_order_fee_amount, + consume_market_fee_addr=consume_market_fees.address, + consume_market_fee=consume_market_fees.amount, tx_dict=transaction_parameters, ) @@ -391,12 +511,13 @@ def buy_DT_and_order( consumer=ContractBase.to_checksum_address(consumer), service_index=service_index, provider_fees=provider_fees, - consume_market_order_fee_address=consume_market_order_fee_address, - consume_market_order_fee_token=consume_market_order_fee_token, - consume_market_order_fee_amount=consume_market_order_fee_amount, + consume_market_fees=consume_market_fees, transaction_parameters=transaction_parameters, ) + def get_publish_market_order_fees(self): + return TokenFeeInfo.from_tuple(self.contract.getPublishingMarketFee()) + class MockERC20(Datatoken): CONTRACT_NAME = "MockERC20" diff --git a/ocean_lib/models/datatoken_enterprise.py b/ocean_lib/models/datatoken_enterprise.py index d67627977..b0b9b3d47 100644 --- a/ocean_lib/models/datatoken_enterprise.py +++ b/ocean_lib/models/datatoken_enterprise.py @@ -2,13 +2,12 @@ # Copyright 2022 Ocean Protocol Foundation # SPDX-License-Identifier: Apache-2.0 # -from typing import Any, Optional +from typing import Any from enforce_typing import enforce_types -from ocean_lib.models.datatoken import Datatoken +from ocean_lib.models.datatoken import Datatoken, TokenFeeInfo from ocean_lib.ocean.util import get_address_of_type -from ocean_lib.web3_internal.constants import ZERO_ADDRESS from ocean_lib.web3_internal.contract_base import ContractBase checksum_addr = ContractBase.to_checksum_address @@ -23,14 +22,12 @@ def buy_DT_and_order( consumer: str, service_index: int, provider_fees: dict, - consume_market_order_fee_address: str, - consume_market_order_fee_token: str, - consume_market_order_fee_amount: int, exchange: Any, max_base_token_amount: int, consume_market_swap_fee_amount: int, consume_market_swap_fee_address: str, transaction_parameters: dict, + consume_market_fees=None, ) -> str: fre_address = get_address_of_type(self.config_dict, "FixedPrice") @@ -40,6 +37,9 @@ def buy_DT_and_order( if not isinstance(exchange, OneExchange): exchange = OneExchange(fre_address, exchange) + if not consume_market_fees: + consume_market_fees = TokenFeeInfo() + return self.contract.buyFromFreAndOrder( ( ContractBase.to_checksum_address(consumer), @@ -54,11 +54,7 @@ def buy_DT_and_order( provider_fees["validUntil"], provider_fees["providerData"], ), - ( - ContractBase.to_checksum_address(consume_market_order_fee_address), - ContractBase.to_checksum_address(consume_market_order_fee_token), - consume_market_order_fee_amount, - ), + consume_market_fees.to_tuple(), ), ( ContractBase.to_checksum_address(exchange.address), @@ -77,10 +73,11 @@ def dispense_and_order( service_index: int, provider_fees: dict, transaction_parameters: dict, - consume_market_order_fee_address: Optional[str] = None, - consume_market_order_fee_token: Optional[str] = None, - consume_market_order_fee_amount: Optional[int] = 0, + consume_market_fees=None, ) -> str: + if not consume_market_fees: + consume_market_fees = TokenFeeInfo() + dispenser_address = get_address_of_type(self.config_dict, "Dispenser") return self.contract.buyFromDispenserAndOrder( ( @@ -96,15 +93,7 @@ def dispense_and_order( provider_fees["validUntil"], provider_fees["providerData"], ), - ( - ContractBase.to_checksum_address( - consume_market_order_fee_address or ZERO_ADDRESS - ), - ContractBase.to_checksum_address( - consume_market_order_fee_token or ZERO_ADDRESS - ), - consume_market_order_fee_amount, - ), + consume_market_fees.to_tuple(), ), ContractBase.to_checksum_address(dispenser_address), transaction_parameters, diff --git a/ocean_lib/models/fixed_rate_exchange.py b/ocean_lib/models/fixed_rate_exchange.py index 851c92570..9e8792afa 100644 --- a/ocean_lib/models/fixed_rate_exchange.py +++ b/ocean_lib/models/fixed_rate_exchange.py @@ -54,7 +54,7 @@ def __str__(self): @enforce_types -class FeesInfo: +class ExchangeFeeInfo: def __init__(self, fees_tup): """ :param:details_tup @@ -70,7 +70,7 @@ def __init__(self, fees_tup): def __str__(self): s = ( - f"FeesInfo: \n" + f"ExchangeFeeInfo: \n" f" publish_market_fee = {str_with_wei(self.publish_market_fee)}\n" f" publish_market_fee_available" f" = {str_with_wei(self.publish_market_fee_available)}\n" @@ -379,10 +379,10 @@ def get_allowed_swapper(self) -> str: return self._FRE.getAllowedSwapper(self._id) @property - def fees_info(self) -> FeesInfo: + def exchange_fees_info(self) -> ExchangeFeeInfo: """Get fee information for this exchange, as an object""" tup = self._FRE.getFeesInfo(self._id) - return FeesInfo(tup) + return ExchangeFeeInfo(tup) @enforce_types def is_active(self) -> bool: diff --git a/ocean_lib/models/test/test_data_nft.py b/ocean_lib/models/test/test_data_nft.py index 5e302a144..19d3cceb1 100644 --- a/ocean_lib/models/test/test_data_nft.py +++ b/ocean_lib/models/test/test_data_nft.py @@ -5,12 +5,10 @@ import pytest from web3 import Web3 -from ocean_lib.models.arguments import DataNFTArguments, DatatokenArguments -from ocean_lib.models.data_nft import DataNFTPermissions +from ocean_lib.models.data_nft import DataNFTArguments, DataNFTPermissions from ocean_lib.models.data_nft_factory import DataNFTFactoryContract -from ocean_lib.models.datatoken import Datatoken +from ocean_lib.models.datatoken import Datatoken, DatatokenArguments, TokenFeeInfo from ocean_lib.ocean.util import get_address_of_type, to_wei -from ocean_lib.web3_internal.constants import ZERO_ADDRESS BLOB = "f8929916089218bdb4aa78c3ecd16633afd44b8aef89299160" @@ -324,8 +322,6 @@ def test_create_datatoken( "DT1", "DT1Symbol", fee_manager=consumer_wallet.address, - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, ), publisher_wallet, ) @@ -338,9 +334,6 @@ def test_create_datatoken( symbol="DatatokenEnterpriseDT1Symbol", minter=publisher_wallet.address, fee_manager=consumer_wallet.address, - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, - publish_market_order_fee_amount=0, bytess=[b""], cap=Web3.toWei("0.1", "ether"), ), @@ -369,22 +362,20 @@ def test_create_datatoken_with_usdc_order_fee( DatatokenArguments( name="DT1", symbol="DT1Symbol", - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=usdc.address, - publish_market_order_fee_amount=publish_market_order_fee_amount_in_wei, + publish_market_order_fees=TokenFeeInfo( + address=publisher_wallet.address, + token=usdc.address, + amount=publish_market_order_fee_amount_in_wei, + ), ), publisher_wallet, ) # Check publish fee info - ( - publish_market_order_fee_address, - publish_market_order_fee_token, - publish_market_order_fee_amount, - ) = dt.getPublishingMarketFee() - assert publish_market_order_fee_address == publisher_wallet.address - assert publish_market_order_fee_token == usdc.address - assert publish_market_order_fee_amount == publish_market_order_fee_amount_in_wei + publish_market_fees = dt.get_publish_market_order_fees() + assert publish_market_fees.address == publisher_wallet.address + assert publish_market_fees.token == usdc.address + assert publish_market_fees.amount == publish_market_order_fee_amount_in_wei @pytest.mark.unit @@ -414,8 +405,6 @@ def test_create_datatoken_with_non_owner( symbol="DT1Symbol", minter=publisher_wallet.address, fee_manager=publisher_wallet.address, - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, ), consumer_wallet, ) @@ -449,8 +438,6 @@ def test_fail_creating_erc20( name="DT1", symbol="DT1Symbol", minter=publisher_wallet.address, - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, ), consumer_wallet, ) @@ -516,8 +503,6 @@ def test_erc721_datatoken_functions( name="DT1", symbol="DT1Symbol", minter=publisher_wallet.address, - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, ), consumer_wallet, ) @@ -622,8 +607,9 @@ def test_transfer_nft( DatatokenArguments( "DT1", "DT1Symbol", - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, + publish_market_order_fees=TokenFeeInfo( + address=publisher_wallet.address, + ), ), consumer_wallet, ) @@ -639,7 +625,7 @@ def test_transfer_nft( OCEAN = publisher_ocean.OCEAN_token OCEAN.approve(factory_router.address, to_wei(10000), {"from": consumer_wallet}) - # Make consumer the publish_market_order_fee_address instead of publisher + # Make consumer the publish market order fee address instead of publisher receipt = datatoken.setPublishingMarketFee( consumer_wallet.address, OCEAN.address, @@ -650,10 +636,10 @@ def test_transfer_nft( set_publishing_fee_event = receipt.events["PublishMarketFeeChanged"] assert set_publishing_fee_event, "Cannot find PublishMarketFeeChanged event." - publish_fees = datatoken.getPublishingMarketFee() - assert publish_fees[0] == consumer_wallet.address - assert publish_fees[1] == OCEAN.address - assert publish_fees[2] == to_wei(1) + publish_fees = datatoken.get_publish_market_order_fees() + assert publish_fees.address == consumer_wallet.address + assert publish_fees.token == OCEAN.address + assert publish_fees.amount == to_wei(1) def test_nft_transfer_with_fre( @@ -787,8 +773,6 @@ def test_nft_owner_transfer(config, publisher_wallet, consumer_wallet, data_NFT_ DatatokenArguments( name="DT1", symbol="DT1Symbol", - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, ), publisher_wallet, ) @@ -801,8 +785,6 @@ def test_nft_owner_transfer(config, publisher_wallet, consumer_wallet, data_NFT_ DatatokenArguments( name="DT1", symbol="DT1Symbol", - publish_market_order_fee_address=consumer_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, ), consumer_wallet, ) diff --git a/ocean_lib/models/test/test_data_nft_factory.py b/ocean_lib/models/test/test_data_nft_factory.py index 41f96d3f3..032a5b438 100644 --- a/ocean_lib/models/test/test_data_nft_factory.py +++ b/ocean_lib/models/test/test_data_nft_factory.py @@ -6,9 +6,8 @@ from brownie import network from web3.main import Web3 -from ocean_lib.models.arguments import DataNFTArguments, DatatokenArguments -from ocean_lib.models.data_nft import DataNFT -from ocean_lib.models.datatoken import Datatoken +from ocean_lib.models.data_nft import DataNFT, DataNFTArguments +from ocean_lib.models.datatoken import Datatoken, DatatokenArguments, TokenFeeInfo from ocean_lib.models.dispenser import Dispenser from ocean_lib.ocean.util import create_checksum, get_address_of_type from ocean_lib.structures.abi_tuples import OrderData @@ -51,8 +50,6 @@ def test_nft_creation( "DT1P", "DT1Symbol", fee_manager=consumer_wallet.address, - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, ), publisher_wallet, ) @@ -88,8 +85,6 @@ def test_combo_functions( "DTB1", "DT1Symbol", fee_manager=consumer_wallet.address, - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, ), wallet=publisher_wallet, ) @@ -107,9 +102,11 @@ def test_combo_functions( "DT1P", "DT1SymbolP", fee_manager=consumer_wallet.address, - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, - publish_market_order_fee_amount=Web3.toWei("0.0005", "ether"), + publish_market_order_fees=TokenFeeInfo( + address=publisher_wallet.address, + token=ZERO_ADDRESS, + amount=Web3.toWei("0.0005", "ether"), + ), ), publisher_wallet, ) @@ -126,8 +123,6 @@ def test_combo_functions( "DTWithPool", "DTP", fee_manager=consumer_wallet.address, - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, ), fixed_price_base_token=fee_datatoken_address, fixed_price_owner=publisher_wallet.address, @@ -156,8 +151,6 @@ def test_combo_functions( "DTWithPool", "DTP", fee_manager=consumer_wallet.address, - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, ), dispenser_max_tokens=Web3.toWei(1, "ether"), dispenser_max_balance=Web3.toWei(1, "ether"), @@ -224,8 +217,6 @@ def test_start_multiple_order( name="DT1", symbol="DT1Symbol", minter=publisher_wallet.address, - publish_market_order_fee_address=publisher_wallet.address, - publish_market_order_fee_token=ZERO_ADDRESS, ), consumer_wallet, ) diff --git a/ocean_lib/models/test/test_datatoken.py b/ocean_lib/models/test/test_datatoken.py index 4310224cb..ab5780ace 100644 --- a/ocean_lib/models/test/test_datatoken.py +++ b/ocean_lib/models/test/test_datatoken.py @@ -6,8 +6,7 @@ from brownie import network from web3.main import Web3 -from ocean_lib.models.arguments import DatatokenArguments -from ocean_lib.models.datatoken import DatatokenRoles +from ocean_lib.models.datatoken import DatatokenArguments, DatatokenRoles, TokenFeeInfo from ocean_lib.ocean.util import get_address_of_type from ocean_lib.web3_internal.constants import MAX_UINT256 from tests.resources.helper_functions import get_mock_provider_fees @@ -127,9 +126,10 @@ def test_start_order(config, publisher_wallet, consumer_wallet, data_NFT_and_DT) consumer=consumer_wallet.address, service_index=1, provider_fees=provider_fees, - consume_market_order_fee_address=publisher_wallet.address, - consume_market_order_fee_token=datatoken.address, - consume_market_order_fee_amount=0, + consume_market_fees=TokenFeeInfo( + address=publisher_wallet.address, + token=datatoken.address, + ), transaction_parameters={"from": publisher_wallet}, ) # Check erc20 balances @@ -217,14 +217,14 @@ def test_start_order(config, publisher_wallet, consumer_wallet, data_NFT_and_DT) {"from": publisher_wallet}, ) - publish_fees = datatoken.getPublishingMarketFee() + publish_fees = datatoken.get_publish_market_order_fees() # PublishMarketFeeAddress set previously - assert publish_fees[0] == publisher_wallet.address + assert publish_fees.address == publisher_wallet.address # PublishMarketFeeToken set previously - assert publish_fees[1] == get_address_of_type(config, "MockUSDC") + assert publish_fees.token == get_address_of_type(config, "MockUSDC") # PublishMarketFeeAmount set previously - assert publish_fees[2] == Web3.toWei("1.2", "ether") + assert publish_fees.amount == Web3.toWei("1.2", "ether") # Fee collector assert datatoken.getPaymentCollector() == get_address_of_type( config, "OPFCommunityFeeCollector" diff --git a/ocean_lib/models/test/test_datatoken_order_both_templates.py b/ocean_lib/models/test/test_datatoken_order_both_templates.py index 59bbd9f85..ec360f0db 100644 --- a/ocean_lib/models/test/test_datatoken_order_both_templates.py +++ b/ocean_lib/models/test/test_datatoken_order_both_templates.py @@ -6,7 +6,7 @@ import pytest -from ocean_lib.models.datatoken import Datatoken +from ocean_lib.models.datatoken import Datatoken, TokenFeeInfo from ocean_lib.ocean.util import from_wei, get_address_of_type, to_wei from ocean_lib.web3_internal.constants import MAX_UINT256 from tests.resources.helper_functions import deploy_erc721_erc20, get_mock_provider_fees @@ -55,11 +55,11 @@ def test_dispense_and_order_with_non_defaults( {"from": publisher_wallet}, ) - (publishMarketFeeAddress, _, publishMarketFeeAmount) = DT.getPublishingMarketFee() + publish_market_fees = DT.get_publish_market_order_fees() USDC.transfer( publisher_wallet.address, - publishMarketFeeAmount, + publish_market_fees.amount, {"from": factory_deployer_wallet}, ) @@ -94,9 +94,10 @@ def test_dispense_and_order_with_non_defaults( consumer=consume_fee_address, service_index=1, provider_fees=provider_fees, - consume_market_order_fee_address=consume_fee_address, - consume_market_order_fee_token=DAI.address, - consume_market_order_fee_amount=0, + consume_market_fees=TokenFeeInfo( + address=consume_fee_address, + token=DAI.address, + ), transaction_parameters={"from": publisher_wallet}, ) @@ -104,7 +105,7 @@ def test_dispense_and_order_with_non_defaults( assert DT.totalSupply() == to_wei(0) balance_opf_consume = DAI.balanceOf(opf_collector_address) - balance_publish = USDC.balanceOf(publishMarketFeeAddress) + balance_publish = USDC.balanceOf(publish_market_fees.address) assert balance_opf_consume - balance_opf_consume_before == 0 assert balance_publish - publish_bal_before == to_wei(2) @@ -188,11 +189,11 @@ def test_buy_DT_and_order( {"from": publisher_wallet}, ) - (publishMarketFeeAddress, _, publishMarketFeeAmount) = DT.getPublishingMarketFee() + publish_market_fees = DT.get_publish_market_order_fees() USDC.transfer( publisher_wallet.address, - publishMarketFeeAmount + to_wei(3), + publish_market_fees.amount + to_wei(3), {"from": factory_deployer_wallet}, ) USDC.approve( @@ -220,19 +221,24 @@ def test_buy_DT_and_order( publish_bal1 = USDC.balanceOf(consumer_wallet.address) provider_fee_bal1 = USDC.balanceOf(another_consumer_wallet.address) - tx = DT.buy_DT_and_order( - consumer=another_consumer_wallet.address, - service_index=1, - provider_fees=provider_fees, - consume_market_order_fee_address=consume_fee_address, - consume_market_order_fee_token=DAI.address, - consume_market_order_fee_amount=0, - exchange=exchange, - max_base_token_amount=to_wei(2.5), - consume_market_swap_fee_amount=to_wei(0.001), # 1e15 => 0.1% - consume_market_swap_fee_address=another_consumer_wallet.address, - transaction_parameters={"from": publisher_wallet}, - ) + args = { + "consumer": another_consumer_wallet.address, + "service_index": 1, + "provider_fees": provider_fees, + "consume_market_fees": TokenFeeInfo( + address=consume_fee_address, + token=DAI.address, + ), + "exchange": exchange, + "transaction_parameters": {"from": publisher_wallet}, + } + + if template_index == 2: + args["max_base_token_amount"] = to_wei(2.5) + args["consume_market_swap_fee_amount"] = to_wei(0.001) # 1e15 => 0.1% + args["consume_market_swap_fee_address"] = another_consumer_wallet.address + + tx = DT.buy_DT_and_order(**args) assert tx @@ -241,7 +247,7 @@ def test_buy_DT_and_order( provider_fee_bal2 = USDC.balanceOf(another_consumer_wallet.address) consume_bal2 = DAI.balanceOf(consume_fee_address) - publish_bal2 = USDC.balanceOf(publishMarketFeeAddress) + publish_bal2 = USDC.balanceOf(publish_market_fees.address) assert from_wei(consume_bal2) == from_wei(consume_bal1) diff --git a/ocean_lib/models/test/test_exchange_fees.py b/ocean_lib/models/test/test_exchange_fees.py index 21f84add9..a62617d57 100644 --- a/ocean_lib/models/test/test_exchange_fees.py +++ b/ocean_lib/models/test/test_exchange_fees.py @@ -2,8 +2,8 @@ # Copyright 2022 Ocean Protocol Foundation # SPDX-License-Identifier: Apache-2.0 # -from decimal import Decimal import time +from decimal import Decimal import pytest from web3.main import Web3 @@ -18,8 +18,8 @@ from ocean_lib.ocean.util import get_address_of_type from ocean_lib.web3_internal.constants import MAX_UINT256, ZERO_ADDRESS from tests.resources.helper_functions import ( - get_wallet, convert_bt_amt_to_dt, + get_wallet, int_units, transfer_bt_if_balance_lte, ) @@ -112,7 +112,7 @@ def test_exchange_swap_fees( allowed_swapper=ZERO_ADDRESS, ) - fees = exchange.fees_info + fees = exchange.exchange_fees_info # Verify fee collectors are configured correctly assert fees.publish_market_fee_collector == alice.address @@ -199,7 +199,7 @@ def test_exchange_swap_fees( # Update publish market swap fee new_publish_market_swap_fee = Web3.toWei(0.09, "ether") exchange.update_publish_market_fee(new_publish_market_swap_fee, {"from": alice}) - assert exchange.fees_info.publish_market_fee == new_publish_market_swap_fee + assert exchange.exchange_fees_info.publish_market_fee == new_publish_market_swap_fee # Increase rate (base tokens per datatoken) by 1 new_bt_per_dt_in_wei = bt_per_dt_in_wei + Web3.toWei("1", "ether") @@ -258,8 +258,10 @@ def buy_or_sell_dt_and_verify_balances_swap_fees( BT_exchange1 = details.bt_balance DT_exchange1 = details.dt_balance - BT_publish_market_fee_avail1 = exchange.fees_info.publish_market_fee_available - BT_opc_fee_avail1 = exchange.fees_info.ocean_fee_available + BT_publish_market_fee_avail1 = ( + exchange.exchange_fees_info.publish_market_fee_available + ) + BT_opc_fee_avail1 = exchange.exchange_fees_info.ocean_fee_available BT_consume_market_fee_avail1 = bt.balanceOf(consume_market_swap_fee_address) if action == "buy": @@ -333,8 +335,10 @@ def buy_or_sell_dt_and_verify_balances_swap_fees( # Get current fee balances # Exchange fees are always base tokens - BT_publish_market_fee_avail2 = exchange.fees_info.publish_market_fee_available - BT_opc_fee_avail2 = exchange.fees_info.ocean_fee_available + BT_publish_market_fee_avail2 = ( + exchange.exchange_fees_info.publish_market_fee_available + ) + BT_opc_fee_avail2 = exchange.exchange_fees_info.ocean_fee_available BT_consume_market_fee_avail2 = bt.balanceOf(consume_market_swap_fee_address) # Check fees @@ -399,11 +403,13 @@ def collect_fee_and_verify_balances( bt = Datatoken(config, exchange.details.base_token) if fee_type == "publish_market_fee": - BT_exchange_fee_avail1 = exchange.fees_info.publish_market_fee_available + BT_exchange_fee_avail1 = ( + exchange.exchange_fees_info.publish_market_fee_available + ) method = exchange.collect_publish_market_fee - fee_collector = exchange.fees_info.publish_market_fee_collector + fee_collector = exchange.exchange_fees_info.publish_market_fee_collector elif fee_type == "ocean_fee": - BT_exchange_fee_avail1 = exchange.fees_info.ocean_fee_available + BT_exchange_fee_avail1 = exchange.exchange_fees_info.ocean_fee_available method = exchange.collect_ocean_fee fee_collector = FRE.get_opc_collector() else: @@ -416,9 +422,11 @@ def collect_fee_and_verify_balances( time.sleep(10) # FIXME, we shouldn't need this! if fee_type == "publish_market_fee": - BT_exchange_fee_avail2 = exchange.fees_info.publish_market_fee_available + BT_exchange_fee_avail2 = ( + exchange.exchange_fees_info.publish_market_fee_available + ) else: - BT_exchange_fee_avail2 = exchange.fees_info.opc_fee_available + BT_exchange_fee_avail2 = exchange.exchange_fees_info.opc_fee_available BT_fee_collector2 = bt.balanceOf(fee_collector) diff --git a/ocean_lib/models/test/test_exchange_main.py b/ocean_lib/models/test/test_exchange_main.py index 6382682a2..3a33659aa 100644 --- a/ocean_lib/models/test/test_exchange_main.py +++ b/ocean_lib/models/test/test_exchange_main.py @@ -3,23 +3,19 @@ # SPDX-License-Identifier: Apache-2.0 # import time -import pytest +import pytest from ocean_lib.models.fixed_rate_exchange import ( - ExchangeDetails, - FeesInfo, BtNeeded, BtReceived, - FixedRateExchange, - OneExchange, + ExchangeDetails, + ExchangeFeeInfo, ) from ocean_lib.models.test.test_factory_router import OPC_SWAP_FEE_APPROVED -from ocean_lib.ocean.util import to_wei, from_wei +from ocean_lib.ocean.util import from_wei, to_wei from ocean_lib.web3_internal.constants import MAX_UINT256, ZERO_ADDRESS -from tests.resources.helper_functions import get_wallet - @pytest.mark.unit def test_with_defaults(OCEAN, DT, alice, bob): @@ -35,12 +31,11 @@ def test_with_defaults(OCEAN, DT, alice, bob): DT.approve(exchange.address, to_wei(100), {"from": alice}) # Bob lets exchange pull the OCEAN needed - consume_market_fee = 0 OCEAN.approve(exchange.address, MAX_UINT256, {"from": bob}) # Bob buys 2 datatokens DT_bob1 = DT.balanceOf(bob) - tx = exchange.buy_DT(datatoken_amt=to_wei(2), tx_dict={"from": bob}) + _ = exchange.buy_DT(datatoken_amt=to_wei(2), tx_dict={"from": bob}) assert from_wei(DT.balanceOf(bob)) == from_wei(DT_bob1) + 2 # all exchanges for this DT @@ -62,7 +57,7 @@ def test_with_defaults(OCEAN, DT, alice, bob): assert not details.with_mint # Fees tests - fees = exchange.fees_info + fees = exchange.exchange_fees_info assert from_wei(fees.publish_market_fee) == 0 # publish mkt swap fee assert fees.publish_market_fee_collector == alice.address # for publish mkt swaps assert ( @@ -146,8 +141,8 @@ def test_with_nondefaults(OCEAN, DT, alice, bob, carlos, dan, FRE): assert exchange.details.owner == bob.address assert exchange.details.with_mint - assert exchange.fees_info.publish_market_fee == publish_market_fee - assert exchange.fees_info.publish_market_fee_collector == alice.address + assert exchange.exchange_fees_info.publish_market_fee == publish_market_fee + assert exchange.exchange_fees_info.publish_market_fee_collector == alice.address assert exchange.get_allowed_swapper() == carlos.address @@ -237,7 +232,7 @@ def test_with_nondefaults(OCEAN, DT, alice, bob, carlos, dan, FRE): # ========================================================================== # As publish market fee collector, Alice collects fees - fees = exchange.fees_info + fees = exchange.exchange_fees_info assert fees.publish_market_fee > 0 assert fees.publish_market_fee_available > 0 @@ -301,11 +296,11 @@ def test_ExchangeDetails(): s = str(details) assert "ExchangeDetails" in s assert f"datatoken = {datatoken}" in s - assert f"rate " in s + assert "rate " in s @pytest.mark.unit -def test_FeesInfo(): +def test_ExchangeFeeInfo(): mkt_fee = to_wei(0.03) mkt_fee_coll = "0xabc" opc_fee = to_wei(0.04) @@ -313,7 +308,7 @@ def test_FeesInfo(): opc_avail = to_wei(0.6) tup = [mkt_fee, mkt_fee_coll, opc_fee, mkt_avail, opc_avail] - fees = FeesInfo(tup) + fees = ExchangeFeeInfo(tup) assert fees.publish_market_fee == mkt_fee assert fees.publish_market_fee_collector == mkt_fee_coll @@ -323,7 +318,7 @@ def test_FeesInfo(): # Test str. Don't need to be thorough s = str(fees) - assert "FeesInfo" in s + assert "ExchangeFeeInfo" in s assert f"publish_market_fee_collector = {mkt_fee_coll}" in s diff --git a/ocean_lib/ocean/ocean_assets.py b/ocean_lib/ocean/ocean_assets.py index d55262336..f675c6dbc 100644 --- a/ocean_lib/ocean/ocean_assets.py +++ b/ocean_lib/ocean/ocean_assets.py @@ -23,11 +23,10 @@ from ocean_lib.data_provider.data_encryptor import DataEncryptor from ocean_lib.data_provider.data_service_provider import DataServiceProvider from ocean_lib.exceptions import AquariusError, InsufficientBalance -from ocean_lib.models.arguments import DataNFTArguments, DatatokenArguments from ocean_lib.models.compute_input import ComputeInput -from ocean_lib.models.data_nft import DataNFT -from ocean_lib.models.datatoken import Datatoken -from ocean_lib.ocean.util import create_checksum, get_ocean_token_address +from ocean_lib.models.data_nft import DataNFT, DataNFTArguments +from ocean_lib.models.datatoken import Datatoken, DatatokenArguments, TokenFeeInfo +from ocean_lib.ocean.util import create_checksum from ocean_lib.services.service import Service from ocean_lib.structures.algorithm_metadata import AlgorithmMetadata from ocean_lib.structures.file_objects import ( @@ -523,21 +522,12 @@ def pay_for_access_service( ddo: DDO, wallet, service: Optional[Service] = None, - consume_market_order_fee_address: Optional[str] = None, - consume_market_order_fee_token: Optional[str] = None, - consume_market_order_fee_amount: Optional[int] = None, + consume_market_fees: Optional[TokenFeeInfo] = None, consumer_address: Optional[str] = None, userdata: Optional[dict] = None, ): # fill in good defaults as needed service = service or ddo.services[0] - consume_market_order_fee_address = ( - consume_market_order_fee_address or wallet.address - ) - consume_market_order_fee_amount = consume_market_order_fee_amount or 0 - if consume_market_order_fee_token is None: - OCEAN_address = get_ocean_token_address(self._config_dict) - consume_market_order_fee_token = OCEAN_address consumer_address = consumer_address or wallet.address # main work... @@ -575,9 +565,7 @@ def pay_for_access_service( consumer=consumer_address, service_index=ddo.get_index_of_service(service), provider_fees=provider_fees, - consume_market_order_fee_address=consume_market_order_fee_address, - consume_market_order_fee_token=consume_market_order_fee_token, - consume_market_order_fee_amount=consume_market_order_fee_amount, + consume_market_fees=consume_market_fees, transaction_parameters={"from": wallet}, ) @@ -613,9 +601,11 @@ def pay_for_compute_service( self._start_or_reuse_order_based_on_initialize_response( datasets[i], item, - consume_market_order_fee_address, - datasets[i].consume_market_order_fee_token, - datasets[i].consume_market_order_fee_amount, + TokenFeeInfo( + consume_market_order_fee_address, + datasets[i].consume_market_order_fee_token, + datasets[i].consume_market_order_fee_amount, + ), wallet, consumer_address, ) @@ -624,9 +614,11 @@ def pay_for_compute_service( self._start_or_reuse_order_based_on_initialize_response( algorithm_data, result["algorithm"], - consume_market_order_fee_address, - algorithm_data.consume_market_order_fee_token, - algorithm_data.consume_market_order_fee_amount, + TokenFeeInfo( + address=consume_market_order_fee_address, + token=algorithm_data.consume_market_order_fee_token, + amount=algorithm_data.consume_market_order_fee_amount, + ), wallet, consumer_address, ) @@ -640,9 +632,7 @@ def _start_or_reuse_order_based_on_initialize_response( self, asset_compute_input: ComputeInput, item: dict, - consume_market_order_fee_address: str, - consume_market_order_fee_token: str, - consume_market_order_fee_amount: int, + consume_market_fees: TokenFeeInfo, wallet, consumer_address: Optional[str] = None, ): @@ -668,8 +658,6 @@ def _start_or_reuse_order_based_on_initialize_response( consumer=consumer_address, service_index=asset_compute_input.ddo.get_index_of_service(service), provider_fees=provider_fees, - consume_market_order_fee_address=consume_market_order_fee_address, - consume_market_order_fee_token=consume_market_order_fee_token, - consume_market_order_fee_amount=consume_market_order_fee_amount, + consume_market_fees=consume_market_fees, transaction_parameters={"from": wallet}, ).txid diff --git a/ocean_lib/ocean/test/test_ocean_assets.py b/ocean_lib/ocean/test/test_ocean_assets.py index 4dfd038dc..d44b0a5c6 100644 --- a/ocean_lib/ocean/test/test_ocean_assets.py +++ b/ocean_lib/ocean/test/test_ocean_assets.py @@ -17,9 +17,9 @@ from ocean_lib.assets.ddo import DDO from ocean_lib.example_config import DEFAULT_PROVIDER_URL from ocean_lib.exceptions import AquariusError, InsufficientBalance -from ocean_lib.models.arguments import DataNFTArguments +from ocean_lib.models.data_nft import DataNFTArguments from ocean_lib.models.data_nft_factory import DataNFTFactoryContract -from ocean_lib.ocean.ocean_assets import DatatokenArguments +from ocean_lib.models.datatoken import DatatokenArguments, TokenFeeInfo from ocean_lib.ocean.util import get_address_of_type from ocean_lib.services.service import Service from ocean_lib.web3_internal.constants import ZERO_ADDRESS @@ -351,9 +351,7 @@ def test_pay_for_access_service_insufficient_balance( ddo, empty_wallet, get_first_service_by_type(ddo, "access"), - consume_market_order_fee_address=empty_wallet.address, - consume_market_order_fee_token=datatoken.address, - consume_market_order_fee_amount=0, + TokenFeeInfo(address=empty_wallet.address, token=datatoken.address), ) diff --git a/tests/flows/test_reuse_order_fees.py b/tests/flows/test_reuse_order_fees.py index 018298377..2ed7ef276 100644 --- a/tests/flows/test_reuse_order_fees.py +++ b/tests/flows/test_reuse_order_fees.py @@ -8,7 +8,7 @@ import pytest from web3.main import Web3 -from ocean_lib.models.datatoken import Datatoken +from ocean_lib.models.datatoken import Datatoken, TokenFeeInfo from ocean_lib.models.factory_router import FactoryRouter from ocean_lib.ocean.util import get_address_of_type from ocean_lib.structures.file_objects import FilesType @@ -73,9 +73,11 @@ def test_reuse_order_fees( file=file1, data_nft=data_nft, publisher_wallet=publisher_wallet, - publish_market_order_fee_address=publish_market_wallet.address, - publish_market_order_fee_token=bt.address, - publish_market_order_fee_amount=int_units("10", bt.decimals()), + publish_market_order_fees=TokenFeeInfo( + address=publish_market_wallet.address, + token=bt.address, + amount=int_units("10", bt.decimals()), + ), timeout=5, ) @@ -111,9 +113,11 @@ def test_reuse_order_fees( consumer=consumer_wallet.address, service_index=ddo.get_index_of_service(service), provider_fees=provider_fees, - consume_market_order_fee_address=consume_market_wallet.address, - consume_market_order_fee_token=bt.address, - consume_market_order_fee_amount=int_units("10", bt.decimals()), + consume_market_fees=TokenFeeInfo( + address=consume_market_wallet.address, + token=bt.address, + amount=int_units("10", bt.decimals()), + ), transaction_parameters={"from": consumer_wallet}, ) diff --git a/tests/flows/test_start_order_fees.py b/tests/flows/test_start_order_fees.py index 5e4f85e3a..ba971d13d 100644 --- a/tests/flows/test_start_order_fees.py +++ b/tests/flows/test_start_order_fees.py @@ -11,9 +11,8 @@ from ocean_lib.agreements.service_types import ServiceTypes from ocean_lib.assets.ddo import DDO from ocean_lib.data_provider.data_service_provider import DataServiceProvider -from ocean_lib.models.arguments import DatatokenArguments from ocean_lib.models.data_nft import DataNFT -from ocean_lib.models.datatoken import Datatoken +from ocean_lib.models.datatoken import Datatoken, DatatokenArguments, TokenFeeInfo from ocean_lib.models.factory_router import FactoryRouter from ocean_lib.ocean.ocean_assets import OceanAssets from ocean_lib.ocean.util import get_address_of_type @@ -91,9 +90,11 @@ def test_start_order_fees( file=file1, data_nft=data_nft, publisher_wallet=publisher_wallet, - publish_market_order_fee_address=publish_market_wallet.address, - publish_market_order_fee_token=bt.address, - publish_market_order_fee_amount=publish_market_order_fee, + publish_market_order_fees=TokenFeeInfo( + address=publish_market_wallet.address, + token=bt.address, + amount=publish_market_order_fee, + ), timeout=3600, ) @@ -148,9 +149,11 @@ def test_start_order_fees( consumer=consumer_wallet.address, service_index=ddo.get_index_of_service(service), provider_fees=provider_fees, - consume_market_order_fee_address=consume_market_wallet.address, - consume_market_order_fee_token=bt.address, - consume_market_order_fee_amount=consume_market_order_fee, + consume_market_fees=TokenFeeInfo( + address=consume_market_wallet.address, + token=bt.address, + amount=consume_market_order_fee, + ), transaction_parameters={"from": consumer_wallet}, ) @@ -169,8 +172,7 @@ def test_start_order_fees( opc_dt_balance_after = dt.balanceOf(opc_collector_address) # Get order fee amount - publish_market_order_fee_amount = dt.getPublishingMarketFee()[2] - assert publish_market_order_fee_amount == publish_market_order_fee + assert dt.get_publish_market_order_fees().amount == publish_market_order_fee # Get Ocean community fee amount opc_order_fee = factory_router.getOPCConsumeFee() @@ -213,9 +215,7 @@ def create_asset_with_order_fee_and_timeout( file: FilesType, data_nft: DataNFT, publisher_wallet, - publish_market_order_fee_address: str, - publish_market_order_fee_token: str, - publish_market_order_fee_amount: int, + publish_market_order_fees, timeout: int, ) -> Tuple[DDO, Service, Datatoken]: @@ -224,9 +224,7 @@ def create_asset_with_order_fee_and_timeout( DatatokenArguments( name="Datatoken 1", symbol="DT1", - publish_market_order_fee_address=publish_market_order_fee_address, - publish_market_order_fee_token=publish_market_order_fee_token, - publish_market_order_fee_amount=publish_market_order_fee_amount, + publish_market_order_fees=publish_market_order_fees, ), publisher_wallet, ) diff --git a/tests/integration/ganache/test_consume_flow.py b/tests/integration/ganache/test_consume_flow.py index a23c211e0..20d1df03b 100644 --- a/tests/integration/ganache/test_consume_flow.py +++ b/tests/integration/ganache/test_consume_flow.py @@ -12,10 +12,8 @@ from ocean_lib.data_provider.data_service_provider import DataServiceProvider from ocean_lib.ocean.ocean_assets import OceanAssets from ocean_lib.ocean.util import get_address_of_type -from ocean_lib.web3_internal.constants import ZERO_ADDRESS from tests.resources.ddo_helpers import get_first_service_by_type -"""branin.arff dataset, permanently stored in Arweave""" ARWEAVE_TRANSACTION_ID = "a4qJoQZa1poIv5guEzkfgZYSAD0uYm7Vw4zm_tCswVQ" @@ -91,9 +89,6 @@ def test_consume_asset(config: dict, publisher_wallet, consumer_wallet, asset_ty consumer=consumer_wallet.address, service_index=ddo.get_index_of_service(service), provider_fees=provider_fees, - consume_market_order_fee_address=ZERO_ADDRESS, - consume_market_order_fee_token=ZERO_ADDRESS, - consume_market_order_fee_amount=0, transaction_parameters={"from": consumer_wallet}, ) diff --git a/tests/integration/ganache/test_graphql.py b/tests/integration/ganache/test_graphql.py index 062343bff..d2ae1bccd 100644 --- a/tests/integration/ganache/test_graphql.py +++ b/tests/integration/ganache/test_graphql.py @@ -10,11 +10,10 @@ from ocean_lib.agreements.service_types import ServiceTypes from ocean_lib.data_provider.data_service_provider import DataServiceProvider -from ocean_lib.models.datatoken import Datatoken +from ocean_lib.models.datatoken import Datatoken, DatatokenArguments from ocean_lib.ocean.ocean import Ocean -from ocean_lib.ocean.ocean_assets import DatatokenArguments, OceanAssets +from ocean_lib.ocean.ocean_assets import OceanAssets from ocean_lib.structures.file_objects import GraphqlQuery -from ocean_lib.web3_internal.constants import ZERO_ADDRESS from tests.resources.ddo_helpers import get_first_service_by_type @@ -69,9 +68,6 @@ def test_consume_simple_graphql_query( consumer=consumer_wallet.address, service_index=ddo.get_index_of_service(service), provider_fees=provider_fees, - consume_market_order_fee_address=ZERO_ADDRESS, - consume_market_order_fee_token=ZERO_ADDRESS, - consume_market_order_fee_amount=0, transaction_parameters={"from": consumer_wallet}, ) @@ -192,9 +188,6 @@ def test_consume_parametrized_graphql_query( consumer=consumer_wallet.address, service_index=ddo.get_index_of_service(service), provider_fees=provider_fees, - consume_market_order_fee_address=ZERO_ADDRESS, - consume_market_order_fee_token=ZERO_ADDRESS, - consume_market_order_fee_amount=0, transaction_parameters={"from": consumer_wallet}, ) diff --git a/tests/integration/ganache/test_market_flow.py b/tests/integration/ganache/test_market_flow.py index 9a8fd1f3b..2121be66a 100644 --- a/tests/integration/ganache/test_market_flow.py +++ b/tests/integration/ganache/test_market_flow.py @@ -8,6 +8,7 @@ import pytest from web3.main import Web3 +from ocean_lib.models.datatoken import TokenFeeInfo from tests.resources.ddo_helpers import get_registered_asset_with_access_service from tests.resources.helper_functions import get_another_consumer_ocean_instance @@ -52,9 +53,7 @@ def test_market_flow( ddo, consumer_wallet, service=service, - consume_market_order_fee_address=consumer_wallet.address, - consume_market_order_fee_token=datatoken.address, - consume_market_order_fee_amount=0, + consume_market_fees=TokenFeeInfo(token=datatoken.address), ) asset_folder = consumer_ocean.assets.download_asset( ddo, @@ -68,9 +67,10 @@ def test_market_flow( ddo, consumer_wallet, service=service, - consume_market_order_fee_address=another_consumer_wallet.address, - consume_market_order_fee_token=datatoken.address, - consume_market_order_fee_amount=0, + consume_market_fees=TokenFeeInfo( + address=another_consumer_wallet.address, + token=datatoken.address, + ), consumer_address=another_consumer_wallet.address, ) asset_folder = consumer_ocean.assets.download_asset( diff --git a/tests/integration/ganache/test_onchain.py b/tests/integration/ganache/test_onchain.py index b293ecf2e..e00c485f0 100644 --- a/tests/integration/ganache/test_onchain.py +++ b/tests/integration/ganache/test_onchain.py @@ -11,11 +11,10 @@ from ocean_lib.agreements.service_types import ServiceTypes from ocean_lib.data_provider.data_service_provider import DataServiceProvider -from ocean_lib.models.datatoken import Datatoken -from ocean_lib.ocean.ocean_assets import DatatokenArguments, OceanAssets +from ocean_lib.models.datatoken import Datatoken, DatatokenArguments +from ocean_lib.ocean.ocean_assets import OceanAssets from ocean_lib.ocean.util import get_address_of_type from ocean_lib.structures.file_objects import SmartContractCall -from ocean_lib.web3_internal.constants import ZERO_ADDRESS from tests.resources.ddo_helpers import get_first_service_by_type @@ -102,9 +101,6 @@ def test_consume_parametrized_onchain_data( consumer=consumer_wallet.address, service_index=ddo.get_index_of_service(service), provider_fees=provider_fees, - consume_market_order_fee_address=ZERO_ADDRESS, - consume_market_order_fee_token=ZERO_ADDRESS, - consume_market_order_fee_amount=0, transaction_parameters={"from": consumer_wallet}, ) diff --git a/tests/integration/remote/util.py b/tests/integration/remote/util.py index 491075f41..0310fed69 100644 --- a/tests/integration/remote/util.py +++ b/tests/integration/remote/util.py @@ -12,7 +12,7 @@ from brownie.network import accounts, chain, priority_fee from enforce_typing import enforce_types -from ocean_lib.models.arguments import DataNFTArguments +from ocean_lib.models.data_nft import DataNFTArguments ERRORS_TO_CATCH = (ContractNotFound, TransactionError, ValueError, VirtualMachineError) diff --git a/tests/resources/ddo_helpers.py b/tests/resources/ddo_helpers.py index a16214c8b..f65ecea3b 100644 --- a/tests/resources/ddo_helpers.py +++ b/tests/resources/ddo_helpers.py @@ -12,11 +12,8 @@ from ocean_lib.agreements.service_types import ServiceTypes from ocean_lib.assets.ddo import DDO from ocean_lib.data_provider.data_service_provider import DataServiceProvider -from ocean_lib.models.datatoken import Datatoken -from ocean_lib.models.factory_router import FactoryRouter -from ocean_lib.models.fixed_rate_exchange import FixedRateExchange +from ocean_lib.models.datatoken import DatatokenArguments from ocean_lib.ocean.ocean import Ocean -from ocean_lib.ocean.ocean_assets import DatatokenArguments from ocean_lib.services.service import Service from ocean_lib.structures.algorithm_metadata import AlgorithmMetadata from ocean_lib.structures.file_objects import FilesTypeFactory, UrlFile diff --git a/tests/resources/helper_functions.py b/tests/resources/helper_functions.py index a8a333aa4..745e3d62b 100644 --- a/tests/resources/helper_functions.py +++ b/tests/resources/helper_functions.py @@ -19,10 +19,9 @@ from web3 import Web3 from ocean_lib.example_config import get_config_dict -from ocean_lib.models.arguments import DataNFTArguments, DatatokenArguments -from ocean_lib.models.data_nft import DataNFT +from ocean_lib.models.data_nft import DataNFT, DataNFTArguments from ocean_lib.models.data_nft_factory import DataNFTFactoryContract -from ocean_lib.models.datatoken import Datatoken +from ocean_lib.models.datatoken import Datatoken, DatatokenArguments from ocean_lib.ocean.ocean import Ocean from ocean_lib.ocean.util import get_address_of_type, to_wei from ocean_lib.structures.file_objects import FilesTypeFactory @@ -180,8 +179,6 @@ def deploy_erc721_erc20( name="DT1", symbol="DT1Symbol", minter=datatoken_minter.address, - publish_market_order_fee_address=data_nft_publisher.address, - publish_market_order_fee_token=ZERO_ADDRESS, ), data_nft_publisher, )