Skip to content

Commit

Permalink
Merge pull request #218 from valory-xyz/feat/add_contract_functionality
Browse files Browse the repository at this point in the history
Migrate contract functionality
  • Loading branch information
Adamantios authored Jun 18, 2024
2 parents eeaaa77 + 9cec5ff commit 0d747da
Show file tree
Hide file tree
Showing 10 changed files with 528 additions and 22 deletions.
14 changes: 7 additions & 7 deletions packages/packages.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
"custom/w1kke/always_blue/0.1.0": "bafybeieshu32h3es2fslduuhr7nimuvh2vuibyeqdunzrcggaeohekg3jm",
"custom/valory/kelly_criterion_no_conf/0.1.0": "bafybeihnweebd6lxqtiat2mgspp5tpal4e2hntwdxvptkmbunpdxq2fple",
"contract/valory/market_maker/0.1.0": "bafybeiba25nt26ntjzkkpfyl2ngbjxrfd44ckg3znfhqm552725vb3gaka",
"contract/valory/realitio/0.1.0": "bafybeic5ie4oodetj4krdogydvbfxg4qggc3matpiflocah626tpevpreq",
"contract/valory/realitio/0.1.0": "bafybeignaxfk7fjlfa4lioflwsfru2z5xln5cyvyew3if5oas2sgm5wuii",
"contract/valory/realitio_proxy/0.1.0": "bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4",
"contract/valory/conditional_tokens/0.1.0": "bafybeigucumqbsk74nj4rpm4p2cpiky4dj6uws7nfmgpimuviaxcamwqnu",
"contract/valory/conditional_tokens/0.1.0": "bafybeibnzmqmeph4cj5vfh3s622mo2o5627vjjwc6bptrhj4dk65mzgvhe",
"contract/valory/agent_registry/0.1.0": "bafybeifsb2krg4qnr4nxdrhcdgpncfr5ra2nahebvn2f2yff7ebwe7ooae",
"contract/valory/service_staking_token/0.1.0": "bafybeigzpmgizwxiptscj6bieumby5sjs54w3ps6f3kdnlyxpiwwxy5iem",
"contract/valory/transfer_nft_condition/0.1.0": "bafybeihnict3irtvnyxtkwyg6wphe44wz3dogijiha45xrkcrh5ktq2lsi",
"contract/valory/relayer/0.1.0": "bafybeiaabvxim4blp5fxb6qjlzjivtvkme3fk24h5jte7w6vr6rsx72j6u",
"skill/valory/market_manager_abci/0.1.0": "bafybeicbvxvjkoksbknujaid5hx7krjlgm6barcjcwo33tdccanrcp674a",
"skill/valory/decision_maker_abci/0.1.0": "bafybeib2uenr2a5y2oalybrw2fs2nrr3lp7tw35bvkxkska6pq7l6qqy2q",
"skill/valory/trader_abci/0.1.0": "bafybeidpeu7toewtfjb4gyxieqklbev2i2pbyj57ket4qoyffdbypdlw7q",
"skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeihws5nfvhepagcqb43bxuqisqc2w45d57246rwu6ajedatxzkfbpa",
"skill/valory/decision_maker_abci/0.1.0": "bafybeibsnlnzufdach74o3zvgggbb3rfgrow47r3q6ey7wioil43ik6jaa",
"skill/valory/trader_abci/0.1.0": "bafybeihulcjfowlm3cpxwqo2tufada52xleleidy7zlccmhxyphqxj76um",
"skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeiavfiyvyafvvt6t6qx7okcitnmf26tjo2woc27dycpuuw4qsgd5zq",
"skill/valory/staking_abci/0.1.0": "bafybeigo7bicej5t2rbki37cmcwkzgwpcnopokn7ijhylmkihsbqw47xr4",
"skill/valory/check_stop_trading_abci/0.1.0": "bafybeickfeuqlpmryegnfvfu2duk2v4ycowwloohu3xxrafd5md6xl5swi",
"agent/valory/trader/0.1.0": "bafybeiggmqtq37rpd7dsa6zdf3k2akzvv4qdln7hbiunshhgbl42jycjt4",
"service/valory/trader/0.1.0": "bafybeifujozezu4nrul3w2v4qgjmywsiwygtdnocazk4f4vttj6swdl2wi"
"agent/valory/trader/0.1.0": "bafybeicsu6mq2wlgphwspjf345iuji3pqosedrog7fcd7dfnkxgnl5g5by",
"service/valory/trader/0.1.0": "bafybeigioak6bvdcpc7fyxybkqf7tx5hpthppnqfuphwoaudlh3hpryoqi"
},
"third_party": {
"protocol/open_aea/signing/1.0.0": "bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi",
Expand Down
10 changes: 5 additions & 5 deletions packages/valory/agents/trader/aea-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ contracts:
- valory/market_maker:0.1.0:bafybeiba25nt26ntjzkkpfyl2ngbjxrfd44ckg3znfhqm552725vb3gaka
- valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y
- valory/mech:0.1.0:bafybeidwpijhdwj5abewa44k3tzxuanxykzmgnnffeq7re2rxp7pqbd2ou
- valory/conditional_tokens:0.1.0:bafybeigucumqbsk74nj4rpm4p2cpiky4dj6uws7nfmgpimuviaxcamwqnu
- valory/realitio:0.1.0:bafybeic5ie4oodetj4krdogydvbfxg4qggc3matpiflocah626tpevpreq
- valory/conditional_tokens:0.1.0:bafybeibnzmqmeph4cj5vfh3s622mo2o5627vjjwc6bptrhj4dk65mzgvhe
- valory/realitio:0.1.0:bafybeignaxfk7fjlfa4lioflwsfru2z5xln5cyvyew3if5oas2sgm5wuii
- valory/realitio_proxy:0.1.0:bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4
- valory/agent_registry:0.1.0:bafybeifsb2krg4qnr4nxdrhcdgpncfr5ra2nahebvn2f2yff7ebwe7ooae
- valory/service_staking_token:0.1.0:bafybeigzpmgizwxiptscj6bieumby5sjs54w3ps6f3kdnlyxpiwwxy5iem
Expand All @@ -45,10 +45,10 @@ skills:
- valory/reset_pause_abci:0.1.0:bafybeiameewywqigpupy3u2iwnkfczeiiucue74x2l5lbge74rmw6bgaie
- valory/termination_abci:0.1.0:bafybeif2zim2de356eo3sipkmoev5emwadpqqzk3huwqarywh4tmqt3vzq
- valory/transaction_settlement_abci:0.1.0:bafybeic3tccdjypuge2lewtlgprwkbb53lhgsgn7oiwzyrcrrptrbeyote
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeihws5nfvhepagcqb43bxuqisqc2w45d57246rwu6ajedatxzkfbpa
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeiavfiyvyafvvt6t6qx7okcitnmf26tjo2woc27dycpuuw4qsgd5zq
- valory/market_manager_abci:0.1.0:bafybeicbvxvjkoksbknujaid5hx7krjlgm6barcjcwo33tdccanrcp674a
- valory/decision_maker_abci:0.1.0:bafybeib2uenr2a5y2oalybrw2fs2nrr3lp7tw35bvkxkska6pq7l6qqy2q
- valory/trader_abci:0.1.0:bafybeidpeu7toewtfjb4gyxieqklbev2i2pbyj57ket4qoyffdbypdlw7q
- valory/decision_maker_abci:0.1.0:bafybeibsnlnzufdach74o3zvgggbb3rfgrow47r3q6ey7wioil43ik6jaa
- valory/trader_abci:0.1.0:bafybeihulcjfowlm3cpxwqo2tufada52xleleidy7zlccmhxyphqxj76um
- valory/staking_abci:0.1.0:bafybeigo7bicej5t2rbki37cmcwkzgwpcnopokn7ijhylmkihsbqw47xr4
- valory/check_stop_trading_abci:0.1.0:bafybeickfeuqlpmryegnfvfu2duk2v4ycowwloohu3xxrafd5md6xl5swi
- valory/mech_interact_abci:0.1.0:bafybeih2cck5xu6yaibomwtm5zbcp6llghr3ighdnk56fzwu3ihu5xx35e
Expand Down
260 changes: 259 additions & 1 deletion packages/valory/contracts/conditional_tokens/contract.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
# Copyright 2023 Valory AG
# Copyright 2023-2024 Valory AG
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -28,9 +28,11 @@
from aea.contracts.base import Contract
from aea.crypto.base import LedgerApi
from hexbytes import HexBytes
from web3.types import BlockIdentifier


FIVE_MINUTES = 300.0
DEFAULT_OUTCOME_SLOT = 2

class ConditionalTokensContract(Contract):
"""The ConditionalTokens smart contract."""
Expand Down Expand Up @@ -160,3 +162,259 @@ def build_redeem_positions_tx(
],
)
return dict(data=data)

