From 70ed33234d4759b9d023600639f5505e2e4dc819 Mon Sep 17 00:00:00 2001 From: coderNp101 Date: Thu, 12 Mar 2026 19:57:18 +0545 Subject: [PATCH 1/4] better logging, and refund script to check for any missing bids yet to refund --- refund.py | 228 +++++++++++++++++++++++++++++ tensorusd/auction/contract.py | 146 ++++++++++++++++++ tensorusd/miner/auction_manager.py | 23 ++- 3 files changed, 391 insertions(+), 6 deletions(-) create mode 100644 refund.py diff --git a/refund.py b/refund.py new file mode 100644 index 0000000..3a33005 --- /dev/null +++ b/refund.py @@ -0,0 +1,228 @@ +""" +Refund checker script for miners. + +Checks whether the miner got all their bidded amount refunded +after an auction is finalized, and attempts to withdraw any unclaimed refunds. + +Usage: + python refund.py +""" + +import os +from substrateinterface import SubstrateInterface, Keypair +from substrateinterface.contracts import ContractInstance + +# ────────────────────────────────────────────────────────────── +# Configuration — update these values before running +# ────────────────────────────────────────────────────────────── +RPC_ENDPOINT = "wss://test.finney.opentensor.ai:443" +CONTRACT_ADDRESS = "5Gg9M2BBG4goA9upeo9CeNLreZsp99yooLQnfJ66DHUh6ukq" +METADATA_PATH = os.path.join(os.path.dirname(__file__), "tensorusd/abis/tusdt_auction.json") + +# Miner's mnemonic (coldkey) — used to sign withdraw transactions +MINER_MNEMONIC = "your mnemonic here" + +# Auction ID to check (set to None to check all finalized auctions the miner participated in) +AUCTION_ID = None + +PAGE_SIZE = 10 +# ────────────────────────────────────────────────────────────── + + +def connect(): + substrate = SubstrateInterface( + url=RPC_ENDPOINT, + use_remote_preset=True, + type_registry={"types": {"Balance": "u64"}}, + ) + contract = ContractInstance.create_from_address( + contract_address=CONTRACT_ADDRESS, + metadata_file=METADATA_PATH, + substrate=substrate, + ) + keypair = Keypair.create_from_mnemonic(MINER_MNEMONIC) + return substrate, contract, keypair + + +def get_auction(contract, keypair, auction_id): + result = contract.read(keypair, "get_auction", {"auction_id": auction_id}) + data = result.contract_result_data.value_object + if data and data[0] == "Ok" and data[1]: + return data[1].value + return None + + +def get_total_auctions_count(contract, keypair): + result = contract.read(keypair, "get_total_auctions_count") + data = result.contract_result_data.value_object + if data and data[0] == "Ok": + return data[1].value + return 0 + + +def get_bids_page(contract, keypair, auction_id, page): + result = contract.read( + keypair, "get_bids", + {"auction_id": auction_id, "page": page}, + ) + data = result.contract_result_data.value_object + if data and data[0] == "Ok" and data[1]: + return data[1].value["Ok"] + return [] + + +def withdraw_refund(contract, keypair, auction_id, bid_id): + args = {"auction_id": auction_id, "bid_id": bid_id} + gas_result = contract.read(keypair, "withdraw_refund", args) + receipt = contract.exec( + keypair, "withdraw_refund", args, + gas_limit=gas_result.gas_required, + ) + return receipt + + +def check_auction(contract, keypair, auction_id, auto_withdraw=False): + """Check a single auction for unrefunded bids. Returns summary dict.""" + my_address = keypair.ss58_address + auction = get_auction(contract, keypair, auction_id) + + if auction is None: + print(f" Auction {auction_id}: not found, skipping") + return None + + is_finalized = auction["is_finalized"] + highest_bid_id = auction.get("highest_bid_id") + highest_bidder = auction.get("highest_bidder") + bid_count = auction["bid_count"] + is_winner = highest_bidder == my_address + + # Collect all of the miner's bids for this auction + my_bids = [] + total_pages = (bid_count + PAGE_SIZE - 1) // PAGE_SIZE if bid_count > 0 else 0 + + for page in range(total_pages): + bids = get_bids_page(contract, keypair, auction_id, page) + for bid in bids: + if bid["bidder"] == my_address: + my_bids.append(bid) + + if not my_bids: + return None # miner didn't participate + + # Categorize bids + winning_bid = None + refundable_bids = [] + withdrawn_bids = [] + pending_bids = [] + + for bid in my_bids: + bid_id = bid["id"] + amount = bid["amount"] + is_withdrawn = bid["is_withdrawn"] + + # The winning bid is not refundable + if is_winner and bid_id == highest_bid_id: + winning_bid = bid + continue + + if is_withdrawn: + withdrawn_bids.append(bid) + else: + pending_bids.append(bid) + + # Print report + total_bidded = sum(b["amount"] for b in my_bids) + total_withdrawn = sum(b["amount"] for b in withdrawn_bids) + total_pending = sum(b["amount"] for b in pending_bids) + winning_amount = winning_bid["amount"] if winning_bid else 0 + + status = "FINALIZED" if is_finalized else "ACTIVE" + print(f"\n Auction {auction_id} [{status}]") + print(f" You placed {len(my_bids)} bid(s), total amount: {total_bidded}") + if is_winner: + print(f" ** You WON this auction (winning bid #{winning_bid['id']}, amount: {winning_amount}) **") + print(f" Refunds withdrawn: {len(withdrawn_bids)} bid(s), amount: {total_withdrawn}") + print(f" Refunds pending: {len(pending_bids)} bid(s), amount: {total_pending}") + + # Attempt auto-withdraw if requested + if auto_withdraw and is_finalized and pending_bids: + print(f" Attempting to withdraw {len(pending_bids)} pending refund(s)...") + for bid in pending_bids: + bid_id = bid["id"] + amount = bid["amount"] + try: + receipt = withdraw_refund(contract, keypair, auction_id, bid_id) + if receipt.is_success: + print(f" ✓ Withdrawn bid #{bid_id}, amount: {amount}, tx: {receipt.extrinsic_hash}") + else: + print(f" ✗ Failed bid #{bid_id}: {receipt.error_message}") + except Exception as e: + print(f" ✗ Error withdrawing bid #{bid_id}: {e}") + + return { + "auction_id": auction_id, + "is_finalized": is_finalized, + "is_winner": is_winner, + "total_bids": len(my_bids), + "total_bidded": total_bidded, + "winning_amount": winning_amount, + "withdrawn": total_withdrawn, + "pending": total_pending, + "pending_count": len(pending_bids), + } + + +def main(): + print("Connecting to chain...") + substrate, contract, keypair = connect() + print(f"Miner address: {keypair.ss58_address}") + print(f"Contract: {CONTRACT_ADDRESS}") + + # Ask user whether to auto-withdraw + auto_withdraw = input("\nAuto-withdraw pending refunds? (y/n): ").strip().lower() == "y" + + auction_ids = [] + if AUCTION_ID is not None: + auction_ids = [AUCTION_ID] + else: + total = get_total_auctions_count(contract, keypair) + print(f"Total auctions on contract: {total}") + auction_ids = range(total) + + results = [] + for aid in auction_ids: + try: + summary = check_auction(contract, keypair, aid, auto_withdraw) + if summary: + results.append(summary) + except Exception as e: + print(f" Error checking auction {aid}: {e}") + + # Final summary + if not results: + print("\nNo auctions found where this miner participated.") + return + + total_pending = sum(r["pending"] for r in results) + total_pending_count = sum(r["pending_count"] for r in results) + total_withdrawn = sum(r["withdrawn"] for r in results) + total_won = sum(r["winning_amount"] for r in results) + + print("\n" + "=" * 55) + print("REFUND SUMMARY") + print("=" * 55) + print(f" Auctions participated in: {len(results)}") + print(f" Total refunds withdrawn: {total_withdrawn}") + print(f" Total refunds pending: {total_pending} ({total_pending_count} bid(s))") + print(f" Total spent on wins: {total_won}") + + if total_pending > 0: + print(f"\n ⚠ You have {total_pending} TUSDT in unclaimed refunds!") + if not auto_withdraw: + print(" Run again with auto-withdraw to claim them.") + else: + print("\n ✓ All refunds accounted for. Nothing left behind.") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/tensorusd/auction/contract.py b/tensorusd/auction/contract.py index ffd4507..f728899 100644 --- a/tensorusd/auction/contract.py +++ b/tensorusd/auction/contract.py @@ -395,6 +395,22 @@ def get_active_auctions_count(self) -> int: except Exception as e: bt.logging.error(f"Error getting active auctions count: {e}") return 0 + + def _get_bid_count(self, auction_id: int) -> int: + """Get count of bids.""" + try: + result = self.contract.read( + keypair=self.wallet.hotkey, + method="get_all_auctions", + args={"auction_id": auction_id} + ) + data = result.contract_result_data.value_object + if data and data[0] == "Ok": + return data[1]['bid_count'] + return 0 + except Exception as e: + bt.logging.error(f"Error getting bid count: {e}") + return 0 def get_current_block(self) -> int: return self.substrate.get_block_number(None) @@ -412,6 +428,136 @@ def get_current_timestamp(self) -> int: except Exception as e: bt.logging.error(f"Error getting blockchain timestamp: {e}") return 0 + + def withdraw_refund( + self, + auction_id: int, + bid_id: int, + keypair: Keypair + ) -> Optional[str]: + """ + Withdraw a refund for a bid on a liquidation auction. + + Args: + auction_id: Auction ID to withdraw refund from (u32) + bid_id: Bid ID to withdraw refund for (u32) + keypair: Keypair to sign the transaction + + Returns: + Transaction hash if successful, None otherwise + """ + try: + args = { + "auction_id": auction_id, + "bid_id": bid_id, + } + + gas_predict_result = self.contract.read( + keypair=keypair, + method="withdraw_refund", + args=args, + ) + + receipt = self.contract.exec( + keypair=keypair, + method="withdraw_refund", + args=args, + gas_limit=gas_predict_result.gas_required, + ) + + if receipt.is_success: + bt.logging.info( + f"Refund withdrawn: auction={auction_id}, bid_id={bid_id}, " + f"tx={receipt.extrinsic_hash}" + ) + return receipt.extrinsic_hash + else: + bt.logging.error(f"Refund withdrawal failed: {receipt.error_message}") + return None + + except Exception as e: + bt.logging.error(f"Error withdrawing refund: {e}") + return None + + + def get_own_bids(self, auction_id: int) -> int: + """ + Sum up bid amounts for bids placed by this wallet's coldkey. + + Iterates paginated bids from the contract and accumulates + the total amount for bids where the bidder matches this wallet. + + Returns: + Total bid amount placed by own coldkey, or 0 if none found + """ + total_amount = 0 + PAGE_SIZE = 10 + my_address = self.wallet.coldkey.ss58_address + + bt.logging.info("Fetching own bids from contract...") + + try: + total_bids = self._get_bid_count(auction_id) + + if total_bids == 0: + bt.logging.info("No bids found") + return 0 + + total_pages = (total_bids + PAGE_SIZE - 1) // PAGE_SIZE + bt.logging.info( + f"Found {total_bids} active auctions across {total_pages} pages" + ) + + for page in range(total_pages): + result = self.contract.read( + keypair=self.wallet.hotkey, + method="get_bids", + args={ + "auction_id": auction_id, + "page": page + }, + ) + + data = result.contract_result_data.value_object + if data and data[0] == "Ok" and data[1]: + bid_list = data[1].value["Ok"] + + for bid_data in bid_list: + bidder = bid_data["bidder"] + bid_id = bid_data["bid_id"] + amount = bid_data["amount"] + + + if bidder == my_address: + receipt = self.withdraw_refund( + auction_id=auction_id, + bid_id=bid_id, + keypair=self.wallet.coldkey, + ) + + if receipt.is_success: + total_amount += amount + + else: + bt.logging.warning( + f"Failed to withdraw refund for auction={auction_id}, " + f"bid_id={bid_id}, skipping but continuing with other bids" + ) + + + bt.logging.debug( + f"Own bid found: bidder={bidder}, amount={bid_data['amount']}" + ) + + bt.logging.info( + f"Fetched own bids total amount: {total_amount}" + ) + return total_amount + + except Exception as e: + bt.logging.error(f"Error fetching own bids: {e}") + return 0 + def get_active_auctions(self) -> List[ActiveAuction]: """ diff --git a/tensorusd/miner/auction_manager.py b/tensorusd/miner/auction_manager.py index d7ec36f..0db148d 100644 --- a/tensorusd/miner/auction_manager.py +++ b/tensorusd/miner/auction_manager.py @@ -182,17 +182,28 @@ async def handle_auction_finalized(self, event: AuctionEvent): """ auction_id = event.auction_id my_address = self.wallet.coldkey.ss58_address + amount_refunded= 0 if event.winner == my_address: bt.logging.success( f"Won auction {auction_id}! winning_bid={event.highest_bid}" ) - else: - bt.logging.info( - f"Auction {auction_id} finalized. " - f"winner={event.winner}, " - f"winning_bid={event.highest_bid}" - ) + amount_refunded = -event.highest_bid + + + bt.logging.info( + f"Auction {auction_id} finalized. " + f"winner={event.winner}, " + f"winning_bid={event.highest_bid}" + ) + + amount_refunded += self.auction_contract.get_own_bids(auction_id) + + bt.logging.info( + f"Settlement amount: " + f"{amount_refunded:+d} TUSDT " + f"({'refund' if amount_refunded > 0 else 'payment'})" + ) async def _submit_bid(self, auction_id: int, bid_amount: int) -> Optional[str]: """ From 39caeac2a1152c6fe317bc24d2c35dd49f52e1aa Mon Sep 17 00:00:00 2001 From: coderNp101 Date: Fri, 13 Mar 2026 20:36:05 +0545 Subject: [PATCH 2/4] refund --- refund.py | 280 +++++++++-------------------- tensorusd/auction/contract.py | 116 ++++++------ tensorusd/miner/auction_manager.py | 24 +-- 3 files changed, 143 insertions(+), 277 deletions(-) diff --git a/refund.py b/refund.py index 3a33005..31d7915 100644 --- a/refund.py +++ b/refund.py @@ -1,228 +1,114 @@ """ -Refund checker script for miners. +Check whether bids for a given auction ID have been refunded. -Checks whether the miner got all their bidded amount refunded -after an auction is finalized, and attempts to withdraw any unclaimed refunds. +COLDKEY_PASSWORD is read from .env automatically. Usage: - python refund.py + uv run refund.py \ + --netuid 421 \ + --subtensor.network test \ + --wallet.name test \ + --wallet.hotkey default \ + --logging.info """ +import asyncio +import argparse import os -from substrateinterface import SubstrateInterface, Keypair -from substrateinterface.contracts import ContractInstance -# ────────────────────────────────────────────────────────────── -# Configuration — update these values before running -# ────────────────────────────────────────────────────────────── -RPC_ENDPOINT = "wss://test.finney.opentensor.ai:443" -CONTRACT_ADDRESS = "5Gg9M2BBG4goA9upeo9CeNLreZsp99yooLQnfJ66DHUh6ukq" -METADATA_PATH = os.path.join(os.path.dirname(__file__), "tensorusd/abis/tusdt_auction.json") +import bittensor as bt +from dotenv import load_dotenv +import logging +logging.getLogger("bittensor").propagate = False -# Miner's mnemonic (coldkey) — used to sign withdraw transactions -MINER_MNEMONIC = "your mnemonic here" +from tensorusd.auction.types import AuctionEvent, AuctionEventType +from tensorusd.auction.contract import TensorUSDAuctionContract, create_substrate_interface +from tensorusd.miner.auction_manager import MinerAuctionManager -# Auction ID to check (set to None to check all finalized auctions the miner participated in) -AUCTION_ID = None +load_dotenv() -PAGE_SIZE = 10 -# ────────────────────────────────────────────────────────────── +# Hardcode the auction ID to check +AUCTION_ID = 9 -def connect(): - substrate = SubstrateInterface( - url=RPC_ENDPOINT, - use_remote_preset=True, - type_registry={"types": {"Balance": "u64"}}, - ) - contract = ContractInstance.create_from_address( - contract_address=CONTRACT_ADDRESS, - metadata_file=METADATA_PATH, - substrate=substrate, +def build_config() -> bt.Config: + parser = argparse.ArgumentParser(description="Check auction bid refund status") + bt.Wallet.add_args(parser) + bt.Subtensor.add_args(parser) + bt.logging.add_args(parser) + + parser.add_argument( + "--auction_contract.address", + type=str, + default=os.getenv("AUCTION_CONTRACT_ADDRESS"), + required=os.getenv("AUCTION_CONTRACT_ADDRESS") is None, + help="TensorUSD Auction contract address (SS58).", ) - keypair = Keypair.create_from_mnemonic(MINER_MNEMONIC) - return substrate, contract, keypair + return bt.Config(parser) -def get_auction(contract, keypair, auction_id): - result = contract.read(keypair, "get_auction", {"auction_id": auction_id}) - data = result.contract_result_data.value_object - if data and data[0] == "Ok" and data[1]: - return data[1].value - return None +async def main(): + config = build_config() + bt.logging(config=config) -def get_total_auctions_count(contract, keypair): - result = contract.read(keypair, "get_total_auctions_count") - data = result.contract_result_data.value_object - if data and data[0] == "Ok": - return data[1].value - return 0 + # Unlock wallet — coldkey is the bidder, hotkey is the signing keypair + coldkey_password = os.getenv("COLDKEY_PASSWORD") + if not coldkey_password: + bt.logging.error("COLDKEY_PASSWORD not set in .env. Exiting.") + return + wallet = bt.Wallet(config=config) + wallet.coldkey_file.save_password_to_env(coldkey_password) + wallet.unlock_coldkey() + bt.logging.info(f"Wallet ready — coldkey: {wallet.coldkey.ss58_address}") + # Connect to chain + subtensor = bt.Subtensor(config=config) + substrate = create_substrate_interface(subtensor.chain_endpoint) -def get_bids_page(contract, keypair, auction_id, page): - result = contract.read( - keypair, "get_bids", - {"auction_id": auction_id, "page": page}, - ) - data = result.contract_result_data.value_object - if data and data[0] == "Ok" and data[1]: - return data[1].value["Ok"] - return [] - - -def withdraw_refund(contract, keypair, auction_id, bid_id): - args = {"auction_id": auction_id, "bid_id": bid_id} - gas_result = contract.read(keypair, "withdraw_refund", args) - receipt = contract.exec( - keypair, "withdraw_refund", args, - gas_limit=gas_result.gas_required, + auction_contract = TensorUSDAuctionContract( + substrate=substrate, + contract_address=config.auction_contract.address, + metadata_path="tensorusd/abis/tusdt_auction.json", + wallet=wallet, ) - return receipt - -def check_auction(contract, keypair, auction_id, auto_withdraw=False): - """Check a single auction for unrefunded bids. Returns summary dict.""" - my_address = keypair.ss58_address - auction = get_auction(contract, keypair, auction_id) + # Pre-checks: auction must exist and be finalized before doing anything + bt.logging.info(f"Fetching auction {AUCTION_ID} from chain ...") + auction = auction_contract.get_auction(AUCTION_ID) if auction is None: - print(f" Auction {auction_id}: not found, skipping") - return None - - is_finalized = auction["is_finalized"] - highest_bid_id = auction.get("highest_bid_id") - highest_bidder = auction.get("highest_bidder") - bid_count = auction["bid_count"] - is_winner = highest_bidder == my_address - - # Collect all of the miner's bids for this auction - my_bids = [] - total_pages = (bid_count + PAGE_SIZE - 1) // PAGE_SIZE if bid_count > 0 else 0 - - for page in range(total_pages): - bids = get_bids_page(contract, keypair, auction_id, page) - for bid in bids: - if bid["bidder"] == my_address: - my_bids.append(bid) - - if not my_bids: - return None # miner didn't participate - - # Categorize bids - winning_bid = None - refundable_bids = [] - withdrawn_bids = [] - pending_bids = [] - - for bid in my_bids: - bid_id = bid["id"] - amount = bid["amount"] - is_withdrawn = bid["is_withdrawn"] - - # The winning bid is not refundable - if is_winner and bid_id == highest_bid_id: - winning_bid = bid - continue - - if is_withdrawn: - withdrawn_bids.append(bid) - else: - pending_bids.append(bid) - - # Print report - total_bidded = sum(b["amount"] for b in my_bids) - total_withdrawn = sum(b["amount"] for b in withdrawn_bids) - total_pending = sum(b["amount"] for b in pending_bids) - winning_amount = winning_bid["amount"] if winning_bid else 0 - - status = "FINALIZED" if is_finalized else "ACTIVE" - print(f"\n Auction {auction_id} [{status}]") - print(f" You placed {len(my_bids)} bid(s), total amount: {total_bidded}") - if is_winner: - print(f" ** You WON this auction (winning bid #{winning_bid['id']}, amount: {winning_amount}) **") - print(f" Refunds withdrawn: {len(withdrawn_bids)} bid(s), amount: {total_withdrawn}") - print(f" Refunds pending: {len(pending_bids)} bid(s), amount: {total_pending}") - - # Attempt auto-withdraw if requested - if auto_withdraw and is_finalized and pending_bids: - print(f" Attempting to withdraw {len(pending_bids)} pending refund(s)...") - for bid in pending_bids: - bid_id = bid["id"] - amount = bid["amount"] - try: - receipt = withdraw_refund(contract, keypair, auction_id, bid_id) - if receipt.is_success: - print(f" ✓ Withdrawn bid #{bid_id}, amount: {amount}, tx: {receipt.extrinsic_hash}") - else: - print(f" ✗ Failed bid #{bid_id}: {receipt.error_message}") - except Exception as e: - print(f" ✗ Error withdrawing bid #{bid_id}: {e}") - - return { - "auction_id": auction_id, - "is_finalized": is_finalized, - "is_winner": is_winner, - "total_bids": len(my_bids), - "total_bidded": total_bidded, - "winning_amount": winning_amount, - "withdrawn": total_withdrawn, - "pending": total_pending, - "pending_count": len(pending_bids), - } - - -def main(): - print("Connecting to chain...") - substrate, contract, keypair = connect() - print(f"Miner address: {keypair.ss58_address}") - print(f"Contract: {CONTRACT_ADDRESS}") - - # Ask user whether to auto-withdraw - auto_withdraw = input("\nAuto-withdraw pending refunds? (y/n): ").strip().lower() == "y" - - auction_ids = [] - if AUCTION_ID is not None: - auction_ids = [AUCTION_ID] - else: - total = get_total_auctions_count(contract, keypair) - print(f"Total auctions on contract: {total}") - auction_ids = range(total) - - results = [] - for aid in auction_ids: - try: - summary = check_auction(contract, keypair, aid, auto_withdraw) - if summary: - results.append(summary) - except Exception as e: - print(f" Error checking auction {aid}: {e}") - - # Final summary - if not results: - print("\nNo auctions found where this miner participated.") + bt.logging.error(f"Auction {AUCTION_ID} not found on chain. Exiting.") return - total_pending = sum(r["pending"] for r in results) - total_pending_count = sum(r["pending_count"] for r in results) - total_withdrawn = sum(r["withdrawn"] for r in results) - total_won = sum(r["winning_amount"] for r in results) + if not auction.is_finalized: + bt.logging.warning( + f"Auction {AUCTION_ID} is not finalized yet. " + f"highest_bid={auction.highest_bid}, " + f"highest_bidder={auction.highest_bidder}. Exiting." + ) + return - print("\n" + "=" * 55) - print("REFUND SUMMARY") - print("=" * 55) - print(f" Auctions participated in: {len(results)}") - print(f" Total refunds withdrawn: {total_withdrawn}") - print(f" Total refunds pending: {total_pending} ({total_pending_count} bid(s))") - print(f" Total spent on wins: {total_won}") + # vault_contract/strategy/tusdt not needed for handle_auction_finalized + manager = MinerAuctionManager( + auction_contract=auction_contract, + vault_contract=None, + strategy=None, + wallet=wallet, + ) + + # Build event using real on-chain winner data + event = AuctionEvent( + event_type=AuctionEventType.FINALIZED, + block_number=0, + auction_id=AUCTION_ID, + winner=auction.highest_bidder, + highest_bid=auction.highest_bid, + ) - if total_pending > 0: - print(f"\n ⚠ You have {total_pending} TUSDT in unclaimed refunds!") - if not auto_withdraw: - print(" Run again with auto-withdraw to claim them.") - else: - print("\n ✓ All refunds accounted for. Nothing left behind.") + bt.logging.info(f"Checking refund status for auction_id={AUCTION_ID} ...") + await manager.handle_auction_finalized(event) if __name__ == "__main__": - main() \ No newline at end of file + asyncio.run(main()) \ No newline at end of file diff --git a/tensorusd/auction/contract.py b/tensorusd/auction/contract.py index f728899..5523ec2 100644 --- a/tensorusd/auction/contract.py +++ b/tensorusd/auction/contract.py @@ -446,6 +446,9 @@ def withdraw_refund( Returns: Transaction hash if successful, None otherwise """ + + bt.logging.info("Refunding your latest bid from contract") + try: args = { "auction_id": auction_id, @@ -458,6 +461,9 @@ def withdraw_refund( args=args, ) + bt.logging.info( + f"Submitting withdraw_refund tx: auction_id={auction_id}, bid_id={bid_id}" + ) receipt = self.contract.exec( keypair=keypair, method="withdraw_refund", @@ -479,85 +485,69 @@ def withdraw_refund( bt.logging.error(f"Error withdrawing refund: {e}") return None - - def get_own_bids(self, auction_id: int) -> int: + def get_auction_bid( + self, + auction_id: int, + ) -> Optional[str]: """ - Sum up bid amounts for bids placed by this wallet's coldkey. + Withdraw a refund for a bid on a liquidation auction. - Iterates paginated bids from the contract and accumulates - the total amount for bids where the bidder matches this wallet. + Args: + auction_id: Auction ID to withdraw refund from (u32) + bid_id: Bid ID to withdraw refund for (u32) + keypair: Keypair to sign the transaction Returns: - Total bid amount placed by own coldkey, or 0 if none found + Transaction hash if successful, None otherwise """ - total_amount = 0 - PAGE_SIZE = 10 my_address = self.wallet.coldkey.ss58_address - - bt.logging.info("Fetching own bids from contract...") + keypair = self.wallet.hotkey + bt.logging.info( + f"Fetching bid info from contract: auction_id={auction_id}, bidder={my_address}" + ) try: - total_bids = self._get_bid_count(auction_id) - - if total_bids == 0: - bt.logging.info("No bids found") - return 0 + args = { + "auction_id": auction_id, + "bidder": my_address, + } - total_pages = (total_bids + PAGE_SIZE - 1) // PAGE_SIZE - bt.logging.info( - f"Found {total_bids} active auctions across {total_pages} pages" + result = self.contract.read( + keypair=keypair, + method="get_auction_bid", + args=args, ) - for page in range(total_pages): - result = self.contract.read( - keypair=self.wallet.hotkey, - method="get_bids", - args={ - "auction_id": auction_id, - "page": page - }, - ) - - data = result.contract_result_data.value_object - if data and data[0] == "Ok" and data[1]: - bid_list = data[1].value["Ok"] - - for bid_data in bid_list: - bidder = bid_data["bidder"] - bid_id = bid_data["bid_id"] - amount = bid_data["amount"] - - - if bidder == my_address: - receipt = self.withdraw_refund( - auction_id=auction_id, - bid_id=bid_id, - keypair=self.wallet.coldkey, - ) + data = result.contract_result_data.value_object - if receipt.is_success: - total_amount += amount - - else: - bt.logging.warning( - f"Failed to withdraw refund for auction={auction_id}, " - f"bid_id={bid_id}, skipping but continuing with other bids" - ) - + if data and data[0] == "Ok" and data[1]: + bid_id = data[1].value["id"] + amount = data[1].value["amount"] + withdrawn = data[1].value["is_withdrawn"] - bt.logging.debug( - f"Own bid found: bidder={bidder}, amount={bid_data['amount']}" - ) + bt.logging.info( + f"Bid found: auction_id={auction_id}, bid_id={bid_id}, " + f"amount={amount}, is_withdrawn={withdrawn}" + ) - bt.logging.info( - f"Fetched own bids total amount: {total_amount}" - ) - return total_amount + if not withdrawn: + bt.logging.info( + f"Bid not yet refunded — initiating withdrawal: " + f"auction_id={auction_id}, bid_id={bid_id}" + ) + self.withdraw_refund(auction_id, bid_id, keypair) + else: + bt.logging.info( + f"Bid already withdrawn: auction_id={auction_id}, " + f"bid_id={bid_id}, amount={amount}" + ) + else: + bt.logging.info( + f"No bid found for auction_id={auction_id}, bidder={my_address}" + ) except Exception as e: - bt.logging.error(f"Error fetching own bids: {e}") - return 0 - + bt.logging.error(f"Error fetching auction bid: {e}") def get_active_auctions(self) -> List[ActiveAuction]: """ diff --git a/tensorusd/miner/auction_manager.py b/tensorusd/miner/auction_manager.py index 0db148d..dee7d14 100644 --- a/tensorusd/miner/auction_manager.py +++ b/tensorusd/miner/auction_manager.py @@ -182,28 +182,18 @@ async def handle_auction_finalized(self, event: AuctionEvent): """ auction_id = event.auction_id my_address = self.wallet.coldkey.ss58_address - amount_refunded= 0 if event.winner == my_address: bt.logging.success( f"Won auction {auction_id}! winning_bid={event.highest_bid}" ) - amount_refunded = -event.highest_bid - - - bt.logging.info( - f"Auction {auction_id} finalized. " - f"winner={event.winner}, " - f"winning_bid={event.highest_bid}" - ) - - amount_refunded += self.auction_contract.get_own_bids(auction_id) - - bt.logging.info( - f"Settlement amount: " - f"{amount_refunded:+d} TUSDT " - f"({'refund' if amount_refunded > 0 else 'payment'})" - ) + else: + bt.logging.info( + f"Auction {auction_id} finalized. " + f"winner={event.winner}, " + f"winning_bid={event.highest_bid}" + ) + self.auction_contract.get_auction_bid(auction_id) async def _submit_bid(self, auction_id: int, bid_amount: int) -> Optional[str]: """ From 7514dcc4bb727ee9aa7612aee388ecbcc61e1c9b Mon Sep 17 00:00:00 2001 From: coderNp101 Date: Sun, 15 Mar 2026 16:22:48 +0545 Subject: [PATCH 3/4] keypair change --- tensorusd/auction/contract.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tensorusd/auction/contract.py b/tensorusd/auction/contract.py index 5523ec2..bf8f26a 100644 --- a/tensorusd/auction/contract.py +++ b/tensorusd/auction/contract.py @@ -432,8 +432,7 @@ def get_current_timestamp(self) -> int: def withdraw_refund( self, auction_id: int, - bid_id: int, - keypair: Keypair + bid_id: int ) -> Optional[str]: """ Withdraw a refund for a bid on a liquidation auction. @@ -456,7 +455,7 @@ def withdraw_refund( } gas_predict_result = self.contract.read( - keypair=keypair, + keypair=self.wallet.coldkey, method="withdraw_refund", args=args, ) @@ -465,7 +464,7 @@ def withdraw_refund( f"Submitting withdraw_refund tx: auction_id={auction_id}, bid_id={bid_id}" ) receipt = self.contract.exec( - keypair=keypair, + keypair=self.wallet.coldkey, method="withdraw_refund", args=args, gas_limit=gas_predict_result.gas_required, @@ -501,7 +500,6 @@ def get_auction_bid( Transaction hash if successful, None otherwise """ my_address = self.wallet.coldkey.ss58_address - keypair = self.wallet.hotkey bt.logging.info( f"Fetching bid info from contract: auction_id={auction_id}, bidder={my_address}" ) @@ -513,7 +511,7 @@ def get_auction_bid( } result = self.contract.read( - keypair=keypair, + keypair=self.wallet.hotkey, method="get_auction_bid", args=args, ) @@ -535,7 +533,7 @@ def get_auction_bid( f"Bid not yet refunded — initiating withdrawal: " f"auction_id={auction_id}, bid_id={bid_id}" ) - self.withdraw_refund(auction_id, bid_id, keypair) + self.withdraw_refund(auction_id, bid_id) else: bt.logging.info( f"Bid already withdrawn: auction_id={auction_id}, " From a7958f2b9ea7b1c9c70cd553b6e4253323916f41 Mon Sep 17 00:00:00 2001 From: coderNp101 Date: Wed, 18 Mar 2026 15:36:55 +0545 Subject: [PATCH 4/4] updated abis and remove logging repetition --- neurons/miner.py | 2 + tensorusd/abis/tusdt_auction.json | 515 ++++++++++++++++++++++-------- tensorusd/abis/tusdt_erc20.json | 42 ++- tensorusd/abis/tusdt_vault.json | 218 ++++++++++--- 4 files changed, 578 insertions(+), 199 deletions(-) diff --git a/neurons/miner.py b/neurons/miner.py index 64b3a05..c8c81aa 100644 --- a/neurons/miner.py +++ b/neurons/miner.py @@ -21,6 +21,8 @@ import typing import asyncio import bittensor as bt +import logging +logging.getLogger("bittensor").propagate = False # Bittensor Miner tensorusd: import tensorusd diff --git a/tensorusd/abis/tusdt_auction.json b/tensorusd/abis/tusdt_auction.json index cbb09d0..f01b194 100644 --- a/tensorusd/abis/tusdt_auction.json +++ b/tensorusd/abis/tusdt_auction.json @@ -1,6 +1,6 @@ { "source": { - "hash": "0xbc85bef428ab060dc2d806901d10400e7c59f69fc2df46a014e801614e71587e", + "hash": "0x1fc0856fb4bdf701e67c80582d75d440bc6aa99336809c79382865f70f24fc9f", "language": "ink! 5.1.1", "compiler": "rustc 1.93.0", "build_info": { @@ -34,6 +34,15 @@ "type": 0 } }, + { + "label": "admin", + "type": { + "displayName": [ + "AccountId" + ], + "type": 0 + } + }, { "label": "token_address", "type": { @@ -45,7 +54,9 @@ } ], "default": false, - "docs": [], + "docs": [ + "Initializes the auction contract with owner, admin, and token contract reference." + ], "label": "new", "payable": false, "returnType": { @@ -53,7 +64,7 @@ "ink_primitives", "ConstructorResult" ], - "type": 34 + "type": 38 }, "selector": "0x9bae9d5e" } @@ -82,13 +93,13 @@ "displayName": [ "ChainExtension" ], - "type": 56 + "type": 60 }, "hash": { "displayName": [ "Hash" ], - "type": 55 + "type": 59 }, "maxEventTopics": 4, "staticBufferSize": 16384, @@ -264,9 +275,9 @@ "label": "winner", "type": { "displayName": [ - "Option" + "AccountId" ], - "type": 8 + "type": 0 } }, { @@ -279,12 +290,34 @@ ], "type": 4 } + }, + { + "docs": [], + "indexed": false, + "label": "debt_balance", + "type": { + "displayName": [ + "Balance" + ], + "type": 4 + } + }, + { + "docs": [], + "indexed": false, + "label": "highest_bid_metadata", + "type": { + "displayName": [ + "Option" + ], + "type": 17 + } } ], "docs": [], "label": "AuctionFinalized", "module_path": "tusdt_auction::auction", - "signature_topic": "0xecb6c55d94a9aac8b4e207a8cb763f4460b8e570530c936dff17a77a009fb26e" + "signature_topic": "0x2bb1b99d11a544c4702e6bb53e1eaea4a6f257ac8d2e41b9c747027662fadd53" }, { "args": [ @@ -374,7 +407,7 @@ "ink", "LangError" ], - "type": 35 + "type": 39 }, "messages": [ { @@ -421,12 +454,14 @@ "displayName": [ "Option" ], - "type": 36 + "type": 40 } } ], "default": false, - "docs": [], + "docs": [ + " Creates a new liquidation auction for a vault with specified collateral and debt, returning the auction ID." + ], "label": "create_auction", "mutates": true, "payable": false, @@ -435,7 +470,7 @@ "ink", "MessageResult" ], - "type": 37 + "type": 41 }, "selector": "0xd6cd59d7" }, @@ -470,7 +505,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Places a bid on an auction, transferring the bid amount and updating the highest bid if applicable." + ], "label": "place_bid", "mutates": true, "payable": false, @@ -479,7 +516,7 @@ "ink", "MessageResult" ], - "type": 37 + "type": 41 }, "selector": "0x441cccf2" }, @@ -496,7 +533,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Finalizes an auction after it has ended, marking the highest bidder as winner." + ], "label": "finalize_auction", "mutates": true, "payable": false, @@ -505,7 +544,7 @@ "ink", "MessageResult" ], - "type": 40 + "type": 44 }, "selector": "0x28dd27b4" }, @@ -531,7 +570,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Withdraws refund for a losing bid after the auction is finalized." + ], "label": "withdraw_refund", "mutates": true, "payable": false, @@ -540,7 +581,7 @@ "ink", "MessageResult" ], - "type": 40 + "type": 44 }, "selector": "0xb98ba333" }, @@ -557,7 +598,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Retrieves the details of an auction by its ID." + ], "label": "get_auction", "mutates": false, "payable": false, @@ -566,7 +609,7 @@ "ink", "MessageResult" ], - "type": 42 + "type": 46 }, "selector": "0x15a41cb5" }, @@ -592,7 +635,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Returns the active auction ID for a vault, or None if no active auction exists." + ], "label": "get_active_vault_auction", "mutates": false, "payable": false, @@ -601,7 +646,7 @@ "ink", "MessageResult" ], - "type": 44 + "type": 48 }, "selector": "0x9b023efc" }, @@ -627,7 +672,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Retrieves a specific bid from an auction by auction ID and bid ID." + ], "label": "get_bid", "mutates": false, "payable": false, @@ -636,10 +683,47 @@ "ink", "MessageResult" ], - "type": 45 + "type": 49 }, "selector": "0xdc2d27f1" }, + { + "args": [ + { + "label": "auction_id", + "type": { + "displayName": [ + "u32" + ], + "type": 3 + } + }, + { + "label": "bidder", + "type": { + "displayName": [ + "AccountId" + ], + "type": 0 + } + } + ], + "default": false, + "docs": [ + " Retrieves a specific bid from an auction by auction ID and Bidder." + ], + "label": "get_auction_bid", + "mutates": false, + "payable": false, + "returnType": { + "displayName": [ + "ink", + "MessageResult" + ], + "type": 49 + }, + "selector": "0xa594e324" + }, { "args": [ { @@ -662,7 +746,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Returns a paginated list of all bids placed on an auction." + ], "label": "get_bids", "mutates": false, "payable": false, @@ -671,14 +757,16 @@ "ink", "MessageResult" ], - "type": 47 + "type": 51 }, "selector": "0x03302346" }, { "args": [], "default": false, - "docs": [], + "docs": [ + " Returns the total number of auctions created." + ], "label": "get_total_auctions_count", "mutates": false, "payable": false, @@ -687,14 +775,16 @@ "ink", "MessageResult" ], - "type": 50 + "type": 54 }, "selector": "0x2700a61f" }, { "args": [], "default": false, - "docs": [], + "docs": [ + " Returns the total number of active auctions." + ], "label": "get_active_auctions_count", "mutates": false, "payable": false, @@ -703,7 +793,7 @@ "ink", "MessageResult" ], - "type": 50 + "type": 54 }, "selector": "0x996f931c" }, @@ -720,7 +810,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Returns a paginated list of all auctions." + ], "label": "get_all_auctions", "mutates": false, "payable": false, @@ -729,7 +821,7 @@ "ink", "MessageResult" ], - "type": 51 + "type": 55 }, "selector": "0x95baa3db" }, @@ -746,7 +838,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Returns a paginated list of active auctions." + ], "label": "get_active_auctions", "mutates": false, "payable": false, @@ -755,14 +849,16 @@ "ink", "MessageResult" ], - "type": 51 + "type": 55 }, "selector": "0x038c0d69" }, { "args": [], "default": false, - "docs": [], + "docs": [ + " Returns the owner account ID." + ], "label": "owner", "mutates": false, "payable": false, @@ -771,9 +867,27 @@ "ink", "MessageResult" ], - "type": 54 + "type": 58 }, "selector": "0xfeaea4fa" + }, + { + "args": [], + "default": false, + "docs": [ + " Returns the admin account ID." + ], + "label": "admin", + "mutates": false, + "payable": false, + "returnType": { + "displayName": [ + "ink", + "MessageResult" + ], + "type": 58 + }, + "selector": "0x1aa66b39" } ] }, @@ -791,6 +905,15 @@ }, "name": "owner" }, + { + "layout": { + "leaf": { + "key": "0x00000000", + "ty": 0 + } + }, + "name": "admin" + }, { "layout": { "struct": { @@ -1093,6 +1216,21 @@ }, "name": "auction_bids" }, + { + "layout": { + "root": { + "layout": { + "leaf": { + "key": "0x68dcca1b", + "ty": 3 + } + }, + "root_key": "0x68dcca1b", + "ty": 21 + } + }, + "name": "auction_bidder_bids" + }, { "layout": { "root": { @@ -1103,7 +1241,7 @@ } }, "root_key": "0xafa18ddb", - "ty": 21 + "ty": 25 } }, "name": "active_vault_auction" @@ -1127,7 +1265,7 @@ } }, "root_key": "0xd9c4d144", - "ty": 25 + "ty": 29 } }, "name": "active_auctions" @@ -1142,7 +1280,7 @@ } }, "root_key": "0xf0e8b11f", - "ty": 28 + "ty": 32 } }, "name": "active_auction_indices" @@ -1152,7 +1290,7 @@ } }, "root_key": "0x00000000", - "ty": 31 + "ty": 35 } }, "types": [ @@ -1666,8 +1804,8 @@ "type": { "def": { "tuple": [ - 0, - 3 + 3, + 0 ] } } @@ -1723,7 +1861,7 @@ "params": [ { "name": "K", - "type": 3 + "type": 26 }, { "name": "V", @@ -1731,7 +1869,7 @@ }, { "name": "KeyType", - "type": 26 + "type": 27 } ], "path": [ @@ -1744,6 +1882,17 @@ }, { "id": 26, + "type": { + "def": { + "tuple": [ + 0, + 3 + ] + } + } + }, + { + "id": 27, "type": { "def": { "composite": {} @@ -1755,7 +1904,7 @@ }, { "name": "R", - "type": 27 + "type": 28 } ], "path": [ @@ -1766,7 +1915,7 @@ } }, { - "id": 27, + "id": 28, "type": { "def": { "composite": {} @@ -1785,7 +1934,7 @@ } }, { - "id": 28, + "id": 29, "type": { "def": { "composite": {} @@ -1801,7 +1950,7 @@ }, { "name": "KeyType", - "type": 29 + "type": 30 } ], "path": [ @@ -1813,7 +1962,7 @@ } }, { - "id": 29, + "id": 30, "type": { "def": { "composite": {} @@ -1825,7 +1974,7 @@ }, { "name": "R", - "type": 30 + "type": 31 } ], "path": [ @@ -1836,7 +1985,7 @@ } }, { - "id": 30, + "id": 31, "type": { "def": { "composite": {} @@ -1855,7 +2004,77 @@ } }, { - "id": 31, + "id": 32, + "type": { + "def": { + "composite": {} + }, + "params": [ + { + "name": "K", + "type": 3 + }, + { + "name": "V", + "type": 3 + }, + { + "name": "KeyType", + "type": 33 + } + ], + "path": [ + "ink_storage", + "lazy", + "mapping", + "Mapping" + ] + } + }, + { + "id": 33, + "type": { + "def": { + "composite": {} + }, + "params": [ + { + "name": "L", + "type": 11 + }, + { + "name": "R", + "type": 34 + } + ], + "path": [ + "ink_storage_traits", + "impls", + "ResolverKey" + ] + } + }, + { + "id": 34, + "type": { + "def": { + "composite": {} + }, + "params": [ + { + "name": "ParentKey", + "type": 13 + } + ], + "path": [ + "ink_storage_traits", + "impls", + "ManualKey" + ] + } + }, + { + "id": 35, "type": { "def": { "composite": { @@ -1865,9 +2084,14 @@ "type": 0, "typeName": ",>>::Type" }, + { + "name": "admin", + "type": 0, + "typeName": ",>>::Type" + }, { "name": "token", - "type": 32, + "type": 36, "typeName": ",>>::Type" }, { @@ -1886,8 +2110,13 @@ "typeName": " as::ink::storage::traits::\nAutoStorableHint<::ink::storage::traits::ManualKey<2050671336u32,\n()>,>>::Type" }, { - "name": "active_vault_auction", + "name": "auction_bidder_bids", "type": 21, + "typeName": " as::ink::storage::traits::\nAutoStorableHint<::ink::storage::traits::ManualKey<466279528u32, ()\n>,>>::Type" + }, + { + "name": "active_vault_auction", + "type": 25, "typeName": " as::ink::storage::traits::\nAutoStorableHint<::ink::storage::traits::ManualKey<3683492271u32,\n()>,>>::Type" }, { @@ -1897,12 +2126,12 @@ }, { "name": "active_auctions", - "type": 25, + "type": 29, "typeName": " as::ink::storage::traits::AutoStorableHint<::\nink::storage::traits::ManualKey<1154598105u32, ()>,>>::Type" }, { "name": "active_auction_indices", - "type": 28, + "type": 32, "typeName": " as::ink::storage::traits::AutoStorableHint<::\nink::storage::traits::ManualKey<531753200u32, ()>,>>::Type" } ] @@ -1916,14 +2145,14 @@ } }, { - "id": 32, + "id": 36, "type": { "def": { "composite": { "fields": [ { "name": "inner", - "type": 33, + "type": 37, "typeName": "::Type" } ] @@ -1937,7 +2166,7 @@ } }, { - "id": 33, + "id": 37, "type": { "def": { "composite": { @@ -1958,7 +2187,7 @@ } }, { - "id": 34, + "id": 38, "type": { "def": { "variant": { @@ -1975,7 +2204,7 @@ { "fields": [ { - "type": 35 + "type": 39 } ], "index": 1, @@ -1991,7 +2220,7 @@ }, { "name": "E", - "type": 35 + "type": 39 } ], "path": [ @@ -2000,7 +2229,7 @@ } }, { - "id": 35, + "id": 39, "type": { "def": { "variant": { @@ -2019,7 +2248,7 @@ } }, { - "id": 36, + "id": 40, "type": { "def": { "variant": { @@ -2052,7 +2281,7 @@ } }, { - "id": 37, + "id": 41, "type": { "def": { "variant": { @@ -2060,7 +2289,7 @@ { "fields": [ { - "type": 38 + "type": 42 } ], "index": 0, @@ -2069,7 +2298,7 @@ { "fields": [ { - "type": 35 + "type": 39 } ], "index": 1, @@ -2081,11 +2310,11 @@ "params": [ { "name": "T", - "type": 38 + "type": 42 }, { "name": "E", - "type": 35 + "type": 39 } ], "path": [ @@ -2094,7 +2323,7 @@ } }, { - "id": 38, + "id": 42, "type": { "def": { "variant": { @@ -2111,7 +2340,7 @@ { "fields": [ { - "type": 39 + "type": 43 } ], "index": 1, @@ -2127,7 +2356,7 @@ }, { "name": "E", - "type": 39 + "type": 43 } ], "path": [ @@ -2136,7 +2365,7 @@ } }, { - "id": 39, + "id": 43, "type": { "def": { "variant": { @@ -2147,58 +2376,66 @@ }, { "index": 1, - "name": "AuctionNotFound" + "name": "NotAdmin" }, { "index": 2, - "name": "BidNotFound" + "name": "AuctionNotFound" }, { "index": 3, - "name": "NotBidder" + "name": "BidNotFound" }, { "index": 4, - "name": "AuctionAlreadyExistsForVault" + "name": "NotBidder" }, { "index": 5, - "name": "BidBelowDebtBalance" + "name": "AuctionAlreadyExistsForVault" }, { "index": 6, - "name": "AuctionEnded" + "name": "BidBelowDebtBalance" }, { "index": 7, - "name": "AuctionNotEnded" + "name": "AuctionEnded" }, { "index": 8, - "name": "AuctionFinalized" + "name": "AuctionNotEnded" }, { "index": 9, - "name": "OutOfBoundPage" + "name": "AuctionFinalized" }, { "index": 10, - "name": "WinningBidLocked" + "name": "AuctionHasNoBids" }, { "index": 11, - "name": "InvalidDuration" + "name": "WinningBidLocked" }, { "index": 12, - "name": "TransferFailed" + "name": "InvalidDuration" }, { "index": 13, - "name": "NoRefundAvailable" + "name": "TransferFailed" }, { "index": 14, + "name": "NoRefundAvailable" + }, + { + "index": 15, + "name": "BidAmountNotIncreased" + }, + { + "index": 16, "name": "ArithmeticError" } ] @@ -2212,7 +2449,7 @@ } }, { - "id": 40, + "id": 44, "type": { "def": { "variant": { @@ -2220,7 +2457,7 @@ { "fields": [ { - "type": 41 + "type": 45 } ], "index": 0, @@ -2229,7 +2466,7 @@ { "fields": [ { - "type": 35 + "type": 39 } ], "index": 1, @@ -2241,11 +2478,11 @@ "params": [ { "name": "T", - "type": 41 + "type": 45 }, { "name": "E", - "type": 35 + "type": 39 } ], "path": [ @@ -2254,7 +2491,7 @@ } }, { - "id": 41, + "id": 45, "type": { "def": { "variant": { @@ -2271,7 +2508,7 @@ { "fields": [ { - "type": 39 + "type": 43 } ], "index": 1, @@ -2287,7 +2524,7 @@ }, { "name": "E", - "type": 39 + "type": 43 } ], "path": [ @@ -2296,7 +2533,7 @@ } }, { - "id": 42, + "id": 46, "type": { "def": { "variant": { @@ -2304,7 +2541,7 @@ { "fields": [ { - "type": 43 + "type": 47 } ], "index": 0, @@ -2313,7 +2550,7 @@ { "fields": [ { - "type": 35 + "type": 39 } ], "index": 1, @@ -2325,11 +2562,11 @@ "params": [ { "name": "T", - "type": 43 + "type": 47 }, { "name": "E", - "type": 35 + "type": 39 } ], "path": [ @@ -2338,7 +2575,7 @@ } }, { - "id": 43, + "id": 47, "type": { "def": { "variant": { @@ -2371,7 +2608,7 @@ } }, { - "id": 44, + "id": 48, "type": { "def": { "variant": { @@ -2388,7 +2625,7 @@ { "fields": [ { - "type": 35 + "type": 39 } ], "index": 1, @@ -2404,7 +2641,7 @@ }, { "name": "E", - "type": 35 + "type": 39 } ], "path": [ @@ -2413,7 +2650,7 @@ } }, { - "id": 45, + "id": 49, "type": { "def": { "variant": { @@ -2421,7 +2658,7 @@ { "fields": [ { - "type": 46 + "type": 50 } ], "index": 0, @@ -2430,7 +2667,7 @@ { "fields": [ { - "type": 35 + "type": 39 } ], "index": 1, @@ -2442,11 +2679,11 @@ "params": [ { "name": "T", - "type": 46 + "type": 50 }, { "name": "E", - "type": 35 + "type": 39 } ], "path": [ @@ -2455,7 +2692,7 @@ } }, { - "id": 46, + "id": 50, "type": { "def": { "variant": { @@ -2488,7 +2725,7 @@ } }, { - "id": 47, + "id": 51, "type": { "def": { "variant": { @@ -2496,7 +2733,7 @@ { "fields": [ { - "type": 48 + "type": 52 } ], "index": 0, @@ -2505,7 +2742,7 @@ { "fields": [ { - "type": 35 + "type": 39 } ], "index": 1, @@ -2517,11 +2754,11 @@ "params": [ { "name": "T", - "type": 48 + "type": 52 }, { "name": "E", - "type": 35 + "type": 39 } ], "path": [ @@ -2530,7 +2767,7 @@ } }, { - "id": 48, + "id": 52, "type": { "def": { "variant": { @@ -2538,7 +2775,7 @@ { "fields": [ { - "type": 49 + "type": 53 } ], "index": 0, @@ -2547,7 +2784,7 @@ { "fields": [ { - "type": 39 + "type": 43 } ], "index": 1, @@ -2559,11 +2796,11 @@ "params": [ { "name": "T", - "type": 49 + "type": 53 }, { "name": "E", - "type": 39 + "type": 43 } ], "path": [ @@ -2572,7 +2809,7 @@ } }, { - "id": 49, + "id": 53, "type": { "def": { "sequence": { @@ -2582,7 +2819,7 @@ } }, { - "id": 50, + "id": 54, "type": { "def": { "variant": { @@ -2599,7 +2836,7 @@ { "fields": [ { - "type": 35 + "type": 39 } ], "index": 1, @@ -2615,7 +2852,7 @@ }, { "name": "E", - "type": 35 + "type": 39 } ], "path": [ @@ -2624,7 +2861,7 @@ } }, { - "id": 51, + "id": 55, "type": { "def": { "variant": { @@ -2632,7 +2869,7 @@ { "fields": [ { - "type": 52 + "type": 56 } ], "index": 0, @@ -2641,7 +2878,7 @@ { "fields": [ { - "type": 35 + "type": 39 } ], "index": 1, @@ -2653,11 +2890,11 @@ "params": [ { "name": "T", - "type": 52 + "type": 56 }, { "name": "E", - "type": 35 + "type": 39 } ], "path": [ @@ -2666,7 +2903,7 @@ } }, { - "id": 52, + "id": 56, "type": { "def": { "variant": { @@ -2674,7 +2911,7 @@ { "fields": [ { - "type": 53 + "type": 57 } ], "index": 0, @@ -2683,7 +2920,7 @@ { "fields": [ { - "type": 39 + "type": 43 } ], "index": 1, @@ -2695,11 +2932,11 @@ "params": [ { "name": "T", - "type": 53 + "type": 57 }, { "name": "E", - "type": 39 + "type": 43 } ], "path": [ @@ -2708,7 +2945,7 @@ } }, { - "id": 53, + "id": 57, "type": { "def": { "sequence": { @@ -2718,7 +2955,7 @@ } }, { - "id": 54, + "id": 58, "type": { "def": { "variant": { @@ -2735,7 +2972,7 @@ { "fields": [ { - "type": 35 + "type": 39 } ], "index": 1, @@ -2751,7 +2988,7 @@ }, { "name": "E", - "type": 35 + "type": 39 } ], "path": [ @@ -2760,7 +2997,7 @@ } }, { - "id": 55, + "id": 59, "type": { "def": { "composite": { @@ -2780,7 +3017,7 @@ } }, { - "id": 56, + "id": 60, "type": { "def": { "variant": {} diff --git a/tensorusd/abis/tusdt_erc20.json b/tensorusd/abis/tusdt_erc20.json index d1bf793..a9a8c7a 100644 --- a/tensorusd/abis/tusdt_erc20.json +++ b/tensorusd/abis/tusdt_erc20.json @@ -1,6 +1,6 @@ { "source": { - "hash": "0xb1052e79867a05402777202989487461fbf05bd2ee5661727ca97ecd84fce37b", + "hash": "0xeead26f978b237d2ce4d3c7fa1016417651e247c87de79358080c426fe97a17a", "language": "ink! 5.1.1", "compiler": "rustc 1.93.0", "build_info": { @@ -36,7 +36,9 @@ } ], "default": false, - "docs": [], + "docs": [ + "Initializes the token contract with the specified owner account." + ], "label": "new", "payable": false, "returnType": { @@ -185,7 +187,9 @@ { "args": [], "default": false, - "docs": [], + "docs": [ + " Returns the owner account ID." + ], "label": "owner", "mutates": false, "payable": false, @@ -201,7 +205,9 @@ { "args": [], "default": false, - "docs": [], + "docs": [ + " Returns the total supply of tokens in circulation." + ], "label": "total_supply", "mutates": false, "payable": false, @@ -227,7 +233,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Returns the token balance of an account." + ], "label": "balance_of", "mutates": false, "payable": false, @@ -262,7 +270,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Returns the amount of tokens that a spender is allowed to transfer from an owner's account." + ], "label": "allowance", "mutates": false, "payable": false, @@ -297,7 +307,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Transfers tokens from the caller to a recipient account." + ], "label": "transfer", "mutates": true, "payable": false, @@ -332,7 +344,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Mints new tokens and adds them to an account's balance; only callable by owner." + ], "label": "mint", "mutates": true, "payable": false, @@ -367,7 +381,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Burns tokens from an account, reducing the total supply; only callable by owner." + ], "label": "burn", "mutates": true, "payable": false, @@ -402,7 +418,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Approves a spender to transfer up to a specified amount of tokens on behalf of the caller." + ], "label": "approve", "mutates": true, "payable": false, @@ -446,7 +464,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Transfers tokens on behalf of an owner account to a recipient, using the caller's allowance." + ], "label": "transfer_from", "mutates": true, "payable": false, diff --git a/tensorusd/abis/tusdt_vault.json b/tensorusd/abis/tusdt_vault.json index ef33a66..5f04e9e 100644 --- a/tensorusd/abis/tusdt_vault.json +++ b/tensorusd/abis/tusdt_vault.json @@ -1,6 +1,6 @@ { "source": { - "hash": "0xba36e326c46f9966fedd54cc4bedd8eb52ef09fbc4f5f209013f9ab33c1e08d3", + "hash": "0xf3a92706983fc3140d7172999a5ce93b37fa65c9ef71fef9022128336a1a849f", "language": "ink! 5.1.1", "compiler": "rustc 1.93.0", "build_info": { @@ -45,7 +45,9 @@ } ], "default": false, - "docs": [], + "docs": [ + "Initializes the vault contract by instantiating the token and auction contracts with the provided code hashes." + ], "label": "new", "payable": false, "returnType": { @@ -82,7 +84,7 @@ "displayName": [ "ChainExtension" ], - "type": 56 + "type": 58 }, "hash": { "displayName": [ @@ -264,9 +266,9 @@ "label": "winner", "type": { "displayName": [ - "Option" + "AccountId" ], - "type": 55 + "type": 0 } }, { @@ -279,12 +281,34 @@ ], "type": 3 } + }, + { + "docs": [], + "indexed": false, + "label": "debt_balance", + "type": { + "displayName": [ + "Balance" + ], + "type": 3 + } + }, + { + "docs": [], + "indexed": false, + "label": "highest_bid_metadata", + "type": { + "displayName": [ + "Option" + ], + "type": 55 + } } ], "docs": [], "label": "AuctionFinalized", "module_path": "tusdt_auction::auction", - "signature_topic": "0xecb6c55d94a9aac8b4e207a8cb763f4460b8e570530c936dff17a77a009fb26e" + "signature_topic": "0x2bb1b99d11a544c4702e6bb53e1eaea4a6f257ac8d2e41b9c747027662fadd53" }, { "args": [ @@ -337,7 +361,7 @@ "displayName": [ "Option" ], - "type": 55 + "type": 57 } }, { @@ -348,7 +372,7 @@ "displayName": [ "Option" ], - "type": 55 + "type": 57 } }, { @@ -616,7 +640,7 @@ "displayName": [ "Option" ], - "type": 55 + "type": 57 } }, { @@ -740,7 +764,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Updates contract parameters (collateral ratio, liquidation ratio, interest rate, etc.) with validation; only callable by owner." + ], "label": "set_contract_params", "mutates": true, "payable": false, @@ -756,7 +782,9 @@ { "args": [], "default": false, - "docs": [], + "docs": [ + " Creates a new vault for the caller with the transferred collateral and returns the vault ID." + ], "label": "create_vault", "mutates": true, "payable": true, @@ -782,7 +810,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Adds the transferred collateral amount to an existing vault." + ], "label": "add_collateral", "mutates": true, "payable": true, @@ -817,7 +847,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Borrows tokens against the vault's collateral, validating collateral ratio and accruing interest." + ], "label": "borrow_token", "mutates": true, "payable": false, @@ -852,7 +884,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Repays borrowed tokens from a vault, accruing interest and burning the repaid tokens." + ], "label": "repay_token", "mutates": true, "payable": false, @@ -887,7 +921,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Releases collateral from a vault while ensuring the remaining collateral maintains the minimum collateral ratio." + ], "label": "release_collateral", "mutates": true, "payable": false, @@ -922,7 +958,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Initiates a liquidation auction for an unsafe vault, returning the auction ID if successful." + ], "label": "trigger_liquidation_auction", "mutates": true, "payable": false, @@ -957,7 +995,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Settles a finalized liquidation auction, transferring collateral to the winner and clearing vault debt." + ], "label": "settle_liquidation_auction", "mutates": true, "payable": false, @@ -992,7 +1032,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Retrieves the vault details for a given owner and vault ID." + ], "label": "get_vault", "mutates": false, "payable": false, @@ -1008,7 +1050,9 @@ { "args": [], "default": false, - "docs": [], + "docs": [ + " Returns the account ID of the deployed ERC-20 token contract." + ], "label": "get_token_address", "mutates": false, "payable": false, @@ -1024,7 +1068,9 @@ { "args": [], "default": false, - "docs": [], + "docs": [ + " Returns the account ID of the deployed auction contract." + ], "label": "get_auction_address", "mutates": false, "payable": false, @@ -1040,7 +1086,9 @@ { "args": [], "default": false, - "docs": [], + "docs": [ + " Returns the current contract parameters (collateral ratio, liquidation ratio, interest rate, etc.) as percentages." + ], "label": "get_contract_params", "mutates": false, "payable": false, @@ -1066,7 +1114,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Sets the collateral-to-token price ratio for testing purposes; only callable by owner." + ], "label": "set_collateral_token_price_for_testing", "mutates": true, "payable": false, @@ -1082,7 +1132,9 @@ { "args": [], "default": false, - "docs": [], + "docs": [ + " Returns the current collateral-to-token price ratio used for calculations." + ], "label": "get_collateral_token_price_for_testing", "mutates": false, "payable": false, @@ -1117,7 +1169,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Returns the collateral balance for a vault, or None if the vault does not exist." + ], "label": "get_vault_collateral_balance", "mutates": false, "payable": false, @@ -1133,7 +1187,9 @@ { "args": [], "default": false, - "docs": [], + "docs": [ + " Returns the total collateral balance across all vaults." + ], "label": "get_total_collateral_balance", "mutates": false, "payable": false, @@ -1168,7 +1224,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Calculates the token value of a vault's collateral based on the current price ratio." + ], "label": "get_vault_collateral_value", "mutates": false, "payable": false, @@ -1203,7 +1261,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Returns the maximum token amount that can be borrowed against a vault's collateral." + ], "label": "get_max_borrow", "mutates": false, "payable": false, @@ -1238,7 +1298,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Returns the auction ID for an active liquidation of a vault, or None if there is no active liquidation." + ], "label": "get_liquidation_auction_id", "mutates": false, "payable": false, @@ -1254,7 +1316,9 @@ { "args": [], "default": false, - "docs": [], + "docs": [ + " Returns the total number of vaults created across all owners." + ], "label": "get_total_vaults_count", "mutates": false, "payable": false, @@ -1280,7 +1344,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Returns the number of vaults owned by a specific account." + ], "label": "get_vaults_count", "mutates": false, "payable": false, @@ -1315,7 +1381,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Returns a paginated list of vaults owned by a specific account." + ], "label": "get_vaults", "mutates": false, "payable": false, @@ -1341,7 +1409,9 @@ } ], "default": false, - "docs": [], + "docs": [ + " Returns a paginated list of all vaults across all owners." + ], "label": "get_all_vaults", "mutates": false, "payable": false, @@ -2609,58 +2679,54 @@ }, { "index": 5, - "name": "OutOfBoundPage" - }, - { - "index": 6, "name": "InvalidRatio" }, { - "index": 7, + "index": 6, "name": "InvalidAuctionDuration" }, { - "index": 8, + "index": 7, "name": "CollateralRatioExceeded" }, { - "index": 9, + "index": 8, "name": "LiquidationRatioExceeded" }, { - "index": 10, + "index": 9, "name": "RepayAmountTooHigh" }, { - "index": 11, + "index": 10, "name": "VaultInLiquidation" }, { - "index": 12, + "index": 11, "name": "NotLiquidatable" }, { - "index": 13, + "index": 12, "name": "LiquidationAuctionExists" }, { - "index": 14, + "index": 13, "name": "AuctionContractCallFailed" }, { - "index": 15, + "index": 14, "name": "AuctionNotFound" }, { - "index": 16, + "index": 15, "name": "AuctionNotFinalized" }, { - "index": 17, + "index": 16, "name": "ArithmeticError" }, { - "index": 18, + "index": 17, "name": "NotContractOwner" } ] @@ -3330,6 +3396,60 @@ }, { "id": 55, + "type": { + "def": { + "variant": { + "variants": [ + { + "index": 0, + "name": "None" + }, + { + "fields": [ + { + "type": 56 + } + ], + "index": 1, + "name": "Some" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 56 + } + ], + "path": [ + "Option" + ] + } + }, + { + "id": 56, + "type": { + "def": { + "composite": { + "fields": [ + { + "name": "hot_key", + "type": 0, + "typeName": "AccountId" + } + ] + } + }, + "path": [ + "tusdt_auction", + "auction", + "BidMetadata" + ] + } + }, + { + "id": 57, "type": { "def": { "variant": { @@ -3362,7 +3482,7 @@ } }, { - "id": 56, + "id": 58, "type": { "def": { "variant": {}