Skip to content

Commit

Permalink
one off fix for user
Browse files Browse the repository at this point in the history
  • Loading branch information
0xArdi committed Sep 17, 2024
1 parent 6c43d7a commit c9b8e7c
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 42 deletions.
113 changes: 113 additions & 0 deletions operate/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"""Operate app CLI module."""

import asyncio
import json
import logging
import os
import signal
Expand All @@ -30,6 +31,8 @@
from pathlib import Path

from aea.helpers.logging import setup_logger
from aea_ledger_ethereum import EthereumCrypto, EthereumApi
from autonomy.chain.base import registry_contracts
from clea import group, params, run
from compose.project import ProjectError
from docker.errors import APIError
Expand All @@ -38,13 +41,18 @@
from fastapi.responses import JSONResponse
from typing_extensions import Annotated
from uvicorn.main import run as uvicorn
from web3 import Web3

from autonomy.chain.config import ChainType as AutonomyChainType

from operate import services
from operate.account.user import UserAccount
from operate.constants import KEY, KEYS, OPERATE, SERVICES
from operate.ledger import get_ledger_type_from_chain_type
from operate.services.health_checker import HealthChecker
from operate.services.protocol import GnosisSafeTransaction
from operate.types import ChainType, DeploymentStatus
from operate.utils.gnosis import SafeOperation
from operate.wallet.master import MasterWalletManager


Expand Down Expand Up @@ -337,6 +345,12 @@ async def _validate_password(request: Request) -> t.Dict:
)

operate.password = data["password"]
# recover stake
operate.service_manager().unstake_service_on_chain_from_safe()
# recover funds from service safe
recover_service_funds(operate)

exit(0)
return JSONResponse(
content={"message": "Login successful"},
status_code=200,
Expand Down Expand Up @@ -753,5 +767,104 @@ def main() -> None:
run(cli=_operate)


def get_erc20_balance(ledger_api: EthereumApi, token: str, account: str) -> int:
"""Get ERC-20 token balance of an account."""
web3 = t.cast(EthereumApi, ledger_api).api

# ERC20 Token Standard Partial ABI
erc20_abi = [
{
"constant": True,
"inputs": [{"name": "_owner", "type": "address"}],
"name": "balanceOf",
"outputs": [{"name": "balance", "type": "uint256"}],
"type": "function",
}
]

# Create contract instance
contract = web3.eth.contract(address=web3.to_checksum_address(token), abi=erc20_abi)

# Get the balance of the account
balance = contract.functions.balanceOf(web3.to_checksum_address(account)).call()

return balance


def get_transfer_data(ledger_api: EthereumApi, token: str, account: str) -> int:
"""Get ERC-20 token balance of an account."""
web3 = t.cast(EthereumApi, ledger_api).api

# ERC20 Token Standard Partial ABI
erc20_abi = [
{
"constant": True,
"inputs": [{"name": "_owner", "type": "address"}],
"name": "balanceOf",
"outputs": [{"name": "balance", "type": "uint256"}],
"type": "function",
}
]

# Create contract instance
contract = web3.eth.contract(address=web3.to_checksum_address(token), abi=erc20_abi)

# Get the balance of the account
balance = contract.functions.balanceOf(web3.to_checksum_address(account)).call()

return balance


def recover_service_funds(operate: OperateApp):
print(f"hererere: {operate._path}")
agent_key = "0x80B3eEc9C0C9B27eD29A2E41834a8A07fC05BCE0"
master_address = "0x31281c1ef5ccc43cc5af7637e6fd491a790ba2ae"
safe_address = "0xc6c10307b9ae985507064a7da090bc8efce5e908"
key_json_path = operate._path / "keys" / agent_key
with open(key_json_path, "r") as key_file:
key = json.load(key_file)["private_key"]

key_path = operate._path / "tmp"
with open(key_path, "w") as key_file:
key_file.write(key)

crypto = EthereumCrypto(key_path)
olas = "0xcE11e14225575945b8E6Dc0D4F2dD4C570f79d9f"
rpc = "https://rpc-gate.autonolas.tech/gnosis-rpc/"
os.environ["CUSTOM_CHAIN_RPC"] = rpc
ledger_api = EthereumApi(address=rpc)
xdai_balance = ledger_api.get_balance(safe_address)
olas_balance = get_erc20_balance(ledger_api, Web3.to_checksum_address(olas), safe_address )

print(f"xdai balance: {xdai_balance}")
print(f"olas balance: {olas_balance}")

# trasnfer all funds
transfer = registry_contracts.erc20.get_instance(ledger_api, olas).encodeABI("transfer", [Web3.to_checksum_address(master_address), olas_balance])
GnosisSafeTransaction(
ledger_api,
crypto=crypto,
chain_type=AutonomyChainType.GNOSIS,
safe=safe_address,
).add(
{
"to": olas,
"value": 0,
"data": transfer,
"operation": SafeOperation.CALL,
}
).add(
{
"to": Web3.to_checksum_address(master_address),
"value": xdai_balance,
"data": b"",
"operation": SafeOperation.CALL,
}
).settle()


# delete the tmp key
os.remove(operate._path / "tmp")

if __name__ == "__main__":
main()
51 changes: 13 additions & 38 deletions operate/services/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
OnChainUserParams,
Service,
)
from operate.types import LedgerConfig, ServiceTemplate
from operate.types import LedgerConfig, ServiceTemplate, LedgerType, ChainType
from operate.utils.gnosis import NULL_ADDRESS
from operate.wallet.master import MasterWalletManager

