Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaammerr committed May 3, 2024
0 parents commit 9eae464
Show file tree
Hide file tree
Showing 15 changed files with 577 additions and 0 deletions.
161 changes: 161 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Byte-compiled / optimized / DLL files
__pycache__/
.idea/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Sepolia Auto Faucet (L0, testnet bridge)

## 🔗 Links

🔔 CHANNEL: https://t.me/JamBitPY

💬 CHAT: https://t.me/JamBitChat

💰 DONATION EVM ADDRESS: 0xe23380ae575D990BebB3b81DB2F90Ce7eDbB6dDa


## 📜 Description
This script uses the L0 bridge https://testnetbridge.com/sepolia to automatically obtain Sepolia test tokens from the ARB network. The exchange rate can be found on the bridge website.

The script will take a random ETH value based on min_amount and max_amount in config for bridge.

```At the time of publication 0.0000323 ETH (0.1$) ARB = 1 ETH Sepolia```


## 📦 Installation
`` Required python >= 3.10``

``1. Close the repo and open CMD (console) inside it``

``2. Install requirements: pip install -r requirements.txt``

``3. Setup configuration and accounts``

``4. Run: python run.py``


## ⚙️ Config (config > settings.yaml)

| Name | Description |
| --- |----------------------------------------------------|
| threads | number of accounts that will work in parallel |
| arb_rpc | ARB RPC URL (if not have, leave the default value) |
| min_amount | min amount to bridge (in ETH) |
| max_amount | max amount to bridge (in ETH) |
| delay_before_start_min | min delay before account starts working |
| delay_before_start_max | max delay before account starts working |


## ⚙️ Accounts format (config > accounts.txt)

- private_key
- mnemonic


## 📝 Results

```angular2html
The script will save success/failed accounts to config > success_accounts.txt and config > failed_accounts.txt
```
1 change: 1 addition & 0 deletions abi/geth_token_abi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH9","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WETH9","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"quoteExactInput","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"name":"quoteExactInputSingle","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"quoteExactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"name":"quoteExactOutputSingle","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"amount0Delta","type":"int256"},{"internalType":"int256","name":"amount1Delta","type":"int256"},{"internalType":"bytes","name":"path","type":"bytes"}],"name":"uniswapV3SwapCallback","outputs":[],"stateMutability":"view","type":"function"}]
1 change: 1 addition & 0 deletions abi/sepolia_abi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"inputs":[{"internalType":"address","name":"_weth","type":"address"},{"internalType":"address","name":"_oft","type":"address"},{"internalType":"address","name":"_universalRouter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"oft","outputs":[{"internalType":"contract IOFTCore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint16","name":"dstChainId","type":"uint16"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address payable","name":"refundAddress","type":"address"},{"internalType":"address","name":"zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"adapterParams","type":"bytes"}],"name":"swapAndBridge","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"universalRouter","outputs":[{"internalType":"contract IUniversalRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
4 changes: 4 additions & 0 deletions config/accounts.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mnemonic/pk
mnemonic/pk
mnemonic/pk
mnemonic/pk
55 changes: 55 additions & 0 deletions config/load_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import os
import yaml

from loguru import logger
from models import Config


def get_accounts() -> list[str]:
accounts_path = os.path.join(os.path.dirname(__file__), "accounts.txt")
if not os.path.exists(accounts_path):
logger.error(f"File <<{accounts_path}>> does not exist")
exit(1)

with open(accounts_path, "r") as f:
accounts = f.readlines()

if not accounts:
logger.error(f"File <<{accounts_path}>> is empty")
exit(1)

return accounts


def load_config() -> Config:
settings_path = os.path.join(os.path.dirname(__file__), "settings.yaml")
if not os.path.exists(settings_path):
logger.error(f"File <<{settings_path}>> does not exist")
exit(1)

with open(settings_path, "r") as f:
settings = yaml.safe_load(f)

REQUIRED_KEYS = (
"threads",
"min_amount",
"max_amount",
"arb_rpc",
"delay_before_start_min",
"delay_before_start_max",
)

for key in REQUIRED_KEYS:
if key not in settings:
logger.error(f"Key <<{key}>> is missing in settings.yaml")
exit(1)

return Config(
accounts=get_accounts(),
threads=settings.get("threads"),
min_amount=settings.get("min_amount"),
max_amount=settings.get("max_amount"),
arb_rpc=settings.get("arb_rpc"),
delay_before_start_min=settings.get("delay_before_start_min"),
delay_before_start_max=settings.get("delay_before_start_max"),
)
8 changes: 8 additions & 0 deletions config/settings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
threads: 5
arb_rpc: https://arb1.arbitrum.io/rpc

min_amount: 0.000001
max_amount: 0.000002

delay_before_start_min: 30
delay_before_start_max: 60
3 changes: 3 additions & 0 deletions loader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from config.load_config import load_config

config = load_config()
2 changes: 2 additions & 0 deletions models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .config import *
from .onchain import *
14 changes: 14 additions & 0 deletions models/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from dataclasses import dataclass


@dataclass
class Config:
accounts: list[str]
threads: int
arb_rpc: str

min_amount: float
max_amount: float

delay_before_start_min: int
delay_before_start_max: int
10 changes: 10 additions & 0 deletions models/onchain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from dataclasses import dataclass


@dataclass
class OnchainData:
bridge_contract: str = "0xfcA99F4B5186D4bfBDbd2C542dcA2ecA4906BA45"
bridge_abi: list = open("./abi/sepolia_abi.json", "r").read()

uniswap_quoter: str = "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6"
uniswap_quoter_abi: list = open("./abi/geth_token_abi.json", "r").read()
7 changes: 7 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
requests~=2.31.0
hexbytes~=0.3.1
loguru~=0.7.2
web3~=6.18.0
urllib3~=2.2.1
art~=6.2
PyYAML~=6.0.1
27 changes: 27 additions & 0 deletions run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from concurrent.futures import ThreadPoolExecutor

from src.main import SepoliaFaucet
from src.util import export_wallets, show_dev_info, setup

from loader import config
from loguru import logger


def run():
setup()
show_dev_info()
logger.info(
f"\n\nBot Started | Threads: {config.threads} | Accounts: {len(config.accounts)}\n\n"
)

with ThreadPoolExecutor(max_workers=config.threads) as executor:
tasks = [
executor.submit(SepoliaFaucet(account.strip()).send_transaction_safe)
for account in config.accounts
]

export_wallets(tasks)


if __name__ == "__main__":
run()
Loading

0 comments on commit 9eae464

Please sign in to comment.