Core Components: - uniswap_manager.py: V3 concentrated liquidity position manager - clp_hedger.py: Hyperliquid perpetuals hedging bot - requirements.txt: Python dependencies - .gitignore: Security exclusions for sensitive data - doc/: Project documentation - tools/: Utility scripts and Git agent Features: - Automated liquidity provision on Uniswap V3 (WETH/USDC) - Delta-neutral hedging using Hyperliquid perpetuals - Position lifecycle management (open/close/rebalance) - Automated backup and version control system Security: - Private keys and tokens excluded from version control - Environment variables properly handled - Automated security validation for backups Git Agent: - Hourly automated backups to separate branches - Keep last 100 backups (~4 days coverage) - Detailed change tracking and parameter monitoring - Push to Gitea server automatically - Manual main branch control preserved - No performance tracking for privacy - No notifications for simplicity Files Added: - git_agent.py: Main automation script - agent_config.json: Configuration with Gitea settings - git_utils.py: Git operations wrapper - backup_manager.py: Backup branch management - change_detector.py: File change analysis - cleanup_manager.py: 100-backup rotation - commit_formatter.py: Detailed commit messages - README_GIT_AGENT.md: Complete usage documentation
140 lines
5.6 KiB
Markdown
140 lines
5.6 KiB
Markdown
# Python Blockchain Development & Review Guidelines
|
|
|
|
## Overview
|
|
This document outlines the standards for writing, reviewing, and deploying Python scripts that interact with EVM-based blockchains (Ethereum, Arbitrum, etc.). These guidelines prioritize **capital preservation**, **transaction robustness**, and **system stability**.
|
|
|
|
---
|
|
|
|
## 1. Transaction Handling & Lifecycle
|
|
*High-reliability transaction management is the core of a production bot. Never "fire and forget."*
|
|
|
|
### 1.1. Timeout & Receipt Management
|
|
- **Requirement:** Never send a transaction without immediately waiting for its receipt or tracking its hash.
|
|
- **Why:** The RPC might accept the tx, but it could be dropped from the mempool or stuck indefinitely.
|
|
- **Code Standard:**
|
|
```python
|
|
# BAD
|
|
w3.eth.send_raw_transaction(signed_txn.rawTransaction)
|
|
|
|
# GOOD
|
|
tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
|
|
try:
|
|
receipt = w3.eth.wait_for_transaction_receipt(tx_hash, timeout=120)
|
|
except TimeExhausted:
|
|
# Handle stuck transaction (bump gas or cancel)
|
|
handle_stuck_transaction(tx_hash)
|
|
```
|
|
|
|
### 1.2. Verification of Success
|
|
- **Requirement:** Explicitly check `receipt.status == 1`.
|
|
- **Why:** A transaction can be mined (success=True) but execution can revert (status=0).
|
|
- **Code Standard:**
|
|
```python
|
|
if receipt.status != 1:
|
|
raise TransactionRevertedError(f"Tx {tx_hash.hex()} reverted on-chain")
|
|
```
|
|
|
|
### 1.3. Gas Management & Stuck Transactions
|
|
- **Requirement:** Do not hardcode gas prices. Use dynamic estimation.
|
|
- **Mechanism:**
|
|
- For EIP-1559 chains (Arbitrum/Base/Mainnet), use `maxFeePerGas` and `maxPriorityFeePerGas`.
|
|
- Implement a "Gas Bumping" mechanism: If a tx is not mined in $X$ seconds, resubmit with 10-20% higher gas using the **same nonce**.
|
|
|
|
### 1.4. Nonce Management
|
|
- **Requirement:** In high-frequency loops, track the nonce locally.
|
|
- **Why:** `w3.eth.get_transaction_count(addr, 'pending')` is often slow or eventually consistent on some RPCs, leading to "Nonce too low" or "Replacement transaction underpriced" errors.
|
|
|
|
---
|
|
|
|
## 2. Financial Logic & Precision
|
|
|
|
### 2.1. No Floating Point Math for Token Amounts
|
|
- **Requirement:** NEVER use standard python `float` for calculating token amounts or prices involved in protocol interactions.
|
|
- **Standard:** Use `decimal.Decimal` or integer math (Wei).
|
|
- **Why:** `0.1 + 0.2 != 0.3` in floating point. This causes dust errors and "Insufficient Balance" reverts.
|
|
```python
|
|
# BAD
|
|
amount = balance * 0.5
|
|
|
|
# GOOD
|
|
amount = int(Decimal(balance) * Decimal("0.5"))
|
|
```
|
|
|
|
### 2.2. Slippage Protection
|
|
- **Requirement:** Never use `0` for `amountOutMinimum` or `sqrtPriceLimitX96` in production.
|
|
- **Standard:** Calculate expected output and apply a config-defined slippage (e.g., 0.1%).
|
|
- **Why:** Front-running and sandwich attacks will drain value from `amountOutMin: 0` trades.
|
|
|
|
### 2.3. Approval Handling
|
|
- **Requirement:** Check allowance before approving.
|
|
- **Standard:**
|
|
- Verify `allowance >= amount`.
|
|
- If `allowance == 0`, approve.
|
|
- **Note:** Some tokens (USDT) require approving `0` before approving a new amount if an allowance already exists.
|
|
|
|
---
|
|
|
|
## 3. Security & Safety
|
|
|
|
### 3.1. Secrets Management
|
|
- **Requirement:** No private keys or mnemonics in source code.
|
|
- **Standard:** Use `.env` files (loaded via `python-dotenv`) or proper secrets managers.
|
|
- **Review Check:** `grep -r "0x..." .` to ensure no keys were accidentally committed.
|
|
|
|
### 3.2. Address Validation
|
|
- **Requirement:** All addresses must be checksummed before use.
|
|
- **Standard:**
|
|
```python
|
|
# Input
|
|
target_address = "0xc364..."
|
|
|
|
# Validation
|
|
if not Web3.is_address(target_address):
|
|
raise ValueError("Invalid address")
|
|
checksum_address = Web3.to_checksum_address(target_address)
|
|
```
|
|
|
|
### 3.3. Simulation (Dry Run)
|
|
- **Requirement:** For complex logic (like batch swaps), use `contract.functions.method().call()` before `.build_transaction()`.
|
|
- **Why:** If the `.call()` fails (reverts), the transaction will definitely fail. Save gas by catching logic errors off-chain.
|
|
|
|
---
|
|
|
|
## 4. Coding Style & Observability
|
|
|
|
### 4.1. Logging
|
|
- **Requirement:** No `print()` statements. Use `logging` module.
|
|
- **Standard:**
|
|
- `INFO`: High-level state changes (e.g., "Position Opened").
|
|
- `DEBUG`: API responses, specific calc steps.
|
|
- `ERROR`: Stack traces and critical failures.
|
|
- **Traceability:** Log the Transaction Hash **immediately** upon sending, not after waiting. If the script crashes while waiting, you need the hash to check the chain manually.
|
|
|
|
### 4.2. Idempotency & State Recovery
|
|
- **Requirement:** Scripts must be restartable without double-spending.
|
|
- **Standard:** Before submitting a "Open Position" transaction, read the chain (or `hedge_status.json`) to ensure a position isn't already open.
|
|
|
|
### 4.3. Type Hinting
|
|
- **Requirement:** Use Python type hints for clarity.
|
|
- **Standard:**
|
|
```python
|
|
def execute_swap(
|
|
token_in: str,
|
|
amount: int,
|
|
slippage_pct: float = 0.5
|
|
) -> str: # Returns tx_hash
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Review Checklist (Copy-Paste for PRs)
|
|
|
|
- [ ] **Secrets:** No private keys in code?
|
|
- [ ] **Math:** Is `Decimal` or Integer math used for all financial calcs?
|
|
- [ ] **Slippage:** Is `amountOutMinimum` > 0?
|
|
- [ ] **Timeouts:** Does `wait_for_transaction_receipt` have a timeout?
|
|
- [ ] **Status Check:** Is `receipt.status` checked for success/revert?
|
|
- [ ] **Gas:** Are gas limits and prices dynamic/reasonable?
|
|
- [ ] **Addresses:** Are all addresses Checksummed?
|
|
- [ ] **Restartability:** What happens if the script dies halfway through?
|