@classmethod
def get_raw_transaction(
cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any
) -> JSONLike:
"""
Handler method for the 'GET_RAW_TRANSACTION' requests.
Implement this method in the sub class if you want
to handle the contract requests manually.
:param ledger_api: the ledger apis.
:param contract_address: the contract address.
:param kwargs: the keyword arguments.
:return: the tx # noqa: DAR202
"""
raise NotImplementedError

@classmethod
def get_raw_message(
cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any
) -> bytes:
"""
Handler method for the 'GET_RAW_MESSAGE' requests.
Implement this method in the sub class if you want
to handle the contract requests manually.
:param ledger_api: the ledger apis.
:param contract_address: the contract address.
:param kwargs: the keyword arguments.
:return: the tx # noqa: DAR202
"""
raise NotImplementedError

@classmethod
def get_state(
cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any
) -> JSONLike:
"""
Handler method for the 'GET_STATE' requests.
Implement this method in the sub class if you want
to handle the contract requests manually.
:param ledger_api: the ledger apis.
:param contract_address: the contract address.
:param kwargs: the keyword arguments.
:return: the tx # noqa: DAR202
"""
raise NotImplementedError

@classmethod
def get_prepare_condition_tx(
cls,
ledger_api: LedgerApi,
contract_address: str,
question_id: str,
oracle_contract: str,
outcome_slot_count: int = DEFAULT_OUTCOME_SLOT,
) -> JSONLike:
"""Tx for preparing condition for marker maker."""
kwargs = {
"oracle": ledger_api.api.to_checksum_address(oracle_contract),
"questionId": question_id,
"outcomeSlotCount": outcome_slot_count,
}
return ledger_api.build_transaction(
contract_instance=cls.get_instance(
ledger_api=ledger_api, contract_address=contract_address
),
method_name="prepareCondition",
method_args=kwargs,
)

