From b11c685db1b279e3e0e79757d87fd2973b721571 Mon Sep 17 00:00:00 2001 From: Adamantios Date: Mon, 31 Jul 2023 14:30:16 +0300 Subject: [PATCH 1/6] refactor: get the balance for both the token and the wallet --- packages/valory/contracts/erc20/contract.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/valory/contracts/erc20/contract.py b/packages/valory/contracts/erc20/contract.py index 137fb3b4e..aa4202535 100644 --- a/packages/valory/contracts/erc20/contract.py +++ b/packages/valory/contracts/erc20/contract.py @@ -45,8 +45,9 @@ def check_balance( """Check the balance of the given account.""" contract_instance = cls.get_instance(ledger_api, contract_address) balance_of = getattr(contract_instance.functions, "balanceOf") - balance = balance_of(account).call() - return dict(balance=balance) + token_balance = balance_of(account).call() + wallet_balance = ledger_api.api.eth.get_balance(account) + return dict(token=token_balance, wallet=wallet_balance) @classmethod def build_approval_tx( From 7a08431fc8e989a3a208ed5ec7e102a3fdc6c2d3 Mon Sep 17 00:00:00 2001 From: Adamantios Date: Mon, 31 Jul 2023 14:31:02 +0300 Subject: [PATCH 2/6] feat: implement method to build a `deposit` transaction --- packages/valory/contracts/erc20/contract.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/valory/contracts/erc20/contract.py b/packages/valory/contracts/erc20/contract.py index aa4202535..3183c4d5d 100644 --- a/packages/valory/contracts/erc20/contract.py +++ b/packages/valory/contracts/erc20/contract.py @@ -49,6 +49,17 @@ def check_balance( wallet_balance = ledger_api.api.eth.get_balance(account) return dict(token=token_balance, wallet=wallet_balance) + @classmethod + def build_deposit_tx( + cls, + ledger_api: EthereumApi, + contract_address: str, + ) -> Dict[str, bytes]: + """Build a deposit transaction.""" + contract_instance = cls.get_instance(ledger_api, contract_address) + data = contract_instance.encodeABI("deposit") + return {"data": bytes.fromhex(data[2:])} + @classmethod def build_approval_tx( cls, From a2e023c92d3db8b0392b6d124194b02e7c1a6160 Mon Sep 17 00:00:00 2001 From: Adamantios Date: Mon, 31 Jul 2023 15:13:55 +0300 Subject: [PATCH 3/6] feat: get both token and wallet balances --- .../decision_maker_abci/behaviours/bet_placement.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/valory/skills/decision_maker_abci/behaviours/bet_placement.py b/packages/valory/skills/decision_maker_abci/behaviours/bet_placement.py index f62a10e58..803d5bdf6 100644 --- a/packages/valory/skills/decision_maker_abci/behaviours/bet_placement.py +++ b/packages/valory/skills/decision_maker_abci/behaviours/bet_placement.py @@ -62,7 +62,8 @@ class BetPlacementBehaviour(DecisionMakerBaseBehaviour): def __init__(self, **kwargs: Any) -> None: """Initialize the bet placement behaviour.""" super().__init__(**kwargs) - self.balance = 0 + self.token_balance = 0 + self.wallet_balance = 0 self.buy_amount = 0 self.multisend_batches: List[MultisendBatch] = [] self.multisend_data = b"" @@ -113,14 +114,16 @@ def _check_balance(self) -> WaitableConditionType: ) return False - balance = response_msg.raw_transaction.body.get("balance", None) - if balance is None: + token = response_msg.raw_transaction.body.get("token", None) + wallet = response_msg.raw_transaction.body.get("wallet", None) + if token is None or wallet is None: self.context.logger.error( f"Something went wrong while trying to get the balance of the safe: {response_msg}" ) return False - self.balance = int(balance) + self.token_balance = int(token) + self.wallet_balance = int(wallet) return True def _build_approval_tx(self) -> WaitableConditionType: From 69c5e2e767d58511ec16fa2bf29ff2c07bdba1ea Mon Sep 17 00:00:00 2001 From: Adamantios Date: Mon, 31 Jul 2023 15:20:16 +0300 Subject: [PATCH 4/6] feat: check and exchange xDAI to wxDAI if necessary --- .../behaviours/bet_placement.py | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/packages/valory/skills/decision_maker_abci/behaviours/bet_placement.py b/packages/valory/skills/decision_maker_abci/behaviours/bet_placement.py index 803d5bdf6..bd44bc6f5 100644 --- a/packages/valory/skills/decision_maker_abci/behaviours/bet_placement.py +++ b/packages/valory/skills/decision_maker_abci/behaviours/bet_placement.py @@ -52,6 +52,7 @@ # hardcoded to 0 because we don't need to send any ETH when betting _ETHER_VALUE = 0 +WXDAI = "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d" class BetPlacementBehaviour(DecisionMakerBaseBehaviour): @@ -85,9 +86,9 @@ def investment_amount(self) -> int: return self.params.get_bet_amount(self.synchronized_data.confidence) @property - def sufficient_balance(self) -> int: - """Get whether the balance is sufficient for the investment amount of the bet.""" - return self.balance >= self.investment_amount + def w_xdai_deficit(self) -> int: + """Get the amount of missing wxDAI fo placing the bet.""" + return self.investment_amount - self.token_balance @property def outcome_index(self) -> int: @@ -126,6 +127,32 @@ def _check_balance(self) -> WaitableConditionType: self.wallet_balance = int(wallet) return True + def _build_exchange_tx(self) -> WaitableConditionType: + """Exchange xDAI to wxDAI.""" + response_msg = yield from self.get_contract_api_response( + performative=ContractApiMessage.Performative.GET_STATE, # type: ignore + contract_address=WXDAI, + contract_id=str(ERC20.contract_id), + contract_callable="build_deposit_tx", + ) + + if response_msg.performative != ContractApiMessage.Performative.STATE: + self.context.logger.info(f"Could not build deposit tx: {response_msg}") + return False + + approval_data = response_msg.state.body.get("data") + if approval_data is None: + self.context.logger.info(f"Could not build deposit tx: {response_msg}") + return False + + batch = MultisendBatch( + to=self.collateral_token, + data=HexBytes(approval_data), + value=self.w_xdai_deficit, + ) + self.multisend_batches.append(batch) + return True + def _build_approval_tx(self) -> WaitableConditionType: """Build an ERC20 approve transaction.""" response_msg = yield from self.get_contract_api_response( @@ -309,9 +336,19 @@ def async_act(self) -> Generator: with self.context.benchmark_tool.measure(self.behaviour_id).local(): yield from self.wait_for_condition_with_sleep(self._check_balance) tx_submitter = betting_tx_hex = None - if self.sufficient_balance: + + can_exchange = ( + self.collateral_token == WXDAI + # no need to take fees into consideration because it is the safe's balance and the agents pay the fees + and self.wallet_balance >= self.w_xdai_deficit + ) + if self.token_balance < self.investment_amount and can_exchange: + yield from self.wait_for_condition_with_sleep(self._build_exchange_tx) + + if self.token_balance >= self.investment_amount or can_exchange: tx_submitter = self.matching_round.auto_round_id() betting_tx_hex = yield from self._prepare_safe_tx() + agent = self.context.agent_address payload = MultisigTxPayload(agent, tx_submitter, betting_tx_hex) From 643e55bed1c2cfd04e18e099622069532a624cde Mon Sep 17 00:00:00 2001 From: Adamantios Date: Mon, 31 Jul 2023 15:24:19 +0300 Subject: [PATCH 5/6] fix: the payable value's calculation --- .../decision_maker_abci/behaviours/bet_placement.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/valory/skills/decision_maker_abci/behaviours/bet_placement.py b/packages/valory/skills/decision_maker_abci/behaviours/bet_placement.py index bd44bc6f5..8ef1f88f7 100644 --- a/packages/valory/skills/decision_maker_abci/behaviours/bet_placement.py +++ b/packages/valory/skills/decision_maker_abci/behaviours/bet_placement.py @@ -50,8 +50,6 @@ from packages.valory.skills.transaction_settlement_abci.rounds import TX_HASH_LENGTH -# hardcoded to 0 because we don't need to send any ETH when betting -_ETHER_VALUE = 0 WXDAI = "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d" @@ -100,6 +98,11 @@ def multi_send_txs(self) -> List[dict]: """Get the multisend transactions as a list of dictionaries.""" return [dataclasses.asdict(batch) for batch in self.multisend_batches] + @property + def txs_value(self) -> int: + """Get the total value of the transactions.""" + return sum(batch.value for batch in self.multisend_batches) + def _check_balance(self) -> WaitableConditionType: """Check the safe's balance.""" response_msg = yield from self.get_contract_api_response( @@ -277,7 +280,7 @@ def _build_safe_tx_hash(self) -> WaitableConditionType: contract_id=str(GnosisSafeContract.contract_id), contract_callable="get_raw_safe_transaction_hash", to_address=self.params.multisend_address, - value=_ETHER_VALUE, + value=self.txs_value, data=self.multisend_data, safe_tx_gas=SAFE_GAS, operation=SafeOperation.DELEGATE_CALL.value, @@ -324,7 +327,7 @@ def _prepare_safe_tx(self) -> Generator[None, None, str]: return hash_payload_to_hex( self.safe_tx_hash, - _ETHER_VALUE, + self.txs_value, SAFE_GAS, self.params.multisend_address, self.multisend_data, From bdc8fa773dd1686c08c1099526573107874d4600 Mon Sep 17 00:00:00 2001 From: Adamantios Date: Mon, 31 Jul 2023 15:36:50 +0300 Subject: [PATCH 6/6] chore: run generators --- packages/packages.json | 12 ++++++------ packages/valory/agents/trader/aea-config.yaml | 8 ++++---- packages/valory/contracts/erc20/contract.yaml | 2 +- packages/valory/services/trader/service.yaml | 2 +- .../valory/skills/decision_maker_abci/skill.yaml | 4 ++-- packages/valory/skills/trader_abci/skill.yaml | 4 ++-- .../skills/tx_settlement_multiplexer_abci/skill.yaml | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/packages.json b/packages/packages.json index df9192384..621139c39 100644 --- a/packages/packages.json +++ b/packages/packages.json @@ -1,13 +1,13 @@ { "dev": { "skill/valory/market_manager_abci/0.1.0": "bafybeids5us4cnfu2zboxfjjkyihxk2i4qmctwzbnrsk2uizzjl2gbjj4m", - "skill/valory/decision_maker_abci/0.1.0": "bafybeigo76utrglsm234zwlnktj2qoi66oyvnoh2ams2ltheccatzn6ow4", - "skill/valory/trader_abci/0.1.0": "bafybeiewtrmwvun7gg7qteyuq5ykdjiwwnwiirtbjc4fynkok5a5yjfsqi", + "skill/valory/decision_maker_abci/0.1.0": "bafybeidwexscouadfvf7qqe37bknjwoj7w54aefwomu54ht2myvgjraes4", + "skill/valory/trader_abci/0.1.0": "bafybeigalvd3cp6sf4nkrl2odialcu2zqfdojjrvm6lnqucgxosiraq3sy", "contract/valory/market_maker/0.1.0": "bafybeig3b2wfngntdypnixi2gphuqz3o6w7zba2rq6n6kepwdmth2mx3ni", - "agent/valory/trader/0.1.0": "bafybeid2qo53p3c5rdq3at45elzm55odirwabipxspqrmf3ny64r2xhaue", - "service/valory/trader/0.1.0": "bafybeifhhrmls6ve2bgr3o6h62tivm45hhhy2blwm64aocifuyotiqrrba", - "contract/valory/erc20/0.1.0": "bafybeict775c7iytqbhiv2tq6pdwtpyzr3p2wls3duvmrl3acee7pietwy", - "skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeieby37xdqlqotwl3cdfvk4i4ng2uhaxmmhuopjylrqufbfkj54iem", + "agent/valory/trader/0.1.0": "bafybeihfpkd5kxtix6wx5lmyycmza6zdi6ltotquspuhi65zbyhibir5me", + "service/valory/trader/0.1.0": "bafybeievpm2om4fsh5duizqabun57mhntd3t5r6te2aj2p3u5bfgmeojl4", + "contract/valory/erc20/0.1.0": "bafybeid4dnlzxpvb7sbgo2bnnffzwk5scelytshworzbfyxce6ibdyk67i", + "skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeig6avhzw2x5tacq7jyxgnpoz6k6s62clgsexlp55y6qdwietcfgqi", "contract/valory/mech/0.1.0": "bafybeib3syh35usqjtqapqjjvobnkcxllkpjbxcb67g3vp3f566qsbhqgq" }, "third_party": { diff --git a/packages/valory/agents/trader/aea-config.yaml b/packages/valory/agents/trader/aea-config.yaml index c6efb057d..9d3cac9e5 100644 --- a/packages/valory/agents/trader/aea-config.yaml +++ b/packages/valory/agents/trader/aea-config.yaml @@ -19,7 +19,7 @@ contracts: - valory/gnosis_safe_proxy_factory:0.1.0:bafybeigbtbgzqlt4tufgymtjsyxiqvivxmtc4csx43hmo5nexmdfcxm6bi - valory/service_registry:0.1.0:bafybeiae7nr5fqn6ckt3ehol27qfd4o5ljzx6kk5k32lgtrvj3mtb62ufm - valory/market_maker:0.1.0:bafybeig3b2wfngntdypnixi2gphuqz3o6w7zba2rq6n6kepwdmth2mx3ni -- valory/erc20:0.1.0:bafybeict775c7iytqbhiv2tq6pdwtpyzr3p2wls3duvmrl3acee7pietwy +- valory/erc20:0.1.0:bafybeid4dnlzxpvb7sbgo2bnnffzwk5scelytshworzbfyxce6ibdyk67i - valory/multisend:0.1.0:bafybeict2k3vf3c4fvzosaq5kku2ivtzsskbomrujmmoicut7eg52onnje - valory/mech:0.1.0:bafybeib3syh35usqjtqapqjjvobnkcxllkpjbxcb67g3vp3f566qsbhqgq protocols: @@ -38,10 +38,10 @@ skills: - valory/reset_pause_abci:0.1.0:bafybeialcwck7fahrr23jckv5qjwg3cdq4ai2ihyjsofnbj44jzyl4cjmm - valory/termination_abci:0.1.0:bafybeifqsogqiar4yook5bu3j6z66dbdcizey7dr3e5oxeocdjijvfbaja - valory/transaction_settlement_abci:0.1.0:bafybeiacwr7p4nhhufoey7uz2jqkegrlykdrmc7mm3rzkvh2mslu66gyle -- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeieby37xdqlqotwl3cdfvk4i4ng2uhaxmmhuopjylrqufbfkj54iem +- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeig6avhzw2x5tacq7jyxgnpoz6k6s62clgsexlp55y6qdwietcfgqi - valory/market_manager_abci:0.1.0:bafybeids5us4cnfu2zboxfjjkyihxk2i4qmctwzbnrsk2uizzjl2gbjj4m -- valory/decision_maker_abci:0.1.0:bafybeigo76utrglsm234zwlnktj2qoi66oyvnoh2ams2ltheccatzn6ow4 -- valory/trader_abci:0.1.0:bafybeiewtrmwvun7gg7qteyuq5ykdjiwwnwiirtbjc4fynkok5a5yjfsqi +- valory/decision_maker_abci:0.1.0:bafybeidwexscouadfvf7qqe37bknjwoj7w54aefwomu54ht2myvgjraes4 +- valory/trader_abci:0.1.0:bafybeigalvd3cp6sf4nkrl2odialcu2zqfdojjrvm6lnqucgxosiraq3sy default_ledger: ethereum required_ledgers: - ethereum diff --git a/packages/valory/contracts/erc20/contract.yaml b/packages/valory/contracts/erc20/contract.yaml index 8ae187eb5..152e0a65b 100644 --- a/packages/valory/contracts/erc20/contract.yaml +++ b/packages/valory/contracts/erc20/contract.yaml @@ -9,7 +9,7 @@ fingerprint: README.md: bafybeifmfma6rglvpa22odtozyosnp5mwljum64utxip2wgmezuhnjjjyi __init__.py: bafybeia2k2vmq7lmd3uchmm6jmzj7ebqkogk5aolpw4nwsawnkgqfobltm build/ERC20.json: bafybeiemn5b5nszuss7xj6lmvmjuendltp6wz7ubihdvd7c6wqw4bohbpa - contract.py: bafybeigybnez6haka42c6hgh6odelf745vhlxtxd5hoe67spoqyfjzmtkq + contract.py: bafybeictdnj5fazrs2hd4uznmnesxulxofd3zsa56idurgs35yzzoe6znm fingerprint_ignore_patterns: [] contracts: [] class_name: ERC20 diff --git a/packages/valory/services/trader/service.yaml b/packages/valory/services/trader/service.yaml index 0e01391a6..a10edec53 100644 --- a/packages/valory/services/trader/service.yaml +++ b/packages/valory/services/trader/service.yaml @@ -7,7 +7,7 @@ license: Apache-2.0 fingerprint: README.md: bafybeigtuothskwyvrhfosps2bu6suauycolj67dpuxqvnicdrdu7yhtvq fingerprint_ignore_patterns: [] -agent: valory/trader:0.1.0:bafybeid2qo53p3c5rdq3at45elzm55odirwabipxspqrmf3ny64r2xhaue +agent: valory/trader:0.1.0:bafybeihfpkd5kxtix6wx5lmyycmza6zdi6ltotquspuhi65zbyhibir5me number_of_agents: 4 deployment: {} --- diff --git a/packages/valory/skills/decision_maker_abci/skill.yaml b/packages/valory/skills/decision_maker_abci/skill.yaml index 10a329af9..31e2336fb 100644 --- a/packages/valory/skills/decision_maker_abci/skill.yaml +++ b/packages/valory/skills/decision_maker_abci/skill.yaml @@ -10,7 +10,7 @@ fingerprint: __init__.py: bafybeih563ujnigeci2ldzh7hakbau6a222vsed7leg3b7lq32vcn3nm4a behaviours/__init__.py: bafybeih6ddz2ocvm6x6ytvlbcz6oi4snb5ee5xh5h65nq4w2qf7fd7zfky behaviours/base.py: bafybeig2zoyowdeqg44kyxdc5tzdiczzpkzpbchq6f2nwjqertfvmi6xvy - behaviours/bet_placement.py: bafybeicqccffm7cuex5xofzu5cn2ink6s4kxjvvf45vvjyllgv55nwkmna + behaviours/bet_placement.py: bafybeigius6g2k2foyttxihbna2xpffeziige6273udsvam24bfcgcspfa behaviours/blacklisting.py: bafybeicvespraci44y2dtddy4wi7cdhjuyk6crjs7ztnssm2rcrovha3hm behaviours/decision_receive.py: bafybeigjct7st66x7n3go5vdp62wtdxgmgw233hyyvd3a63ly4x3ptdqbq behaviours/decision_request.py: bafybeidsvohdt2fxonh5qmctftjj5wfaa5z3ommr2yie6e7bhcml6xueuu @@ -35,7 +35,7 @@ connections: [] contracts: - valory/gnosis_safe:0.1.0:bafybeic3ajabs7sl6qgkzy452szlsdeitj746kdzfd7k4m4ixtxw4g33qi - valory/market_maker:0.1.0:bafybeig3b2wfngntdypnixi2gphuqz3o6w7zba2rq6n6kepwdmth2mx3ni -- valory/erc20:0.1.0:bafybeict775c7iytqbhiv2tq6pdwtpyzr3p2wls3duvmrl3acee7pietwy +- valory/erc20:0.1.0:bafybeid4dnlzxpvb7sbgo2bnnffzwk5scelytshworzbfyxce6ibdyk67i - valory/multisend:0.1.0:bafybeict2k3vf3c4fvzosaq5kku2ivtzsskbomrujmmoicut7eg52onnje - valory/mech:0.1.0:bafybeib3syh35usqjtqapqjjvobnkcxllkpjbxcb67g3vp3f566qsbhqgq protocols: diff --git a/packages/valory/skills/trader_abci/skill.yaml b/packages/valory/skills/trader_abci/skill.yaml index 7b3d2cf9f..a195a821e 100644 --- a/packages/valory/skills/trader_abci/skill.yaml +++ b/packages/valory/skills/trader_abci/skill.yaml @@ -25,8 +25,8 @@ skills: - valory/transaction_settlement_abci:0.1.0:bafybeiacwr7p4nhhufoey7uz2jqkegrlykdrmc7mm3rzkvh2mslu66gyle - valory/termination_abci:0.1.0:bafybeifqsogqiar4yook5bu3j6z66dbdcizey7dr3e5oxeocdjijvfbaja - valory/market_manager_abci:0.1.0:bafybeids5us4cnfu2zboxfjjkyihxk2i4qmctwzbnrsk2uizzjl2gbjj4m -- valory/decision_maker_abci:0.1.0:bafybeigo76utrglsm234zwlnktj2qoi66oyvnoh2ams2ltheccatzn6ow4 -- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeieby37xdqlqotwl3cdfvk4i4ng2uhaxmmhuopjylrqufbfkj54iem +- valory/decision_maker_abci:0.1.0:bafybeidwexscouadfvf7qqe37bknjwoj7w54aefwomu54ht2myvgjraes4 +- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeig6avhzw2x5tacq7jyxgnpoz6k6s62clgsexlp55y6qdwietcfgqi behaviours: main: args: {} diff --git a/packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml b/packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml index a56db4fa0..d2215d0ec 100644 --- a/packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml +++ b/packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml @@ -20,7 +20,7 @@ contracts: [] protocols: [] skills: - valory/abstract_round_abci:0.1.0:bafybeiaseziuvbzh3trjggl5hx2tv3fduqrpiwiyksudaf6nvuxmwrg74i -- valory/decision_maker_abci:0.1.0:bafybeigo76utrglsm234zwlnktj2qoi66oyvnoh2ams2ltheccatzn6ow4 +- valory/decision_maker_abci:0.1.0:bafybeidwexscouadfvf7qqe37bknjwoj7w54aefwomu54ht2myvgjraes4 behaviours: main: args: {}