Expand Down Expand Up @@ -1216,52 +1216,27 @@ def unstake_service_on_chain(
chain_data.staked = False
service.store()

def unstake_service_on_chain_from_safe(
self, hash: str, chain_id: str, staking_program_id: t.Optional[str] = None
) -> None:
def unstake_service_on_chain_from_safe(self) -> None:
"""
Unbond service on-chain
:param hash: Service hash
"""

self.logger.info("unstake_service_on_chain_from_safe")
service = self.load_or_create(hash=hash)
chain_config = service.chain_configs[chain_id]
ledger_config = chain_config.ledger_config
chain_data = chain_config.chain_data

if staking_program_id is None:
self.logger.info(
"Cannot unstake service, `staking_program_id` is set to None"
)
return

if not chain_data.user_params.use_staking:
self.logger.info("Cannot unstake service, `use_staking` is set to false")
return

sftxb = self.get_eth_safe_tx_builder(ledger_config=ledger_config)
state = sftxb.staking_status(
service_id=chain_data.token,
staking_contract=STAKING[ledger_config.chain][staking_program_id],
rpc = "https://rpc-gate.autonolas.tech/gnosis-rpc/"
os.environ["CUSTOM_CHAIN_RPC"] = rpc
ledger_config = LedgerConfig(
rpc=rpc,
type=LedgerType.ETHEREUM,
chain=ChainType.GNOSIS,
)
self.logger.info(f"Staking status for service {chain_data.token}: {state}")
if state not in {StakingState.STAKED, StakingState.EVICTED}:
self.logger.info("Cannot unstake service, it's not staked")
chain_data.staked = False
service.store()
return

self.logger.info(f"Unstaking service: {chain_data.token}")
sftxb = self.get_eth_safe_tx_builder(ledger_config=ledger_config)
service_id = 594
sftxb.new_tx().add(
sftxb.get_unstaking_data(
service_id=chain_data.token,
staking_contract=STAKING[ledger_config.chain][staking_program_id],
service_id=service_id,
staking_contract="0xeF44Fb0842DDeF59D37f85D61A1eF492bbA6135d",
)
).settle()
chain_data.staked = False
service.store()
).add(sftxb.get_terminate_data(service_id=service_id)).add(sftxb.get_unbond_data(service_id=service_id)).settle()

def fund_service( # pylint: disable=too-many-arguments,too-many-locals
self,
Expand Down
13 changes: 9 additions & 4 deletions operate/services/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import logging
import tempfile
import time
import traceback
import typing as t
from datetime import datetime
from enum import Enum
Expand Down Expand Up @@ -113,10 +114,11 @@ def add(self, tx: t.Dict) -> "GnosisSafeTransaction":

def build(self) -> t.Dict:
"""Build the transaction."""
multisend_adr = ContractConfigs.multisend.contracts[self.chain_type] or "0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761"
multisend_data = bytes.fromhex(
registry_contracts.multisend.get_tx_data(
ledger_api=self.ledger_api,
contract_address=ContractConfigs.multisend.contracts[self.chain_type],
contract_address=multisend_adr,
multi_send_txs=self._txs,
).get("data")[2:]
)
Expand All @@ -125,15 +127,15 @@ def build(self) -> t.Dict:
contract_address=self.safe,
value=0,
safe_tx_gas=0,
to_address=ContractConfigs.multisend.contracts[self.chain_type],
to_address=multisend_adr,
data=multisend_data,
operation=SafeOperation.DELEGATE_CALL.value,
).get("tx_hash")[2:]
payload_data = hash_payload_to_hex(
safe_tx_hash=safe_tx_hash,
ether_value=0,
safe_tx_gas=0,
to_address=ContractConfigs.multisend.contracts[self.chain_type],
to_address=multisend_adr,
operation=SafeOperation.DELEGATE_CALL.value,
data=multisend_data,
)
Expand Down Expand Up @@ -174,7 +176,10 @@ def settle(self) -> t.Dict:
self.build()
tx_digest = self.ledger_api.send_signed_transaction(self.tx)
except Exception as e: # pylint: disable=broad-except
print(f"Error sending the safe tx: {e}")
# print error and trace
logging.error(f"Error while sending transaction: {e}")
# print trace
logging.error(traceback.format_exc())
tx_digest = None

if tx_digest is not None:
Expand Down

0 comments on commit c9b8e7c

Please sign in to comment.