@classmethod
def get_prepare_condition_tx_data(
cls,
ledger_api: LedgerApi,
contract_address: str,
question_id: str,
oracle_contract: str,
outcome_slot_count: int = DEFAULT_OUTCOME_SLOT,
) -> JSONLike:
"""Tx for preparing condition for marker maker."""
kwargs = {
"oracle": ledger_api.api.to_checksum_address(oracle_contract),
"questionId": question_id,
"outcomeSlotCount": outcome_slot_count,
}
contract_instance = cls.get_instance(
ledger_api=ledger_api, contract_address=contract_address
)
data = contract_instance.encodeABI(fn_name="prepareCondition", kwargs=kwargs)
return {"data": bytes.fromhex(data[2:])}

@classmethod
def calculate_condition_id(
cls,
ledger_api: LedgerApi,
contract_address: str,
oracle_contract: str,
question_id: str,
outcome_slot_count: int,
) -> str:
"""Calculate condition ID."""
return {
"condition_id": ledger_api.api.solidity_keccak(
["address", "bytes32", "uint256"],
[
ledger_api.api.to_checksum_address(oracle_contract),
bytes.fromhex(question_id[2:]),
outcome_slot_count,
],
).hex()
}

@classmethod
def get_condition_id(
cls,
ledger_api: LedgerApi,
contract_address: str,
tx_digest: str, # retrieved from `prepareCondition` tx
) -> JSONLike:
"""Tx for preparing condition for marker maker."""
contract_instance = cls.get_instance(
ledger_api=ledger_api, contract_address=contract_address
)
tx_receipt = ledger_api.api.eth.getTransactionReceipt(tx_digest)
(log,) = contract_instance.events.ConditionPreparation().process_receipt(
tx_receipt
)
return "0x" + log["args"]["conditionId"].hex()

