├── accounts.txt ├── proxy.txt ├── requirements.txt ├── README.md └── bot.py /accounts.txt: -------------------------------------------------------------------------------- 1 | your_private_key_1 2 | your_private_key_2 -------------------------------------------------------------------------------- /proxy.txt: -------------------------------------------------------------------------------- 1 | ip:port # Default Protcol HTTP. 2 | protocol://ip:port 3 | protocol://user:pass@ip:port -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | web3==7.11.1 2 | aiohttp==3.11.10 3 | aiohttp-socks==0.9.1 4 | eth-account==0.13.7 5 | colorama==0.4.6 6 | pytz==2024.1 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenFi BOT 2 | OpenFi BOT 3 | 4 | - Register Here : [OpenFi](https://app.open-fi.xyz/) 5 | - Connect Same Wallet With Pharos 6 | 7 | ## Features 8 | 9 | - Auto Get Account Information 10 | - Auto Run With Private Proxy - `Choose 1` 11 | - Auto Run Without Proxy - `Choose 2` 12 | - Auto Mint Faucets 13 | - Auto Deposit PHRS 14 | - Auto Supply Assets 15 | - Auto Borrow Assets 16 | - Auto Repay Assets 17 | - Auto Withdraw Assets 18 | - Multi Accounts 19 | 20 | ## Requiremnets 21 | 22 | - Make sure you have Python3.9 or higher installed and pip. 23 | 24 | ## Instalation 25 | 26 | 1. **Clone The Repositories:** 27 | ```bash 28 | git clone https://github.com/vonssy/OpenFi-BOT.git 29 | ``` 30 | ```bash 31 | cd OpenFi-BOT 32 | ``` 33 | 34 | 2. **Install Requirements:** 35 | ```bash 36 | pip install -r requirements.txt #or pip3 install -r requirements.txt 37 | ``` 38 | 39 | ### Note: Check your web3 and eth-account libraries version first. If not same with version in requirements.txt, u must uninstall that library. 40 | - **Check Library Version** 41 | ```bash 42 | pip show libary_name 43 | ``` 44 | - **Uninstall Library** 45 | ```bash 46 | pip uninstall libary_name 47 | ``` 48 | - **Install Library With Version** 49 | ```bash 50 | pip install libary_name==version 51 | ``` 52 | 53 | ## Configuration 54 | 55 | - **accounts.txt:** You will find the file `accounts.txt` inside the project directory. Make sure `accounts.txt` contains data that matches the format expected by the script. Here are examples of file formats: 56 | ```bash 57 | your_private_key_1 58 | your_private_key_2 59 | ``` 60 | 61 | - **proxy.txt:** You will find the file `proxy.txt` inside the project directory. Make sure `proxy.txt` contains data that matches the format expected by the script. Here are examples of file formats: 62 | ```bash 63 | ip:port # Default Protcol HTTP. 64 | protocol://ip:port 65 | protocol://user:pass@ip:port 66 | ``` 67 | 68 | ## Run 69 | 70 | ```bash 71 | python bot.py #or python3 bot.py 72 | ``` 73 | 74 | ## Buy Me a Coffee 75 | 76 | - **EVM:** 0xe3c9ef9a39e9eb0582e5b147026cae524338521a 77 | - **TON:** UQBEFv58DC4FUrGqinBB5PAQS7TzXSm5c1Fn6nkiet8kmehB 78 | - **SOL:** E1xkaJYmAFEj28NPHKhjbf7GcvfdjKdvXju8d8AeSunf 79 | - **SUI:** 0xa03726ecbbe00b31df6a61d7a59d02a7eedc39fe269532ceab97852a04cf3347 80 | 81 | Thank you for visiting this repository, don't forget to contribute in the form of follows and stars. 82 | If you have questions, find an issue, or have suggestions for improvement, feel free to contact me or open an *issue* in this GitHub repository. 83 | 84 | **vonssy** -------------------------------------------------------------------------------- /bot.py: -------------------------------------------------------------------------------- 1 | from web3 import Web3 2 | from web3.exceptions import TransactionNotFound 3 | from eth_account import Account 4 | from aiohttp import ClientResponseError, ClientSession, ClientTimeout, BasicAuth 5 | from aiohttp_socks import ProxyConnector 6 | from datetime import datetime 7 | from colorama import * 8 | import asyncio, random, json, re, os, pytz 9 | 10 | wib = pytz.timezone('Asia/Jakarta') 11 | 12 | class OpenFi: 13 | def __init__(self) -> None: 14 | # self.RPC_URL = "https://testnet.dplabs-internal.com/" 15 | self.RPC_URL = "https://api.zan.top/node/v1/pharos/testnet/1c23cdaa41f34fd2a74fc375d2400c47" 16 | self.PHRS_CONTRACT_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" 17 | self.WPHRS_CONTRACT_ADDRESS = "0x3019B247381c850ab53Dc0EE53bCe7A07Ea9155f" 18 | self.USDC_CONTRACT_ADDRESS = "0x72df0bcd7276f2dFbAc900D1CE63c272C4BCcCED" 19 | self.USDT_CONTRACT_ADDRESS = "0xD4071393f8716661958F766DF660033b3d35fD29" 20 | self.WETH_CONTRACT_ADDRESS = "0x4E28826d32F1C398DED160DC16Ac6873357d048f" 21 | self.WBTC_CONTRACT_ADDRESS = "0x8275c526d1bCEc59a31d673929d3cE8d108fF5c7" 22 | self.GOLD_CONTRACT_ADDRESS = "0xAaf03Cbb486201099EdD0a52E03Def18cd0c7354" 23 | self.TSLA_CONTRACT_ADDRESS = "0xA778b48339d3c6b4Bc5a75B37c6Ce210797076b1" 24 | self.NVIDIA_CONTRACT_ADDRESS = "0xAaF3A7F1676385883593d7Ea7ea4FcCc675EE5d6" 25 | self.FAUCET_ROUTER_ADDRESS = "0x0E29d74Af0489f4B08fBfc774e25C0D3b5f43285" 26 | self.WRAPPED_ROUTER_ADDRESS = "0x974828e18bff1E71780f9bE19d0DFf4Fe1f61fCa" 27 | self.POOL_ROUTER_ADDRESS = "0x11d1ca4012d94846962bca2FBD58e5A27ddcBfC5" 28 | self.POOL_PROVIDER_ADDRESS = "0x54cb4f6C4c12105B48b11e21d78becC32Ef694EC" 29 | self.LENDING_POOL_ADDRESS = "0x0000000000000000000000000000000000000000" 30 | self.ERC20_CONTRACT_ABI = json.loads('''[ 31 | {"type":"function","name":"balanceOf","stateMutability":"view","inputs":[{"name":"address","type":"address"}],"outputs":[{"name":"","type":"uint256"}]}, 32 | {"type":"function","name":"allowance","stateMutability":"view","inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"outputs":[{"name":"","type":"uint256"}]}, 33 | {"type":"function","name":"approve","stateMutability":"nonpayable","inputs":[{"name":"spender","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]}, 34 | {"type":"function","name":"decimals","stateMutability":"view","inputs":[],"outputs":[{"name":"","type":"uint8"}]} 35 | ]''') 36 | self.OPENFI_CONTRACT_ABI = [ 37 | { 38 | "type": "function", 39 | "name": "isMintable", 40 | "stateMutability": "view", 41 | "inputs": [ 42 | { "internalType": "address", "name": "asset", "type": "address" } 43 | ], 44 | "outputs": [ 45 | { "internalType": "bool", "name": "", "type": "bool" } 46 | ] 47 | }, 48 | { 49 | "type": "function", 50 | "name": "getUserReserveData", 51 | "stateMutability": "view", 52 | "inputs": [ 53 | { "internalType": "address", "name": "asset", "type": "address" }, 54 | { "internalType": "address", "name": "user", "type": "address" } 55 | ], 56 | "outputs": [ 57 | { "internalType": "uint256", "name": "currentBTokenBalance", "type": "uint256" }, 58 | { "internalType": "uint256", "name": "currentStableDebt", "type": "uint256" }, 59 | { "internalType": "uint256", "name": "currentVariableDebt", "type": "uint256" }, 60 | { "internalType": "uint256", "name": "principalStableDebt", "type": "uint256" }, 61 | { "internalType": "uint256", "name": "scaledVariableDebt", "type": "uint256" }, 62 | { "internalType": "uint256", "name": "stableBorrowRate", "type": "uint256" }, 63 | { "internalType": "uint256", "name": "liquidityRate", "type": "uint256" }, 64 | { "internalType": "uint40", "name": "stableRateLastUpdated", "type": "uint40" }, 65 | { "internalType": "bool", "name": "usageAsCollateralEnabled", "type": "bool" } 66 | ] 67 | }, 68 | { 69 | "type": "function", 70 | "name": "getReserveConfigurationData", 71 | "stateMutability": "view", 72 | "inputs": [ 73 | { "internalType": "address", "name": "asset", "type": "address" } 74 | ], 75 | "outputs": [ 76 | { "internalType": "uint256", "name": "decimals", "type": "uint256" }, 77 | { "internalType": "uint256", "name": "ltv", "type": "uint256" }, 78 | { "internalType": "uint256", "name": "liquidationThreshold", "type": "uint256" }, 79 | { "internalType": "uint256", "name": "liquidationBonus", "type": "uint256" }, 80 | { "internalType": "uint256", "name": "reserveFactor", "type": "uint256" }, 81 | { "internalType": "bool", "name": "usageAsCollateralEnabled", "type": "bool" }, 82 | { "internalType": "bool", "name": "borrowingEnabled", "type": "bool" }, 83 | { "internalType": "bool", "name": "stableBorrowRateEnabled", "type": "bool" }, 84 | { "internalType": "bool", "name": "isActive", "type": "bool" }, 85 | { "internalType": "bool", "name": "isFrozen", "type": "bool" } 86 | ] 87 | }, 88 | { 89 | "type": "function", 90 | "name": "getReserveData", 91 | "stateMutability": "view", 92 | "inputs": [ 93 | { "internalType": "address", "name": "asset", "type": "address" } 94 | ], 95 | "outputs": [ 96 | { "internalType": "uint256", "name": "unbacked", "type": "uint256" }, 97 | { "internalType": "uint256", "name": "accruedToTreasuryScaled", "type": "uint256" }, 98 | { "internalType": "uint256", "name": "totalBToken", "type": "uint256" }, 99 | { "internalType": "uint256", "name": "totalStableDebt", "type": "uint256" }, 100 | { "internalType": "uint256", "name": "totalVariableDebt", "type": "uint256" }, 101 | { "internalType": "uint256", "name": "liquidityRate", "type": "uint256" }, 102 | { "internalType": "uint256", "name": "variableBorrowRate", "type": "uint256" }, 103 | { "internalType": "uint256", "name": "stableBorrowRate", "type": "uint256" }, 104 | { "internalType": "uint256", "name": "averageStableBorrowRate", "type": "uint256" }, 105 | { "internalType": "uint256", "name": "liquidityIndex", "type": "uint256" }, 106 | { "internalType": "uint256", "name": "variableBorrowIndex", "type": "uint256" }, 107 | { "internalType": "uint40", "name": "lastUpdateTimestamp", "type": "uint40" } 108 | ] 109 | }, 110 | { 111 | "type": "function", 112 | "name": "mint", 113 | "stateMutability": "nonpayable", 114 | "inputs": [ 115 | { "internalType": "address", "name": "token", "type": "address" }, 116 | { "internalType": "address", "name": "to", "type": "address" }, 117 | { "internalType": "uint256", "name": "amount", "type": "uint256" } 118 | ], 119 | "outputs": [ 120 | { "internalType": "uint256", "name": "", "type": "uint256" } 121 | ] 122 | }, 123 | { 124 | "type": "function", 125 | "name": "depositETH", 126 | "stateMutability": "payable", 127 | "inputs": [ 128 | { "internalType": "address", "name": "", "type": "address" }, 129 | { "internalType": "address", "name": "onBehalfOf", "type": "address" }, 130 | { "internalType": "uint16", "name": "referralCode", "type": "uint16" } 131 | ], 132 | "outputs": [] 133 | }, 134 | { 135 | "type": "function", 136 | "name": "supply", 137 | "stateMutability": "nonpayable", 138 | "inputs": [ 139 | { "internalType": "address", "name": "asset", "type": "address" }, 140 | { "internalType": "uint256", "name": "amount", "type": "uint256" }, 141 | { "internalType": "address", "name": "onBehalfOf", "type": "address" }, 142 | { "internalType": "uint16", "name": "referralCode", "type": "uint16" } 143 | ], 144 | "outputs": [] 145 | }, 146 | { 147 | "type": "function", 148 | "name": "borrow", 149 | "stateMutability": "nonpayable", 150 | "inputs": [ 151 | { "internalType": "address", "name": "asset", "type": "address" }, 152 | { "internalType": "uint256", "name": "amount", "type": "uint256" }, 153 | { "internalType": "uint256", "name": "interestRateMode", "type": "uint256" }, 154 | { "internalType": "uint16", "name": "referralCode", "type": "uint16" }, 155 | { "internalType": "address", "name": "onBehalfOf", "type": "address" } 156 | ], 157 | "outputs": [] 158 | }, 159 | { 160 | "type": "function", 161 | "name": "repay", 162 | "stateMutability": "nonpayable", 163 | "inputs": [ 164 | { "internalType": "address", "name": "asset", "type": "address" }, 165 | { "internalType": "uint256", "name": "amount", "type": "uint256" }, 166 | { "internalType": "uint256", "name": "interestRateMode", "type": "uint256" }, 167 | { "internalType": "address", "name": "onBehalfOf", "type": "address" } 168 | ], 169 | "outputs": [ 170 | { "internalType": "uint256", "name": "", "type": "uint256" } 171 | ] 172 | }, 173 | { 174 | "type": "function", 175 | "name": "withdraw", 176 | "stateMutability": "nonpayable", 177 | "inputs": [ 178 | { "internalType": "address", "name": "asset", "type": "address" }, 179 | { "internalType": "uint256", "name": "amount", "type": "uint256" }, 180 | { "internalType": "address", "name": "to", "type": "address" } 181 | ], 182 | "outputs": [ 183 | { "internalType": "uint256", "name": "", "type": "uint256" } 184 | ] 185 | } 186 | ] 187 | self.proxies = [] 188 | self.proxy_index = 0 189 | self.account_proxies = {} 190 | self.used_nonce = {} 191 | self.deposit_count = 0 192 | self.deposit_amount = 0 193 | self.supply_count = 0 194 | self.supply_amount = 0 195 | self.borrow_count = 0 196 | self.borrow_amount = 0 197 | self.repay_count = 0 198 | self.repay_amount = 0 199 | self.withdraw_count = 0 200 | self.withdraw_amount = 0 201 | self.min_delay = 0 202 | self.max_delay = 0 203 | 204 | def clear_terminal(self): 205 | os.system('cls' if os.name == 'nt' else 'clear') 206 | 207 | def log(self, message): 208 | print( 209 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}" 210 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}{message}", 211 | flush=True 212 | ) 213 | 214 | def welcome(self): 215 | print( 216 | f""" 217 | {Fore.GREEN + Style.BRIGHT}OpenFi {Fore.BLUE + Style.BRIGHT}Auto BOT 218 | """ 219 | f""" 220 | {Fore.GREEN + Style.BRIGHT}Rey? {Fore.YELLOW + Style.BRIGHT} 221 | """ 222 | ) 223 | 224 | def format_seconds(self, seconds): 225 | hours, remainder = divmod(seconds, 3600) 226 | minutes, seconds = divmod(remainder, 60) 227 | return f"{int(hours):02}:{int(minutes):02}:{int(seconds):02}" 228 | 229 | async def load_proxies(self): 230 | filename = "proxy.txt" 231 | try: 232 | if not os.path.exists(filename): 233 | self.log(f"{Fore.RED + Style.BRIGHT}File {filename} Not Found.{Style.RESET_ALL}") 234 | return 235 | with open(filename, 'r') as f: 236 | self.proxies = [line.strip() for line in f.read().splitlines() if line.strip()] 237 | 238 | if not self.proxies: 239 | self.log(f"{Fore.RED + Style.BRIGHT}No Proxies Found.{Style.RESET_ALL}") 240 | return 241 | 242 | self.log( 243 | f"{Fore.GREEN + Style.BRIGHT}Proxies Total : {Style.RESET_ALL}" 244 | f"{Fore.WHITE + Style.BRIGHT}{len(self.proxies)}{Style.RESET_ALL}" 245 | ) 246 | 247 | except Exception as e: 248 | self.log(f"{Fore.RED + Style.BRIGHT}Failed To Load Proxies: {e}{Style.RESET_ALL}") 249 | self.proxies = [] 250 | 251 | def check_proxy_schemes(self, proxies): 252 | schemes = ["http://", "https://", "socks4://", "socks5://"] 253 | if any(proxies.startswith(scheme) for scheme in schemes): 254 | return proxies 255 | return f"http://{proxies}" 256 | 257 | def get_next_proxy_for_account(self, account): 258 | if account not in self.account_proxies: 259 | if not self.proxies: 260 | return None 261 | proxy = self.check_proxy_schemes(self.proxies[self.proxy_index]) 262 | self.account_proxies[account] = proxy 263 | self.proxy_index = (self.proxy_index + 1) % len(self.proxies) 264 | return self.account_proxies[account] 265 | 266 | def rotate_proxy_for_account(self, account): 267 | if not self.proxies: 268 | return None 269 | proxy = self.check_proxy_schemes(self.proxies[self.proxy_index]) 270 | self.account_proxies[account] = proxy 271 | self.proxy_index = (self.proxy_index + 1) % len(self.proxies) 272 | return proxy 273 | 274 | def build_proxy_config(self, proxy=None): 275 | if not proxy: 276 | return None, None, None 277 | 278 | if proxy.startswith("socks"): 279 | connector = ProxyConnector.from_url(proxy) 280 | return connector, None, None 281 | 282 | elif proxy.startswith("http"): 283 | match = re.match(r"http://(.*?):(.*?)@(.*)", proxy) 284 | if match: 285 | username, password, host_port = match.groups() 286 | clean_url = f"http://{host_port}" 287 | auth = BasicAuth(username, password) 288 | return None, clean_url, auth 289 | else: 290 | return None, proxy, None 291 | 292 | raise Exception("Unsupported Proxy Type.") 293 | 294 | def generate_address(self, account: str): 295 | try: 296 | account = Account.from_key(account) 297 | address = account.address 298 | 299 | return address 300 | except Exception as e: 301 | self.log( 302 | f"{Fore.CYAN+Style.BRIGHT}Status :{Style.RESET_ALL}" 303 | f"{Fore.RED+Style.BRIGHT} Generate Address Failed {Style.RESET_ALL}" 304 | f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}" 305 | f"{Fore.YELLOW+Style.BRIGHT} {str(e)} {Style.RESET_ALL} " 306 | ) 307 | return None 308 | 309 | def mask_account(self, account): 310 | try: 311 | mask_account = account[:6] + '*' * 6 + account[-6:] 312 | return mask_account 313 | except Exception as e: 314 | return None 315 | 316 | def generate_random_option(self): 317 | assets = [ 318 | ("WPHRS", self.WPHRS_CONTRACT_ADDRESS, 18), 319 | ("USDC", self.USDC_CONTRACT_ADDRESS, 6), 320 | ("USDT", self.USDT_CONTRACT_ADDRESS, 6), 321 | ("WETH", self.WETH_CONTRACT_ADDRESS, 18), 322 | ("WBTC", self.WBTC_CONTRACT_ADDRESS, 8), 323 | ("GOLD", self.GOLD_CONTRACT_ADDRESS, 18), 324 | ("TSLA", self.TSLA_CONTRACT_ADDRESS, 18), 325 | ("NVIDIA", self.NVIDIA_CONTRACT_ADDRESS, 18) 326 | ] 327 | 328 | ticker, asset_address, decimals = random.choice(assets) 329 | 330 | return ticker, asset_address, decimals 331 | 332 | async def get_web3_with_check(self, address: str, use_proxy: bool, retries=3, timeout=60): 333 | request_kwargs = {"timeout": timeout} 334 | 335 | proxy = self.get_next_proxy_for_account(address) if use_proxy else None 336 | 337 | if use_proxy and proxy: 338 | request_kwargs["proxies"] = {"http": proxy, "https": proxy} 339 | 340 | for attempt in range(retries): 341 | try: 342 | web3 = Web3(Web3.HTTPProvider(self.RPC_URL, request_kwargs=request_kwargs)) 343 | web3.eth.get_block_number() 344 | return web3 345 | except Exception as e: 346 | if attempt < retries - 1: 347 | await asyncio.sleep(3) 348 | continue 349 | raise Exception(f"Failed to Connect to RPC: {str(e)}") 350 | 351 | async def get_token_balance(self, address: str, contract_address: str, use_proxy: bool): 352 | try: 353 | web3 = await self.get_web3_with_check(address, use_proxy) 354 | 355 | if contract_address == self.PHRS_CONTRACT_ADDRESS: 356 | balance = web3.eth.get_balance(address) 357 | decimals = 18 358 | else: 359 | token_contract = web3.eth.contract(address=web3.to_checksum_address(contract_address), abi=self.ERC20_CONTRACT_ABI) 360 | balance = token_contract.functions.balanceOf(address).call() 361 | decimals = token_contract.functions.decimals().call() 362 | 363 | token_balance = balance / (10 ** decimals) 364 | 365 | return token_balance 366 | except Exception as e: 367 | self.log( 368 | f"{Fore.CYAN+Style.BRIGHT} Message :{Style.RESET_ALL}" 369 | f"{Fore.RED+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 370 | ) 371 | return None 372 | 373 | async def send_raw_transaction_with_retries(self, account, web3, tx, retries=5): 374 | for attempt in range(retries): 375 | try: 376 | signed_tx = web3.eth.account.sign_transaction(tx, account) 377 | raw_tx = web3.eth.send_raw_transaction(signed_tx.raw_transaction) 378 | tx_hash = web3.to_hex(raw_tx) 379 | return tx_hash 380 | except TransactionNotFound: 381 | pass 382 | except Exception as e: 383 | self.log( 384 | f"{Fore.CYAN + Style.BRIGHT} Message :{Style.RESET_ALL}" 385 | f"{Fore.YELLOW + Style.BRIGHT} [Attempt {attempt + 1}] Send TX Error: {str(e)} {Style.RESET_ALL}" 386 | ) 387 | await asyncio.sleep(2 ** attempt) 388 | raise Exception("Transaction Hash Not Found After Maximum Retries") 389 | 390 | async def wait_for_receipt_with_retries(self, web3, tx_hash, retries=5): 391 | for attempt in range(retries): 392 | try: 393 | receipt = await asyncio.to_thread(web3.eth.wait_for_transaction_receipt, tx_hash, timeout=300) 394 | return receipt 395 | except TransactionNotFound: 396 | pass 397 | except Exception as e: 398 | self.log( 399 | f"{Fore.CYAN + Style.BRIGHT} Message :{Style.RESET_ALL}" 400 | f"{Fore.YELLOW + Style.BRIGHT} [Attempt {attempt + 1}] Wait for Receipt Error: {str(e)} {Style.RESET_ALL}" 401 | ) 402 | await asyncio.sleep(2 ** attempt) 403 | raise Exception("Transaction Receipt Not Found After Maximum Retries") 404 | 405 | async def check_faucet_status(self, address: str, asset_address, use_proxy: bool): 406 | try: 407 | web3 = await self.get_web3_with_check(address, use_proxy) 408 | 409 | contract_address = web3.to_checksum_address(self.FAUCET_ROUTER_ADDRESS) 410 | token_contract = web3.eth.contract(address=contract_address, abi=self.OPENFI_CONTRACT_ABI) 411 | is_mintable = token_contract.functions.isMintable(web3.to_checksum_address(asset_address)).call() 412 | 413 | return is_mintable 414 | except Exception as e: 415 | self.log( 416 | f"{Fore.CYAN+Style.BRIGHT} Message :{Style.RESET_ALL}" 417 | f"{Fore.RED+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 418 | ) 419 | return None 420 | 421 | async def get_supplied_balance(self, address: str, asset_address, decimals: int, use_proxy: bool): 422 | try: 423 | web3 = await self.get_web3_with_check(address, use_proxy) 424 | 425 | asset = web3.to_checksum_address(asset_address) 426 | 427 | contract_address = web3.to_checksum_address(self.POOL_PROVIDER_ADDRESS) 428 | token_contract = web3.eth.contract(address=contract_address, abi=self.OPENFI_CONTRACT_ABI) 429 | user_reserve_data = token_contract.functions.getUserReserveData(asset, address).call() 430 | 431 | supplied_balance = user_reserve_data[0] / (10 ** decimals) 432 | 433 | return supplied_balance 434 | except Exception as e: 435 | self.log( 436 | f"{Fore.CYAN+Style.BRIGHT} Message :{Style.RESET_ALL}" 437 | f"{Fore.RED+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 438 | ) 439 | return None 440 | 441 | async def get_borrowed_balance(self, address: str, asset_address, decimals: int, use_proxy: bool): 442 | try: 443 | web3 = await self.get_web3_with_check(address, use_proxy) 444 | 445 | asset = web3.to_checksum_address(asset_address) 446 | 447 | contract_address = web3.to_checksum_address(self.POOL_PROVIDER_ADDRESS) 448 | token_contract = web3.eth.contract(address=contract_address, abi=self.OPENFI_CONTRACT_ABI) 449 | user_reserve_data = token_contract.functions.getUserReserveData(asset, address).call() 450 | 451 | stable_debt = user_reserve_data[1] 452 | variable_debt = user_reserve_data[2] 453 | 454 | total_debt = (stable_debt + variable_debt) / (10 ** decimals) 455 | 456 | return total_debt 457 | except Exception as e: 458 | self.log( 459 | f"{Fore.CYAN+Style.BRIGHT} Message :{Style.RESET_ALL}" 460 | f"{Fore.RED+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 461 | ) 462 | return None 463 | 464 | async def get_available_borrowed_balance(self, address: str, asset_address, decimals: int, use_proxy: bool): 465 | try: 466 | web3 = await self.get_web3_with_check(address, use_proxy) 467 | 468 | asset = web3.to_checksum_address(asset_address) 469 | 470 | contract_address = web3.to_checksum_address(self.POOL_PROVIDER_ADDRESS) 471 | token_contract = web3.eth.contract(address=contract_address, abi=self.OPENFI_CONTRACT_ABI) 472 | 473 | user_reserve_data = token_contract.functions.getUserReserveData(asset, address).call() 474 | supplied_balance = user_reserve_data[0] 475 | stable_debt = user_reserve_data[1] 476 | variable_debt = user_reserve_data[2] 477 | 478 | configuration_data = token_contract.functions.getReserveConfigurationData(asset).call() 479 | ltv = configuration_data[1] 480 | 481 | reserve_data = token_contract.functions.getReserveData(asset).call() 482 | total_token = reserve_data[2] 483 | total_stable_debt = reserve_data[3] 484 | total_variable_debt = reserve_data[4] 485 | 486 | available_liquidity = total_token - (total_stable_debt + total_variable_debt) 487 | 488 | total_debt = stable_debt + variable_debt 489 | max_borrow_from_collateral = (supplied_balance * ltv) // 10000 490 | available_to_borrow = max_borrow_from_collateral - total_debt 491 | if available_to_borrow < 0: 492 | available_to_borrow = 0 493 | 494 | available_to_borrow = min(available_to_borrow, available_liquidity) / (10 ** decimals) 495 | 496 | return available_to_borrow 497 | except Exception as e: 498 | self.log( 499 | f"{Fore.CYAN+Style.BRIGHT} Message :{Style.RESET_ALL}" 500 | f"{Fore.RED+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 501 | ) 502 | return None 503 | 504 | async def mint_faucet(self, account: str, address: str, asset_address: str, use_proxy: bool): 505 | try: 506 | web3 = await self.get_web3_with_check(address, use_proxy) 507 | 508 | router_address = web3.to_checksum_address(self.FAUCET_ROUTER_ADDRESS) 509 | router_contract = web3.eth.contract(address=router_address, abi=self.OPENFI_CONTRACT_ABI) 510 | 511 | asset_address = web3.to_checksum_address(asset_address) 512 | asset_contract = web3.eth.contract(address=asset_address, abi=self.ERC20_CONTRACT_ABI) 513 | 514 | decimals = asset_contract.functions.decimals().call() 515 | 516 | amount_to_wei = int(100 * (10 ** decimals)) 517 | mint_data = router_contract.functions.mint(asset_address, address, amount_to_wei) 518 | estimated_gas = mint_data.estimate_gas({"from": address}) 519 | 520 | max_priority_fee = web3.to_wei(1, "gwei") 521 | max_fee = max_priority_fee 522 | 523 | mint_tx = mint_data.build_transaction({ 524 | "from": address, 525 | "gas": int(estimated_gas * 1.2), 526 | "maxFeePerGas": int(max_fee), 527 | "maxPriorityFeePerGas": int(max_priority_fee), 528 | "nonce": self.used_nonce[address], 529 | "chainId": web3.eth.chain_id, 530 | }) 531 | 532 | tx_hash = await self.send_raw_transaction_with_retries(account, web3, mint_tx) 533 | receipt = await self.wait_for_receipt_with_retries(web3, tx_hash) 534 | 535 | block_number = receipt.blockNumber 536 | self.used_nonce[address] += 1 537 | 538 | return tx_hash, block_number 539 | except Exception as e: 540 | self.log( 541 | f"{Fore.CYAN+Style.BRIGHT} Message :{Style.RESET_ALL}" 542 | f"{Fore.RED+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 543 | ) 544 | return None, None 545 | 546 | async def perform_deposit(self, account: str, address: str, amount: float, use_proxy: bool): 547 | try: 548 | web3 = await self.get_web3_with_check(address, use_proxy) 549 | 550 | amount_to_wei = web3.to_wei(amount, "ether") 551 | 552 | router_address = web3.to_checksum_address(self.WRAPPED_ROUTER_ADDRESS) 553 | router_contract = web3.eth.contract(address=router_address, abi=self.OPENFI_CONTRACT_ABI) 554 | 555 | deposit_data = router_contract.functions.depositETH(self.LENDING_POOL_ADDRESS, address, 0) 556 | estimated_gas = deposit_data.estimate_gas({"from": address, "value": amount_to_wei}) 557 | 558 | max_priority_fee = web3.to_wei(1, "gwei") 559 | max_fee = max_priority_fee 560 | 561 | deposit_tx = deposit_data.build_transaction({ 562 | "from": address, 563 | "value": amount_to_wei, 564 | "gas": int(estimated_gas * 1.2), 565 | "maxFeePerGas": int(max_fee), 566 | "maxPriorityFeePerGas": int(max_priority_fee), 567 | "nonce": self.used_nonce[address], 568 | "chainId": web3.eth.chain_id, 569 | }) 570 | 571 | tx_hash = await self.send_raw_transaction_with_retries(account, web3, deposit_tx) 572 | receipt = await self.wait_for_receipt_with_retries(web3, tx_hash) 573 | 574 | block_number = receipt.blockNumber 575 | self.used_nonce[address] += 1 576 | 577 | return tx_hash, block_number 578 | except Exception as e: 579 | self.log( 580 | f"{Fore.CYAN+Style.BRIGHT} Message :{Style.RESET_ALL}" 581 | f"{Fore.RED+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 582 | ) 583 | return None, None 584 | 585 | async def approving_token(self, account: str, address: str, router_address: str, asset_address: str, amount: float, use_proxy: bool): 586 | try: 587 | web3 = await self.get_web3_with_check(address, use_proxy) 588 | 589 | spender = web3.to_checksum_address(router_address) 590 | token_contract = web3.eth.contract(address=web3.to_checksum_address(asset_address), abi=self.ERC20_CONTRACT_ABI) 591 | decimals = token_contract.functions.decimals().call() 592 | 593 | amount_to_wei = int(amount * (10 ** decimals)) 594 | 595 | allowance = token_contract.functions.allowance(address, spender).call() 596 | if allowance < amount_to_wei: 597 | approve_data = token_contract.functions.approve(spender, 2**256 - 1) 598 | estimated_gas = approve_data.estimate_gas({"from": address}) 599 | 600 | max_priority_fee = web3.to_wei(1, "gwei") 601 | max_fee = max_priority_fee 602 | 603 | approve_tx = approve_data.build_transaction({ 604 | "from": address, 605 | "gas": int(estimated_gas * 1.2), 606 | "maxFeePerGas": int(max_fee), 607 | "maxPriorityFeePerGas": int(max_priority_fee), 608 | "nonce": self.used_nonce[address], 609 | "chainId": web3.eth.chain_id, 610 | }) 611 | 612 | tx_hash = await self.send_raw_transaction_with_retries(account, web3, approve_tx) 613 | receipt = await self.wait_for_receipt_with_retries(web3, tx_hash) 614 | 615 | block_number = receipt.blockNumber 616 | self.used_nonce[address] += 1 617 | 618 | explorer = f"https://testnet.pharosscan.xyz/tx/{tx_hash}" 619 | 620 | self.log( 621 | f"{Fore.CYAN+Style.BRIGHT} Approve :{Style.RESET_ALL}" 622 | f"{Fore.GREEN+Style.BRIGHT} Success {Style.RESET_ALL} " 623 | ) 624 | self.log( 625 | f"{Fore.CYAN+Style.BRIGHT} Block :{Style.RESET_ALL}" 626 | f"{Fore.WHITE+Style.BRIGHT} {block_number} {Style.RESET_ALL}" 627 | ) 628 | self.log( 629 | f"{Fore.CYAN+Style.BRIGHT} Tx Hash :{Style.RESET_ALL}" 630 | f"{Fore.WHITE+Style.BRIGHT} {tx_hash} {Style.RESET_ALL}" 631 | ) 632 | self.log( 633 | f"{Fore.CYAN+Style.BRIGHT} Explorer :{Style.RESET_ALL}" 634 | f"{Fore.WHITE+Style.BRIGHT} {explorer} {Style.RESET_ALL}" 635 | ) 636 | await self.print_timer() 637 | 638 | return True 639 | except Exception as e: 640 | raise Exception(f"Approving Token Contract Failed: {str(e)}") 641 | 642 | async def perform_supply(self, account: str, address: str, asset_address: str, supply_amount: float, use_proxy: bool): 643 | try: 644 | web3 = await self.get_web3_with_check(address, use_proxy) 645 | 646 | await self.approving_token(account, address, self.POOL_ROUTER_ADDRESS, asset_address, supply_amount, use_proxy) 647 | 648 | router_address = web3.to_checksum_address(self.POOL_ROUTER_ADDRESS) 649 | router_contract = web3.eth.contract(address=router_address, abi=self.OPENFI_CONTRACT_ABI) 650 | 651 | token_address = web3.to_checksum_address(asset_address) 652 | token_contract = web3.eth.contract(address=token_address, abi=self.ERC20_CONTRACT_ABI) 653 | decimals = token_contract.functions.decimals().call() 654 | 655 | amount_to_wei = int(supply_amount * (10 ** decimals)) 656 | supply_data = router_contract.functions.supply(token_address, amount_to_wei, address, 0) 657 | estimated_gas = supply_data.estimate_gas({"from": address}) 658 | 659 | max_priority_fee = web3.to_wei(1, "gwei") 660 | max_fee = max_priority_fee 661 | 662 | supply_tx = supply_data.build_transaction({ 663 | "from": address, 664 | "gas": int(estimated_gas * 1.2), 665 | "maxFeePerGas": int(max_fee), 666 | "maxPriorityFeePerGas": int(max_priority_fee), 667 | "nonce": self.used_nonce[address], 668 | "chainId": web3.eth.chain_id, 669 | }) 670 | 671 | tx_hash = await self.send_raw_transaction_with_retries(account, web3, supply_tx) 672 | receipt = await self.wait_for_receipt_with_retries(web3, tx_hash) 673 | 674 | block_number = receipt.blockNumber 675 | self.used_nonce[address] += 1 676 | 677 | return tx_hash, block_number 678 | except Exception as e: 679 | self.log( 680 | f"{Fore.CYAN+Style.BRIGHT} Message :{Style.RESET_ALL}" 681 | f"{Fore.RED+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 682 | ) 683 | return None, None 684 | 685 | async def perform_borrow(self, account: str, address: str, asset_address: str, borrow_amount: float, use_proxy: bool): 686 | try: 687 | web3 = await self.get_web3_with_check(address, use_proxy) 688 | 689 | router_address = web3.to_checksum_address(self.POOL_ROUTER_ADDRESS) 690 | router_contract = web3.eth.contract(address=router_address, abi=self.OPENFI_CONTRACT_ABI) 691 | 692 | token_address = web3.to_checksum_address(asset_address) 693 | token_contract = web3.eth.contract(address=token_address, abi=self.ERC20_CONTRACT_ABI) 694 | decimals = token_contract.functions.decimals().call() 695 | 696 | amount_to_wei = int(borrow_amount * (10 ** decimals)) 697 | borrow_data = router_contract.functions.borrow(token_address, amount_to_wei, 2, 0, address) 698 | estimated_gas = borrow_data.estimate_gas({"from": address}) 699 | 700 | max_priority_fee = web3.to_wei(1, "gwei") 701 | max_fee = max_priority_fee 702 | 703 | borrow_tx = borrow_data.build_transaction({ 704 | "from": address, 705 | "gas": int(estimated_gas * 1.2), 706 | "maxFeePerGas": int(max_fee), 707 | "maxPriorityFeePerGas": int(max_priority_fee), 708 | "nonce": self.used_nonce[address], 709 | "chainId": web3.eth.chain_id, 710 | }) 711 | 712 | tx_hash = await self.send_raw_transaction_with_retries(account, web3, borrow_tx) 713 | receipt = await self.wait_for_receipt_with_retries(web3, tx_hash) 714 | 715 | block_number = receipt.blockNumber 716 | self.used_nonce[address] += 1 717 | 718 | return tx_hash, block_number 719 | except Exception as e: 720 | self.log( 721 | f"{Fore.CYAN+Style.BRIGHT} Message :{Style.RESET_ALL}" 722 | f"{Fore.RED+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 723 | ) 724 | return None, None 725 | 726 | async def perform_repay(self, account: str, address: str, asset_address: str, repay_amount: float, use_proxy: bool): 727 | try: 728 | web3 = await self.get_web3_with_check(address, use_proxy) 729 | 730 | await self.approving_token(account, address, self.POOL_ROUTER_ADDRESS, asset_address, repay_amount, use_proxy) 731 | 732 | router_address = web3.to_checksum_address(self.POOL_ROUTER_ADDRESS) 733 | router_contract = web3.eth.contract(address=router_address, abi=self.OPENFI_CONTRACT_ABI) 734 | 735 | token_address = web3.to_checksum_address(asset_address) 736 | token_contract = web3.eth.contract(address=token_address, abi=self.ERC20_CONTRACT_ABI) 737 | decimals = token_contract.functions.decimals().call() 738 | 739 | amount_to_wei = int(repay_amount * (10 ** decimals)) 740 | repay_data = router_contract.functions.repay(token_address, amount_to_wei, 2, address) 741 | estimated_gas = repay_data.estimate_gas({"from": address}) 742 | 743 | max_priority_fee = web3.to_wei(1, "gwei") 744 | max_fee = max_priority_fee 745 | 746 | repay_tx = repay_data.build_transaction({ 747 | "from": address, 748 | "gas": int(estimated_gas * 1.2), 749 | "maxFeePerGas": int(max_fee), 750 | "maxPriorityFeePerGas": int(max_priority_fee), 751 | "nonce": self.used_nonce[address], 752 | "chainId": web3.eth.chain_id, 753 | }) 754 | 755 | tx_hash = await self.send_raw_transaction_with_retries(account, web3, repay_tx) 756 | receipt = await self.wait_for_receipt_with_retries(web3, tx_hash) 757 | 758 | block_number = receipt.blockNumber 759 | self.used_nonce[address] += 1 760 | 761 | return tx_hash, block_number 762 | except Exception as e: 763 | self.log( 764 | f"{Fore.CYAN+Style.BRIGHT} Message :{Style.RESET_ALL}" 765 | f"{Fore.RED+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 766 | ) 767 | return None, None 768 | 769 | async def perform_withdraw(self, account: str, address: str, asset_address: str, withdraw_amount: float, use_proxy: bool): 770 | try: 771 | web3 = await self.get_web3_with_check(address, use_proxy) 772 | 773 | router_address = web3.to_checksum_address(self.POOL_ROUTER_ADDRESS) 774 | router_contract = web3.eth.contract(address=router_address, abi=self.OPENFI_CONTRACT_ABI) 775 | 776 | token_address = web3.to_checksum_address(asset_address) 777 | token_contract = web3.eth.contract(address=token_address, abi=self.ERC20_CONTRACT_ABI) 778 | decimals = token_contract.functions.decimals().call() 779 | 780 | amount_to_wei = int(withdraw_amount * (10 ** decimals)) 781 | withdraw_data = router_contract.functions.withdraw(token_address, amount_to_wei, address) 782 | estimated_gas = withdraw_data.estimate_gas({"from": address}) 783 | 784 | max_priority_fee = web3.to_wei(1, "gwei") 785 | max_fee = max_priority_fee 786 | 787 | withdraw_tx = withdraw_data.build_transaction({ 788 | "from": address, 789 | "gas": int(estimated_gas * 1.2), 790 | "maxFeePerGas": int(max_fee), 791 | "maxPriorityFeePerGas": int(max_priority_fee), 792 | "nonce": self.used_nonce[address], 793 | "chainId": web3.eth.chain_id, 794 | }) 795 | 796 | tx_hash = await self.send_raw_transaction_with_retries(account, web3, withdraw_tx) 797 | receipt = await self.wait_for_receipt_with_retries(web3, tx_hash) 798 | 799 | block_number = receipt.blockNumber 800 | self.used_nonce[address] += 1 801 | 802 | return tx_hash, block_number 803 | except Exception as e: 804 | self.log( 805 | f"{Fore.CYAN+Style.BRIGHT} Message :{Style.RESET_ALL}" 806 | f"{Fore.RED+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 807 | ) 808 | return None, None 809 | 810 | async def print_timer(self): 811 | for remaining in range(random.randint(self.min_delay, self.max_delay), 0, -1): 812 | print( 813 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}" 814 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}" 815 | f"{Fore.BLUE + Style.BRIGHT}Wait For{Style.RESET_ALL}" 816 | f"{Fore.WHITE + Style.BRIGHT} {remaining} {Style.RESET_ALL}" 817 | f"{Fore.BLUE + Style.BRIGHT}Seconds For Next Tx...{Style.RESET_ALL}", 818 | end="\r", 819 | flush=True 820 | ) 821 | await asyncio.sleep(1) 822 | 823 | def print_deposit_question(self): 824 | while True: 825 | try: 826 | deposit_count = int(input(f"{Fore.YELLOW + Style.BRIGHT}Enter Deposit Count -> {Style.RESET_ALL}").strip()) 827 | if deposit_count > 0: 828 | self.deposit_count = deposit_count 829 | break 830 | else: 831 | print(f"{Fore.RED + Style.BRIGHT}Deposit Count must be greater than 0.{Style.RESET_ALL}") 832 | except ValueError: 833 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a float or decimal number.{Style.RESET_ALL}") 834 | 835 | while True: 836 | try: 837 | deposit_amount = float(input(f"{Fore.YELLOW + Style.BRIGHT}Enter Deposit Amount [PHRS] -> {Style.RESET_ALL}").strip()) 838 | if deposit_amount > 0: 839 | self.deposit_amount = deposit_amount 840 | break 841 | else: 842 | print(f"{Fore.RED + Style.BRIGHT}Amount must be greater than 0.{Style.RESET_ALL}") 843 | except ValueError: 844 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a float or decimal number.{Style.RESET_ALL}") 845 | 846 | def print_supply_question(self): 847 | while True: 848 | try: 849 | supply_count = int(input(f"{Fore.YELLOW + Style.BRIGHT}Enter Supply Count -> {Style.RESET_ALL}").strip()) 850 | if supply_count > 0: 851 | self.supply_count = supply_count 852 | break 853 | else: 854 | print(f"{Fore.RED + Style.BRIGHT}Supply Count must be greater than 0.{Style.RESET_ALL}") 855 | except ValueError: 856 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a float or decimal number.{Style.RESET_ALL}") 857 | 858 | while True: 859 | try: 860 | supply_amount = float(input(f"{Fore.YELLOW + Style.BRIGHT}Enter Supply Amount [ERC20] -> {Style.RESET_ALL}").strip()) 861 | if supply_amount > 0: 862 | self.supply_amount = supply_amount 863 | break 864 | else: 865 | print(f"{Fore.RED + Style.BRIGHT}Amount must be greater than 0.{Style.RESET_ALL}") 866 | except ValueError: 867 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a float or decimal number.{Style.RESET_ALL}") 868 | 869 | def print_borrow_question(self): 870 | while True: 871 | try: 872 | borrow_count = int(input(f"{Fore.YELLOW + Style.BRIGHT}Enter Borrow Count -> {Style.RESET_ALL}").strip()) 873 | if borrow_count > 0: 874 | self.borrow_count = borrow_count 875 | break 876 | else: 877 | print(f"{Fore.RED + Style.BRIGHT}Borrow Count must be greater than 0.{Style.RESET_ALL}") 878 | except ValueError: 879 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a float or decimal number.{Style.RESET_ALL}") 880 | 881 | while True: 882 | try: 883 | borrow_amount = float(input(f"{Fore.YELLOW + Style.BRIGHT}Enter Borrow Amount [ERC20] -> {Style.RESET_ALL}").strip()) 884 | if borrow_amount > 0: 885 | self.borrow_amount = borrow_amount 886 | break 887 | else: 888 | print(f"{Fore.RED + Style.BRIGHT}Amount must be greater than 0.{Style.RESET_ALL}") 889 | except ValueError: 890 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a float or decimal number.{Style.RESET_ALL}") 891 | 892 | def print_repay_question(self): 893 | while True: 894 | try: 895 | repay_count = int(input(f"{Fore.YELLOW + Style.BRIGHT}Enter Repay Count -> {Style.RESET_ALL}").strip()) 896 | if repay_count > 0: 897 | self.repay_count = repay_count 898 | break 899 | else: 900 | print(f"{Fore.RED + Style.BRIGHT}Repay Count must be greater than 0.{Style.RESET_ALL}") 901 | except ValueError: 902 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a float or decimal number.{Style.RESET_ALL}") 903 | 904 | while True: 905 | try: 906 | repay_amount = float(input(f"{Fore.YELLOW + Style.BRIGHT}Enter Repay Amount [ERC20] -> {Style.RESET_ALL}").strip()) 907 | if repay_amount > 0: 908 | self.repay_amount = repay_amount 909 | break 910 | else: 911 | print(f"{Fore.RED + Style.BRIGHT}Amount must be greater than 0.{Style.RESET_ALL}") 912 | except ValueError: 913 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a float or decimal number.{Style.RESET_ALL}") 914 | 915 | def print_withdraw_question(self): 916 | while True: 917 | try: 918 | withdraw_count = int(input(f"{Fore.YELLOW + Style.BRIGHT}Enter Withdraw Count -> {Style.RESET_ALL}").strip()) 919 | if withdraw_count > 0: 920 | self.withdraw_count = withdraw_count 921 | break 922 | else: 923 | print(f"{Fore.RED + Style.BRIGHT}Withdraw Count must be greater than 0.{Style.RESET_ALL}") 924 | except ValueError: 925 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a float or decimal number.{Style.RESET_ALL}") 926 | 927 | while True: 928 | try: 929 | withdraw_amount = float(input(f"{Fore.YELLOW + Style.BRIGHT}Enter Withdraw Amount [ERC20] -> {Style.RESET_ALL}").strip()) 930 | if withdraw_amount > 0: 931 | self.withdraw_amount = withdraw_amount 932 | break 933 | else: 934 | print(f"{Fore.RED + Style.BRIGHT}Amount must be greater than 0.{Style.RESET_ALL}") 935 | except ValueError: 936 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a float or decimal number.{Style.RESET_ALL}") 937 | 938 | def print_delay_question(self): 939 | while True: 940 | try: 941 | min_delay = int(input(f"{Fore.YELLOW + Style.BRIGHT}Min Delay Each Tx -> {Style.RESET_ALL}").strip()) 942 | if min_delay >= 0: 943 | self.min_delay = min_delay 944 | break 945 | else: 946 | print(f"{Fore.RED + Style.BRIGHT}Min Delay must be >= 0.{Style.RESET_ALL}") 947 | except ValueError: 948 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a number.{Style.RESET_ALL}") 949 | 950 | while True: 951 | try: 952 | max_delay = int(input(f"{Fore.YELLOW + Style.BRIGHT}Max Delay Each Tx -> {Style.RESET_ALL}").strip()) 953 | if max_delay >= min_delay: 954 | self.max_delay = max_delay 955 | break 956 | else: 957 | print(f"{Fore.RED + Style.BRIGHT}Min Delay must be >= Min Delay.{Style.RESET_ALL}") 958 | except ValueError: 959 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a number.{Style.RESET_ALL}") 960 | 961 | def print_question(self): 962 | while True: 963 | try: 964 | print(f"{Fore.GREEN + Style.BRIGHT}Select Option:{Style.RESET_ALL}") 965 | print(f"{Fore.WHITE + Style.BRIGHT}1. Mint Faucets{Style.RESET_ALL}") 966 | print(f"{Fore.WHITE + Style.BRIGHT}2. Deposit PHRS{Style.RESET_ALL}") 967 | print(f"{Fore.WHITE + Style.BRIGHT}3. Supply Assets{Style.RESET_ALL}") 968 | print(f"{Fore.WHITE + Style.BRIGHT}4. Borrow Assets{Style.RESET_ALL}") 969 | print(f"{Fore.WHITE + Style.BRIGHT}5. Repay Assets{Style.RESET_ALL}") 970 | print(f"{Fore.WHITE + Style.BRIGHT}6. Withdraw Assets{Style.RESET_ALL}") 971 | print(f"{Fore.WHITE + Style.BRIGHT}7. Run All Features{Style.RESET_ALL}") 972 | option = int(input(f"{Fore.BLUE + Style.BRIGHT}Choose [1/2/3/4/5/6/7] -> {Style.RESET_ALL}").strip()) 973 | 974 | if option in [1, 2, 3, 4, 5, 6, 7]: 975 | option_type = ( 976 | "Mint Faucets" if option == 1 else 977 | "Deposit PHRS" if option == 2 else 978 | "Supply Assets" if option == 3 else 979 | "Borrow Assets" if option == 4 else 980 | "Repay Assets" if option == 5 else 981 | "Withdraw Assets" if option == 6 else 982 | "Run All Features" 983 | ) 984 | print(f"{Fore.GREEN + Style.BRIGHT}{option_type} Selected.{Style.RESET_ALL}") 985 | break 986 | else: 987 | print(f"{Fore.RED + Style.BRIGHT}Please enter either 1, 2, 3, 4, 5, 6 or 7.{Style.RESET_ALL}") 988 | except ValueError: 989 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a number (1, 2, 3, 4, 5, 6 or 7).{Style.RESET_ALL}") 990 | 991 | if option == 1: 992 | self.print_delay_question() 993 | 994 | elif option == 2: 995 | self.print_deposit_question() 996 | self.print_delay_question() 997 | 998 | elif option == 3: 999 | self.print_supply_question() 1000 | self.print_delay_question() 1001 | 1002 | elif option == 4: 1003 | self.print_borrow_question() 1004 | self.print_delay_question() 1005 | 1006 | elif option == 5: 1007 | self.print_repay_question() 1008 | self.print_delay_question() 1009 | 1010 | elif option == 6: 1011 | self.print_withdraw_question() 1012 | self.print_delay_question() 1013 | 1014 | elif option == 7: 1015 | self.print_deposit_question() 1016 | self.print_supply_question() 1017 | self.print_borrow_question() 1018 | self.print_repay_question() 1019 | self.print_withdraw_question() 1020 | self.print_delay_question() 1021 | 1022 | while True: 1023 | try: 1024 | print(f"{Fore.WHITE + Style.BRIGHT}1. Run With Proxy{Style.RESET_ALL}") 1025 | print(f"{Fore.WHITE + Style.BRIGHT}2. Run Without Proxy{Style.RESET_ALL}") 1026 | proxy_choice = int(input(f"{Fore.BLUE + Style.BRIGHT}Choose [1/2] -> {Style.RESET_ALL}").strip()) 1027 | 1028 | if proxy_choice in [1, 2]: 1029 | proxy_type = ( 1030 | "With" if proxy_choice == 1 else 1031 | "Without" 1032 | ) 1033 | print(f"{Fore.GREEN + Style.BRIGHT}Run {proxy_type} Proxy Selected.{Style.RESET_ALL}") 1034 | break 1035 | else: 1036 | print(f"{Fore.RED + Style.BRIGHT}Please enter either 1 or 2.{Style.RESET_ALL}") 1037 | except ValueError: 1038 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a number (1 or 2).{Style.RESET_ALL}") 1039 | 1040 | rotate_proxy = False 1041 | if proxy_choice == 1: 1042 | while True: 1043 | rotate_proxy = input(f"{Fore.BLUE + Style.BRIGHT}Rotate Invalid Proxy? [y/n] -> {Style.RESET_ALL}").strip() 1044 | 1045 | if rotate_proxy in ["y", "n"]: 1046 | rotate_proxy = rotate_proxy == "y" 1047 | break 1048 | else: 1049 | print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter 'y' or 'n'.{Style.RESET_ALL}") 1050 | 1051 | return option, proxy_choice, rotate_proxy 1052 | 1053 | async def check_connection(self, proxy_url=None): 1054 | connector, proxy, proxy_auth = self.build_proxy_config(proxy_url) 1055 | try: 1056 | async with ClientSession(connector=connector, timeout=ClientTimeout(total=30)) as session: 1057 | async with session.get(url="https://api.ipify.org?format=json", proxy=proxy, proxy_auth=proxy_auth) as response: 1058 | response.raise_for_status() 1059 | return True 1060 | except (Exception, ClientResponseError) as e: 1061 | self.log( 1062 | f"{Fore.CYAN+Style.BRIGHT}Status :{Style.RESET_ALL}" 1063 | f"{Fore.RED+Style.BRIGHT} Connection Not 200 OK {Style.RESET_ALL}" 1064 | f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}" 1065 | f"{Fore.YELLOW+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 1066 | ) 1067 | return None 1068 | 1069 | async def process_check_connection(self, address: str, use_proxy: bool, rotate_proxy: bool): 1070 | while True: 1071 | proxy = self.get_next_proxy_for_account(address) if use_proxy else None 1072 | self.log( 1073 | f"{Fore.CYAN+Style.BRIGHT}Proxy :{Style.RESET_ALL}" 1074 | f"{Fore.WHITE + Style.BRIGHT} {proxy} {Style.RESET_ALL}" 1075 | ) 1076 | 1077 | is_valid = await self.check_connection(proxy) 1078 | if not is_valid: 1079 | if rotate_proxy: 1080 | proxy = self.rotate_proxy_for_account(address) 1081 | await asyncio.sleep(1) 1082 | continue 1083 | 1084 | return False 1085 | 1086 | return True 1087 | 1088 | async def process_mint_faucet(self, account: str, address: str, asset_address: str, ticker: str, use_proxy: bool): 1089 | is_mintable = await self.check_faucet_status(address, asset_address, use_proxy) 1090 | if is_mintable: 1091 | tx_hash, block_number = await self.mint_faucet(account, address, asset_address, use_proxy) 1092 | if tx_hash and block_number: 1093 | explorer = f"https://testnet.pharosscan.xyz/tx/{tx_hash}" 1094 | self.log( 1095 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1096 | f"{Fore.GREEN+Style.BRIGHT} Mint 100 {ticker} Faucet Success {Style.RESET_ALL} " 1097 | ) 1098 | self.log( 1099 | f"{Fore.CYAN+Style.BRIGHT} Block :{Style.RESET_ALL}" 1100 | f"{Fore.WHITE+Style.BRIGHT} {block_number} {Style.RESET_ALL}" 1101 | ) 1102 | self.log( 1103 | f"{Fore.CYAN+Style.BRIGHT} Tx Hash :{Style.RESET_ALL}" 1104 | f"{Fore.WHITE+Style.BRIGHT} {tx_hash} {Style.RESET_ALL}" 1105 | ) 1106 | self.log( 1107 | f"{Fore.CYAN+Style.BRIGHT} Explorer :{Style.RESET_ALL}" 1108 | f"{Fore.WHITE+Style.BRIGHT} {explorer} {Style.RESET_ALL}" 1109 | ) 1110 | else: 1111 | self.log( 1112 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1113 | f"{Fore.RED+Style.BRIGHT} Perform On-Chain Failed {Style.RESET_ALL}" 1114 | ) 1115 | else: 1116 | self.log( 1117 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1118 | f"{Fore.YELLOW+Style.BRIGHT} Not Able to Mint {Style.RESET_ALL}" 1119 | ) 1120 | 1121 | async def process_perform_deposit(self, account: str, address: str, deposit_amount: float, use_proxy: bool): 1122 | tx_hash, block_number = await self.perform_deposit(account, address, deposit_amount, use_proxy) 1123 | if tx_hash and block_number: 1124 | explorer = f"https://testnet.pharosscan.xyz/tx/{tx_hash}" 1125 | self.log( 1126 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1127 | f"{Fore.GREEN+Style.BRIGHT} Deposit {deposit_amount} PHRS Success {Style.RESET_ALL} " 1128 | ) 1129 | self.log( 1130 | f"{Fore.CYAN+Style.BRIGHT} Block :{Style.RESET_ALL}" 1131 | f"{Fore.WHITE+Style.BRIGHT} {block_number} {Style.RESET_ALL}" 1132 | ) 1133 | self.log( 1134 | f"{Fore.CYAN+Style.BRIGHT} Tx Hash :{Style.RESET_ALL}" 1135 | f"{Fore.WHITE+Style.BRIGHT} {tx_hash} {Style.RESET_ALL}" 1136 | ) 1137 | self.log( 1138 | f"{Fore.CYAN+Style.BRIGHT} Explorer :{Style.RESET_ALL}" 1139 | f"{Fore.WHITE+Style.BRIGHT} {explorer} {Style.RESET_ALL}" 1140 | ) 1141 | else: 1142 | self.log( 1143 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1144 | f"{Fore.RED+Style.BRIGHT} Perform On-Chain Failed {Style.RESET_ALL}" 1145 | ) 1146 | 1147 | async def process_perform_supply(self, account: str, address: str, asset_address: str, supply_amount: float, ticker: str, use_proxy: bool): 1148 | tx_hash, block_number = await self.perform_supply(account, address, asset_address, supply_amount, use_proxy) 1149 | if tx_hash and block_number: 1150 | explorer = f"https://testnet.pharosscan.xyz/tx/{tx_hash}" 1151 | self.log( 1152 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1153 | f"{Fore.GREEN+Style.BRIGHT} Supply {supply_amount} {ticker} Success {Style.RESET_ALL} " 1154 | ) 1155 | self.log( 1156 | f"{Fore.CYAN+Style.BRIGHT} Block :{Style.RESET_ALL}" 1157 | f"{Fore.WHITE+Style.BRIGHT} {block_number} {Style.RESET_ALL}" 1158 | ) 1159 | self.log( 1160 | f"{Fore.CYAN+Style.BRIGHT} Tx Hash :{Style.RESET_ALL}" 1161 | f"{Fore.WHITE+Style.BRIGHT} {tx_hash} {Style.RESET_ALL}" 1162 | ) 1163 | self.log( 1164 | f"{Fore.CYAN+Style.BRIGHT} Explorer :{Style.RESET_ALL}" 1165 | f"{Fore.WHITE+Style.BRIGHT} {explorer} {Style.RESET_ALL}" 1166 | ) 1167 | else: 1168 | self.log( 1169 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1170 | f"{Fore.RED+Style.BRIGHT} Perform On-Chain Failed {Style.RESET_ALL}" 1171 | ) 1172 | 1173 | async def process_perform_borrow(self, account: str, address: str, asset_address: str, borrow_amount: float, ticker: str, use_proxy: bool): 1174 | tx_hash, block_number = await self.perform_borrow(account, address, asset_address, borrow_amount, use_proxy) 1175 | if tx_hash and block_number: 1176 | explorer = f"https://testnet.pharosscan.xyz/tx/{tx_hash}" 1177 | self.log( 1178 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1179 | f"{Fore.GREEN+Style.BRIGHT} Borrow {borrow_amount} {ticker} Success {Style.RESET_ALL} " 1180 | ) 1181 | self.log( 1182 | f"{Fore.CYAN+Style.BRIGHT} Block :{Style.RESET_ALL}" 1183 | f"{Fore.WHITE+Style.BRIGHT} {block_number} {Style.RESET_ALL}" 1184 | ) 1185 | self.log( 1186 | f"{Fore.CYAN+Style.BRIGHT} Tx Hash :{Style.RESET_ALL}" 1187 | f"{Fore.WHITE+Style.BRIGHT} {tx_hash} {Style.RESET_ALL}" 1188 | ) 1189 | self.log( 1190 | f"{Fore.CYAN+Style.BRIGHT} Explorer :{Style.RESET_ALL}" 1191 | f"{Fore.WHITE+Style.BRIGHT} {explorer} {Style.RESET_ALL}" 1192 | ) 1193 | else: 1194 | self.log( 1195 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1196 | f"{Fore.RED+Style.BRIGHT} Perform On-Chain Failed {Style.RESET_ALL}" 1197 | ) 1198 | 1199 | async def process_perform_repay(self, account: str, address: str, asset_address: str, repay_amount: float, ticker: str, use_proxy: bool): 1200 | tx_hash, block_number = await self.perform_repay(account, address, asset_address, repay_amount, use_proxy) 1201 | if tx_hash and block_number: 1202 | explorer = f"https://testnet.pharosscan.xyz/tx/{tx_hash}" 1203 | self.log( 1204 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1205 | f"{Fore.GREEN+Style.BRIGHT} Repay {repay_amount} {ticker} Success {Style.RESET_ALL} " 1206 | ) 1207 | self.log( 1208 | f"{Fore.CYAN+Style.BRIGHT} Block :{Style.RESET_ALL}" 1209 | f"{Fore.WHITE+Style.BRIGHT} {block_number} {Style.RESET_ALL}" 1210 | ) 1211 | self.log( 1212 | f"{Fore.CYAN+Style.BRIGHT} Tx Hash :{Style.RESET_ALL}" 1213 | f"{Fore.WHITE+Style.BRIGHT} {tx_hash} {Style.RESET_ALL}" 1214 | ) 1215 | self.log( 1216 | f"{Fore.CYAN+Style.BRIGHT} Explorer :{Style.RESET_ALL}" 1217 | f"{Fore.WHITE+Style.BRIGHT} {explorer} {Style.RESET_ALL}" 1218 | ) 1219 | else: 1220 | self.log( 1221 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1222 | f"{Fore.RED+Style.BRIGHT} Perform On-Chain Failed {Style.RESET_ALL}" 1223 | ) 1224 | 1225 | async def process_perform_withdraw(self, account: str, address: str, asset_address: str, withdraw_amount: float, ticker: str, use_proxy: bool): 1226 | tx_hash, block_number = await self.perform_withdraw(account, address, asset_address, withdraw_amount, use_proxy) 1227 | if tx_hash and block_number: 1228 | explorer = f"https://testnet.pharosscan.xyz/tx/{tx_hash}" 1229 | self.log( 1230 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1231 | f"{Fore.GREEN+Style.BRIGHT} Withdraw {withdraw_amount} {ticker} Success {Style.RESET_ALL} " 1232 | ) 1233 | self.log( 1234 | f"{Fore.CYAN+Style.BRIGHT} Block :{Style.RESET_ALL}" 1235 | f"{Fore.WHITE+Style.BRIGHT} {block_number} {Style.RESET_ALL}" 1236 | ) 1237 | self.log( 1238 | f"{Fore.CYAN+Style.BRIGHT} Tx Hash :{Style.RESET_ALL}" 1239 | f"{Fore.WHITE+Style.BRIGHT} {tx_hash} {Style.RESET_ALL}" 1240 | ) 1241 | self.log( 1242 | f"{Fore.CYAN+Style.BRIGHT} Explorer :{Style.RESET_ALL}" 1243 | f"{Fore.WHITE+Style.BRIGHT} {explorer} {Style.RESET_ALL}" 1244 | ) 1245 | else: 1246 | self.log( 1247 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1248 | f"{Fore.RED+Style.BRIGHT} Perform On-Chain Failed {Style.RESET_ALL}" 1249 | ) 1250 | 1251 | async def process_option_1(self, account: str, address: str, use_proxy: bool): 1252 | self.log( 1253 | f"{Fore.MAGENTA+Style.BRIGHT} ● {Style.RESET_ALL}" 1254 | f"{Fore.GREEN+Style.BRIGHT}Mint{Style.RESET_ALL} " 1255 | ) 1256 | 1257 | for ticker, asset_address in [ 1258 | ("GOLD", self.GOLD_CONTRACT_ADDRESS), 1259 | ("TSLA", self.TSLA_CONTRACT_ADDRESS), 1260 | ("NVIDIA", self.NVIDIA_CONTRACT_ADDRESS) 1261 | ]: 1262 | 1263 | self.log( 1264 | f"{Fore.CYAN+Style.BRIGHT} Assets :{Style.RESET_ALL}" 1265 | f"{Fore.BLUE+Style.BRIGHT} {ticker} {Style.RESET_ALL} " 1266 | ) 1267 | 1268 | await self.process_mint_faucet(account, address, asset_address, ticker, use_proxy) 1269 | await self.print_timer() 1270 | 1271 | async def process_option_2(self, account: str, address: str, use_proxy: bool): 1272 | self.log( 1273 | f"{Fore.MAGENTA+Style.BRIGHT} ● {Style.RESET_ALL}" 1274 | f"{Fore.GREEN+Style.BRIGHT}Deposit{Style.RESET_ALL} " 1275 | ) 1276 | 1277 | for i in range(self.deposit_count): 1278 | self.log( 1279 | f"{Fore.GREEN+Style.BRIGHT} ● {Style.RESET_ALL}" 1280 | f"{Fore.BLUE+Style.BRIGHT}Deposit{Style.RESET_ALL}" 1281 | f"{Fore.WHITE+Style.BRIGHT} {i+1} {Style.RESET_ALL}" 1282 | f"{Fore.MAGENTA+Style.BRIGHT}Of{Style.RESET_ALL}" 1283 | f"{Fore.WHITE+Style.BRIGHT} {self.deposit_count} {Style.RESET_ALL} " 1284 | ) 1285 | 1286 | self.log( 1287 | f"{Fore.CYAN+Style.BRIGHT} Assets :{Style.RESET_ALL}" 1288 | f"{Fore.BLUE+Style.BRIGHT} PHRS {Style.RESET_ALL} " 1289 | ) 1290 | 1291 | self.log( 1292 | f"{Fore.CYAN+Style.BRIGHT} Amount :{Style.RESET_ALL}" 1293 | f"{Fore.WHITE+Style.BRIGHT} {self.deposit_amount} PHRS {Style.RESET_ALL}" 1294 | ) 1295 | 1296 | balance = await self.get_token_balance(address, self.PHRS_CONTRACT_ADDRESS, use_proxy) 1297 | 1298 | self.log( 1299 | f"{Fore.CYAN+Style.BRIGHT} Balance :{Style.RESET_ALL}" 1300 | f"{Fore.WHITE+Style.BRIGHT} {balance} PHRS {Style.RESET_ALL}" 1301 | ) 1302 | 1303 | if not balance or balance <= self.deposit_amount: 1304 | self.log( 1305 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1306 | f"{Fore.YELLOW+Style.BRIGHT} Insufficient PHRS Token Balance {Style.RESET_ALL}" 1307 | ) 1308 | return 1309 | 1310 | await self.process_perform_deposit(account, address, self.deposit_amount, use_proxy) 1311 | await self.print_timer() 1312 | 1313 | async def process_option_3(self, account: str, address: str, use_proxy: bool): 1314 | self.log( 1315 | f"{Fore.MAGENTA+Style.BRIGHT} ● {Style.RESET_ALL}" 1316 | f"{Fore.GREEN+Style.BRIGHT}Supply{Style.RESET_ALL} " 1317 | ) 1318 | 1319 | for i in range(self.supply_count): 1320 | self.log( 1321 | f"{Fore.GREEN+Style.BRIGHT} ● {Style.RESET_ALL}" 1322 | f"{Fore.BLUE+Style.BRIGHT}Supply{Style.RESET_ALL}" 1323 | f"{Fore.WHITE+Style.BRIGHT} {i+1} {Style.RESET_ALL}" 1324 | f"{Fore.MAGENTA+Style.BRIGHT}Of{Style.RESET_ALL}" 1325 | f"{Fore.WHITE+Style.BRIGHT} {self.supply_count} {Style.RESET_ALL} " 1326 | ) 1327 | 1328 | ticker, asset_address, decimals = self.generate_random_option() 1329 | 1330 | self.log( 1331 | f"{Fore.CYAN+Style.BRIGHT} Assets :{Style.RESET_ALL}" 1332 | f"{Fore.BLUE+Style.BRIGHT} {ticker} {Style.RESET_ALL} " 1333 | ) 1334 | 1335 | self.log( 1336 | f"{Fore.CYAN+Style.BRIGHT} Amount :{Style.RESET_ALL}" 1337 | f"{Fore.WHITE+Style.BRIGHT} {self.supply_amount} {ticker} {Style.RESET_ALL}" 1338 | ) 1339 | 1340 | balance = await self.get_token_balance(address, asset_address, use_proxy) 1341 | 1342 | self.log( 1343 | f"{Fore.CYAN+Style.BRIGHT} Balance :{Style.RESET_ALL}" 1344 | f"{Fore.WHITE+Style.BRIGHT} {balance} {ticker} {Style.RESET_ALL}" 1345 | ) 1346 | 1347 | if not balance or balance <= self.supply_amount: 1348 | self.log( 1349 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1350 | f"{Fore.YELLOW+Style.BRIGHT} Insufficient {ticker} Token Balance {Style.RESET_ALL}" 1351 | ) 1352 | continue 1353 | 1354 | await self.process_perform_supply(account, address, asset_address, self.supply_amount, ticker, use_proxy) 1355 | await self.print_timer() 1356 | 1357 | async def process_option_4(self, account: str, address: str, use_proxy: bool): 1358 | self.log( 1359 | f"{Fore.MAGENTA+Style.BRIGHT} ● {Style.RESET_ALL}" 1360 | f"{Fore.GREEN+Style.BRIGHT}Borrow{Style.RESET_ALL} " 1361 | ) 1362 | 1363 | for i in range(self.borrow_count): 1364 | self.log( 1365 | f"{Fore.GREEN+Style.BRIGHT} ● {Style.RESET_ALL}" 1366 | f"{Fore.BLUE+Style.BRIGHT}Borrow{Style.RESET_ALL}" 1367 | f"{Fore.WHITE+Style.BRIGHT} {i+1} {Style.RESET_ALL}" 1368 | f"{Fore.MAGENTA+Style.BRIGHT}Of{Style.RESET_ALL}" 1369 | f"{Fore.WHITE+Style.BRIGHT} {self.borrow_count} {Style.RESET_ALL} " 1370 | ) 1371 | 1372 | ticker, asset_address, decimals = self.generate_random_option() 1373 | 1374 | self.log( 1375 | f"{Fore.CYAN+Style.BRIGHT} Assets :{Style.RESET_ALL}" 1376 | f"{Fore.BLUE+Style.BRIGHT} {ticker} {Style.RESET_ALL} " 1377 | ) 1378 | 1379 | self.log( 1380 | f"{Fore.CYAN+Style.BRIGHT} Amount :{Style.RESET_ALL}" 1381 | f"{Fore.WHITE+Style.BRIGHT} {self.borrow_amount} {ticker} {Style.RESET_ALL}" 1382 | ) 1383 | 1384 | available_to_borrow = await self.get_available_borrowed_balance(address, asset_address, decimals, use_proxy) 1385 | 1386 | self.log( 1387 | f"{Fore.CYAN+Style.BRIGHT} Available:{Style.RESET_ALL}" 1388 | f"{Fore.WHITE+Style.BRIGHT} {available_to_borrow} {ticker} {Style.RESET_ALL}" 1389 | ) 1390 | 1391 | if not available_to_borrow or available_to_borrow < self.borrow_amount: 1392 | self.log( 1393 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1394 | f"{Fore.YELLOW+Style.BRIGHT} Available {ticker} Borrow Balance Less Than Borrow Amount {Style.RESET_ALL}" 1395 | ) 1396 | continue 1397 | 1398 | await self.process_perform_borrow(account, address, asset_address, self.borrow_amount, ticker, use_proxy) 1399 | await self.print_timer() 1400 | 1401 | async def process_option_5(self, account: str, address: str, use_proxy: bool): 1402 | self.log( 1403 | f"{Fore.MAGENTA+Style.BRIGHT} ● {Style.RESET_ALL}" 1404 | f"{Fore.GREEN+Style.BRIGHT}Repay{Style.RESET_ALL} " 1405 | ) 1406 | 1407 | for i in range(self.repay_count): 1408 | self.log( 1409 | f"{Fore.GREEN+Style.BRIGHT} ● {Style.RESET_ALL}" 1410 | f"{Fore.BLUE+Style.BRIGHT}Repay{Style.RESET_ALL}" 1411 | f"{Fore.WHITE+Style.BRIGHT} {i+1} {Style.RESET_ALL}" 1412 | f"{Fore.MAGENTA+Style.BRIGHT}Of{Style.RESET_ALL}" 1413 | f"{Fore.WHITE+Style.BRIGHT} {self.repay_count} {Style.RESET_ALL} " 1414 | ) 1415 | 1416 | ticker, asset_address, decimals = self.generate_random_option() 1417 | 1418 | self.log( 1419 | f"{Fore.CYAN+Style.BRIGHT} Assets :{Style.RESET_ALL}" 1420 | f"{Fore.BLUE+Style.BRIGHT} {ticker} {Style.RESET_ALL} " 1421 | ) 1422 | 1423 | self.log( 1424 | f"{Fore.CYAN+Style.BRIGHT} Amount :{Style.RESET_ALL}" 1425 | f"{Fore.WHITE+Style.BRIGHT} {self.repay_amount} {ticker} {Style.RESET_ALL}" 1426 | ) 1427 | 1428 | borrowed_balance = await self.get_borrowed_balance(address, asset_address, decimals, use_proxy) 1429 | 1430 | self.log( 1431 | f"{Fore.CYAN+Style.BRIGHT} Borrowed :{Style.RESET_ALL}" 1432 | f"{Fore.WHITE+Style.BRIGHT} {borrowed_balance} {ticker} {Style.RESET_ALL}" 1433 | ) 1434 | 1435 | if not borrowed_balance or borrowed_balance < self.repay_amount: 1436 | self.log( 1437 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1438 | f"{Fore.YELLOW+Style.BRIGHT} Borrowed {ticker} Token Balance Less Than Repay Amount {Style.RESET_ALL}" 1439 | ) 1440 | continue 1441 | 1442 | balance = await self.get_token_balance(address, asset_address, use_proxy) 1443 | 1444 | self.log( 1445 | f"{Fore.CYAN+Style.BRIGHT} Balance :{Style.RESET_ALL}" 1446 | f"{Fore.WHITE+Style.BRIGHT} {balance} {ticker} {Style.RESET_ALL}" 1447 | ) 1448 | 1449 | if not balance or balance <= self.repay_amount: 1450 | self.log( 1451 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1452 | f"{Fore.YELLOW+Style.BRIGHT} Insufficient {ticker} Token Balance {Style.RESET_ALL}" 1453 | ) 1454 | continue 1455 | 1456 | await self.process_perform_repay(account, address, asset_address, self.repay_amount, ticker, use_proxy) 1457 | await self.print_timer() 1458 | 1459 | async def process_option_6(self, account: str, address: str, use_proxy: bool): 1460 | self.log( 1461 | f"{Fore.MAGENTA+Style.BRIGHT} ● {Style.RESET_ALL}" 1462 | f"{Fore.GREEN+Style.BRIGHT}Withdraw{Style.RESET_ALL} " 1463 | ) 1464 | 1465 | for i in range(self.withdraw_count): 1466 | self.log( 1467 | f"{Fore.GREEN+Style.BRIGHT} ● {Style.RESET_ALL}" 1468 | f"{Fore.BLUE+Style.BRIGHT}Withdraw{Style.RESET_ALL}" 1469 | f"{Fore.WHITE+Style.BRIGHT} {i+1} {Style.RESET_ALL}" 1470 | f"{Fore.MAGENTA+Style.BRIGHT}Of{Style.RESET_ALL}" 1471 | f"{Fore.WHITE+Style.BRIGHT} {self.withdraw_count} {Style.RESET_ALL} " 1472 | ) 1473 | 1474 | ticker, asset_address, decimals = self.generate_random_option() 1475 | 1476 | self.log( 1477 | f"{Fore.CYAN+Style.BRIGHT} Assets :{Style.RESET_ALL}" 1478 | f"{Fore.BLUE+Style.BRIGHT} {ticker} {Style.RESET_ALL} " 1479 | ) 1480 | 1481 | self.log( 1482 | f"{Fore.CYAN+Style.BRIGHT} Amount :{Style.RESET_ALL}" 1483 | f"{Fore.WHITE+Style.BRIGHT} {self.withdraw_amount} {ticker} {Style.RESET_ALL}" 1484 | ) 1485 | 1486 | supplied_balance = await self.get_supplied_balance(address, asset_address, decimals, use_proxy) 1487 | 1488 | self.log( 1489 | f"{Fore.CYAN+Style.BRIGHT} Supplied :{Style.RESET_ALL}" 1490 | f"{Fore.WHITE+Style.BRIGHT} {supplied_balance} {ticker} {Style.RESET_ALL}" 1491 | ) 1492 | 1493 | if not supplied_balance or supplied_balance < self.withdraw_amount: 1494 | self.log( 1495 | f"{Fore.CYAN+Style.BRIGHT} Status :{Style.RESET_ALL}" 1496 | f"{Fore.YELLOW+Style.BRIGHT} Supplied {ticker} Token Balance Less Than Withdraw Amount {Style.RESET_ALL}" 1497 | ) 1498 | continue 1499 | 1500 | await self.process_perform_withdraw(account, address, asset_address, self.withdraw_amount, ticker, use_proxy) 1501 | await self.print_timer() 1502 | 1503 | async def process_accounts(self, account: str, address: str, option: int, use_proxy: bool, rotate_proxy: bool): 1504 | is_valid = await self.process_check_connection(address, use_proxy, rotate_proxy) 1505 | if is_valid: 1506 | 1507 | try: 1508 | web3 = await self.get_web3_with_check(address, use_proxy) 1509 | except Exception as e: 1510 | self.log( 1511 | f"{Fore.CYAN+Style.BRIGHT}Status :{Style.RESET_ALL}" 1512 | f"{Fore.RED+Style.BRIGHT} Web3 Not Connected {Style.RESET_ALL}" 1513 | f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}" 1514 | f"{Fore.YELLOW+Style.BRIGHT} {str(e)} {Style.RESET_ALL}" 1515 | ) 1516 | return 1517 | 1518 | self.used_nonce[address] = web3.eth.get_transaction_count(address, "pending") 1519 | 1520 | if option == 1: 1521 | self.log( 1522 | f"{Fore.CYAN+Style.BRIGHT}Option :{Style.RESET_ALL}" 1523 | f"{Fore.BLUE+Style.BRIGHT} Mint Faucets {Style.RESET_ALL}" 1524 | ) 1525 | await self.process_option_1(account, address, use_proxy) 1526 | 1527 | elif option == 2: 1528 | self.log( 1529 | f"{Fore.CYAN+Style.BRIGHT}Option :{Style.RESET_ALL}" 1530 | f"{Fore.BLUE+Style.BRIGHT} Deposit PHRS {Style.RESET_ALL}" 1531 | ) 1532 | await self.process_option_2(account, address, use_proxy) 1533 | 1534 | elif option == 3: 1535 | self.log( 1536 | f"{Fore.CYAN+Style.BRIGHT}Option :{Style.RESET_ALL}" 1537 | f"{Fore.BLUE+Style.BRIGHT} Supply Assets {Style.RESET_ALL}" 1538 | ) 1539 | await self.process_option_3(account, address, use_proxy) 1540 | 1541 | elif option == 4: 1542 | self.log( 1543 | f"{Fore.CYAN+Style.BRIGHT}Option :{Style.RESET_ALL}" 1544 | f"{Fore.BLUE+Style.BRIGHT} Borrow Assets {Style.RESET_ALL}" 1545 | ) 1546 | await self.process_option_4(account, address, use_proxy) 1547 | 1548 | elif option == 5: 1549 | self.log( 1550 | f"{Fore.CYAN+Style.BRIGHT}Option :{Style.RESET_ALL}" 1551 | f"{Fore.BLUE+Style.BRIGHT} Repay Assets {Style.RESET_ALL}" 1552 | ) 1553 | await self.process_option_5(account, address, use_proxy) 1554 | 1555 | elif option == 6: 1556 | self.log( 1557 | f"{Fore.CYAN+Style.BRIGHT}Option :{Style.RESET_ALL}" 1558 | f"{Fore.BLUE+Style.BRIGHT} Withdraw Assets {Style.RESET_ALL}" 1559 | ) 1560 | await self.process_option_6(account, address, use_proxy) 1561 | 1562 | else: 1563 | self.log( 1564 | f"{Fore.CYAN+Style.BRIGHT}Option :{Style.RESET_ALL}" 1565 | f"{Fore.BLUE+Style.BRIGHT} Run All Features {Style.RESET_ALL}" 1566 | ) 1567 | await self.process_option_1(account, address, use_proxy) 1568 | 1569 | await self.process_option_2(account, address, use_proxy) 1570 | 1571 | await self.process_option_3(account, address, use_proxy) 1572 | 1573 | await self.process_option_4(account, address, use_proxy) 1574 | 1575 | await self.process_option_5(account, address, use_proxy) 1576 | 1577 | await self.process_option_6(account, address, use_proxy) 1578 | 1579 | async def main(self): 1580 | try: 1581 | with open('accounts.txt', 'r') as file: 1582 | accounts = [line.strip() for line in file if line.strip()] 1583 | 1584 | option, proxy_choice, rotate_proxy = self.print_question() 1585 | 1586 | use_proxy = True if proxy_choice == 1 else False 1587 | 1588 | while True: 1589 | self.clear_terminal() 1590 | self.welcome() 1591 | self.log( 1592 | f"{Fore.GREEN + Style.BRIGHT}Account's Total: {Style.RESET_ALL}" 1593 | f"{Fore.WHITE + Style.BRIGHT}{len(accounts)}{Style.RESET_ALL}" 1594 | ) 1595 | 1596 | if use_proxy: 1597 | await self.load_proxies() 1598 | 1599 | separator = "=" * 25 1600 | for account in accounts: 1601 | if account: 1602 | address = self.generate_address(account) 1603 | 1604 | self.log( 1605 | f"{Fore.CYAN + Style.BRIGHT}{separator}[{Style.RESET_ALL}" 1606 | f"{Fore.WHITE + Style.BRIGHT} {self.mask_account(address)} {Style.RESET_ALL}" 1607 | f"{Fore.CYAN + Style.BRIGHT}]{separator}{Style.RESET_ALL}" 1608 | ) 1609 | 1610 | if not address: 1611 | self.log( 1612 | f"{Fore.CYAN + Style.BRIGHT}Status :{Style.RESET_ALL}" 1613 | f"{Fore.RED + Style.BRIGHT} Invalid Private Key or Library Version Not Supported {Style.RESET_ALL}" 1614 | ) 1615 | continue 1616 | 1617 | await self.process_accounts(account, address, option, use_proxy, rotate_proxy) 1618 | await asyncio.sleep(3) 1619 | 1620 | self.log(f"{Fore.CYAN + Style.BRIGHT}={Style.RESET_ALL}"*72) 1621 | seconds = 24 * 60 * 60 1622 | while seconds > 0: 1623 | formatted_time = self.format_seconds(seconds) 1624 | print( 1625 | f"{Fore.CYAN+Style.BRIGHT}[ Wait for{Style.RESET_ALL}" 1626 | f"{Fore.WHITE+Style.BRIGHT} {formatted_time} {Style.RESET_ALL}" 1627 | f"{Fore.CYAN+Style.BRIGHT}... ]{Style.RESET_ALL}" 1628 | f"{Fore.WHITE+Style.BRIGHT} | {Style.RESET_ALL}" 1629 | f"{Fore.BLUE+Style.BRIGHT}All Accounts Have Been Processed.{Style.RESET_ALL}", 1630 | end="\r" 1631 | ) 1632 | await asyncio.sleep(1) 1633 | seconds -= 1 1634 | 1635 | except FileNotFoundError: 1636 | self.log(f"{Fore.RED}File 'accounts.txt' Not Found.{Style.RESET_ALL}") 1637 | return 1638 | except Exception as e: 1639 | self.log(f"{Fore.RED+Style.BRIGHT}Error: {e}{Style.RESET_ALL}") 1640 | raise e 1641 | 1642 | if __name__ == "__main__": 1643 | try: 1644 | bot = OpenFi() 1645 | asyncio.run(bot.main()) 1646 | except KeyboardInterrupt: 1647 | print( 1648 | f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}" 1649 | f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}" 1650 | f"{Fore.RED + Style.BRIGHT}[ EXIT ] OpenFi - BOT{Style.RESET_ALL} " 1651 | ) --------------------------------------------------------------------------------