@classmethod
def get_condition_preparation_events(
cls,
ledger_api: LedgerApi,
contract_address: str,
condition_ids: List[bytes],
from_block: BlockIdentifier = "earliest",
to_block: BlockIdentifier = "latest",
) -> JSONLike:
"""Get condition preparation events."""
contract_instance = cls.get_instance(
ledger_api=ledger_api, contract_address=contract_address
)
entries = (
contract_instance.events.ConditionPreparation()
.create_filter(
fromBlock=from_block,
toBlock=to_block,
argument_filters={
"conditionId": condition_ids,
},
)
.get_all_entries()
)
events = list(
dict(
tx_hash=entry.transactionHash.hex(),
block_number=entry.blockNumber,
condition_id=entry["args"]["conditionId"],
oracle=entry["args"]["oracle"],
question_id=entry["args"]["questionId"],
outcome_slot_count=entry["args"]["outcomeSlotCount"],
)
for entry in entries
)
return dict(data=events)

@staticmethod
def get_partitions(count: int) -> List[int]:
"""Calculate and return partitions."""
return list(map(lambda x: 1 << x, range(count)))

@classmethod
def get_user_holdings(
cls,
ledger_api: LedgerApi,
contract_address: str,
outcome_slot_count: int,
condition_id: str,
creator: str,
collateral_token: str,
market: str,
parent_collection_id: str,
) -> JSONLike:
"""Returns user holding."""
holdings = []
shares = []
instance = cls.get_instance(
ledger_api=ledger_api,
contract_address=contract_address,
)
for i in cls.get_partitions(count=outcome_slot_count):
collection_id = int.from_bytes(
instance.functions.getCollectionId(
parent_collection_id, condition_id, i
).call(),
"big",
)
position_id = int.from_bytes(
ledger_api.api.solidity_keccak(
["address", "uint256"],
[
ledger_api.api.to_checksum_address(collateral_token),
collection_id,
],
),
"big",
)
holdings.append(
instance.functions.balanceOf(
ledger_api.api.to_checksum_address(market),
position_id,
).call()
)
shares.append(
instance.functions.balanceOf(
ledger_api.api.to_checksum_address(creator), position_id
).call()
)
return dict(
holdings=holdings,
shares=shares,
)

@classmethod
def build_merge_positions_tx(
cls,
ledger_api: LedgerApi,
contract_address: str,
collateral_token: str,
parent_collection_id: bytes,
condition_id: bytes,
outcome_slot_count: int,
amount: int,
**kwargs: Any
) -> JSONLike:
"""Build mergePositions tx."""
instance = cls.get_instance(ledger_api, contract_address)
partition = cls.get_partitions(count=outcome_slot_count)
data = instance.encodeABI(
fn_name="mergePositions",
args=[
ledger_api.api.to_checksum_address(collateral_token),
parent_collection_id,
condition_id,
partition,
amount,
],
)
return dict(
data=data,
)
2 changes: 1 addition & 1 deletion packages/valory/contracts/conditional_tokens/contract.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0'
fingerprint:
__init__.py: bafybeidhdxio3oq5gqdnxmngumvt3fcd6zyiyrpk5f2k4dwhflbg4e5iky
build/ConditionalTokens.json: bafybeia2ahis7zx2yhhf23kpkcxu56hto6fwg6ptjg5ld46lp4dgz7cz3e
contract.py: bafybeiesym65thjsazplbgjhqleci6sdriytubqljpc3smtjitrpthhaam
contract.py: bafybeigdhjd2qvkmawsxd4afufr6uy3hufxwi3chcne5gba5i6whitn2r4
fingerprint_ignore_patterns: []
class_name: ConditionalTokensContract
contract_interface_paths:
Expand Down
Loading

0 comments on commit 0d747da

Please sign in to comment.