A Python-based bot for detecting and executing price differences between AMM pools and external markets on the Strato blockchain. Also scans for under-collateralized CDP (Collateralized Debt Position) positions and executes profitable liquidations. Supports multiple pools simultaneously.
arbitrage_bot/
├── core/ # Core utilities
│ ├── strato_client.py # Strato blockchain interaction
│ ├── oauth_client.py # OAuth authentication
│ ├── constants.py # Configuration constants (WEI_SCALE, BPS_DENOM, USDST_ADDRESS)
│ └── math_utils.py # Mathematical calculations (wei-based, closed-form optimal input)
├── onchain/ # Blockchain contracts
│ ├── token.py # Token wrapper
│ ├── pool.py # AMM pool wrapper (includes position tracking)
│ └── cdp.py # CDP liquidation contract wrapper
├── market/ # Market data
│ └── oracle.py # Price oracle (BlockApps on-chain PriceOracle)
├── engine/ # Arbitrage & liquidation logic
│ ├── arb_executor.py # Opportunity detection and trade execution
│ ├── liquidation_executor.py # CDP liquidation scanning and execution
│ └── helpers.py # Helper functions (approvals, gas checks, PnL checks, profit tracking)
├── config.yaml # Configuration (multi-pool support)
├── main.py # Main application
├── requirements.txt # Python dependencies
└── README.md # Documentation
-
Create and activate virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
-
Create a
.envfile in the project root (see.env.examplefor template):# Strato Blockchain Configuration STRATO_NODE_URL=https://your-strato-node-url.com USERNAME=your_username PASSWORD=your_password # OAuth Configuration OAUTH_CLIENT_ID=your_oauth_client_id OAUTH_CLIENT_SECRET=your_oauth_client_secret OAUTH_DISCOVERY_URL=https://your-oauth-discovery-url.com
Note: Make sure
.envis in.gitignoreto avoid committing sensitive credentials.The bot reads all market prices from the BlockApps on-chain
PriceOraclecontract (configured viaoracle.blockapps_price_oracleinconfig.yaml). No external pricing API key is required — every non-USDST token used by a configured pool must have a corresponding price entry in that contract. USDST is hardcoded to $1. -
Edit
config.yaml:pools: - address: "0000000000000000000000000000000000001017" # ETH-USDST pool - address: "000000000000000000000000000000000000101b" # GOLDST-USDST pool # Trading Parameters trading: fee_bps: 30 # Pool fee in basis points (0.3%) min_profit: 0.01 # $0.01 minimum profit (in USDST, wei-scaled) # Oracle Configuration oracle: timeout: 10 blockapps_price_oracle: "0000000000000000000000000000000000001002" # CDP Liquidation Settings liquidation: enabled: true # Execution Settings execution: execution_interval: 60 # seconds between scans
The bot runs in dry-run mode by default, which means it will scan for opportunities and log what it would do, but will not execute any trades.
python main.pyTo execute actual trades, use the --live flag:
# Set all required environment variables (see Installation section)
python main.py --liveYou can specify a custom config file:
python main.py --config custom_config.yaml-
Multi-Pool Scanning: The bot scans all configured pools sequentially, checking each for arbitrage opportunities.
-
Price Discovery: For each pool, the bot:
- Fetches the current pool price (from on-chain reserves)
- Fetches the oracle price for every coin from the BlockApps on-chain
PriceOraclecontract (USDST is treated as a fixed $1) - Compares the two prices to detect arbitrage opportunities
- If any required price is missing from the on-chain oracle, the scan is skipped
for that pool and a Slack alert is sent (see
core/notifier.py)
-
Opportunity Detection: When a price difference is detected, the bot:
- Calculates the optimal trade size using a closed-form solution that maximizes profit
- Automatically determines the most profitable direction (buy or sell)
- Validates that the profit meets the minimum threshold
-
Gas Management: The bot automatically:
- Reserves 0.01 USDST (or checks for vouchers ≥ 1 voucher = 1e18 wei) for gas fees
- Adjusts token balances to account for gas reserves before calculating trade sizes
- If trading USDST, the balance is reduced by 0.01 USDST to ensure gas availability
-
Position Tracking: For sell opportunities, the bot:
- Checks the weighted-average cost basis from historical trades
- Ensures the trade would be profitable (avoids selling at a loss)
- Uses Cirrus search API to query historical swap data
-
Execution: If an opportunity meets all criteria:
- Profit threshold met
- Gas availability confirmed
- Cost basis check passed (for sells)
- The bot executes the trade and updates cumulative profit tracking
-
Profit Tracking: After each successful trade, the bot:
- Updates cumulative profit in
profit.json - Uses thread-safe file locking to prevent race conditions
- Tracks both wei-scaled and USD values
- Updates cumulative profit in
-
CDP Liquidation Scanning: When enabled, the bot also scans for under-collateralized CDP positions:
- Queries the
/api/cdp/liquidatableendpoint for positions eligible for liquidation - Filters out positions with missing fields or zero debt
- Queries the
-
Liquidation Execution: For each liquidatable position, the bot:
- Calls the
/api/cdp/liquidateendpoint with the collateral asset, borrower address, and debt to cover - Estimates profit as
debtToCover × closeFactorBps × liquidationPenaltyBps(currently 5% of debt) - Tracks liquidation profit separately in
liquidation_profit.json
- Calls the
- Multi-Pool Support: Monitor and trade across multiple pools simultaneously
- Automatic Direction Selection: Automatically determines whether to buy or sell based on which direction is more profitable
- Closed-Form Optimal Input: Uses mathematical optimization to calculate the exact trade size that maximizes profit
- Gas-Aware Trading: Automatically reserves gas fees and adjusts balances accordingly
- Cost Basis Protection: Prevents selling at a loss by tracking weighted-average cost basis
- Thread-Safe Execution: Uses locks to prevent concurrent execution
- Dry-Run Mode: Safe testing mode enabled by default
- Cumulative Profit Tracking: Tracks total profit across all trades in
profit.json - CDP Liquidation: Scans for under-collateralized positions and executes profitable liquidations
- Detailed Logging: Comprehensive logging with reasons for each decision
Each pool in the pools array requires:
address: The pool contract address on Strato
Token symbols and addresses are discovered automatically from the pool contract.
Each non-USDST token must already have a price entry in the BlockApps on-chain
PriceOracle (configured via oracle.blockapps_price_oracle).
fee_bps: Pool fee in basis points (e.g., 30 = 0.3%)min_profit: Minimum profit threshold in USD (e.g., 0.01 = $0.01)
enabled: Enable or disable CDP liquidation scanning (default:false)
execution_interval: Seconds between scans (default: 60)
The bot provides detailed logging for each pool scan:
2025-11-07 14:14:19,004 - INFO - Pool price: 3418.012526 USDST per ETHST
2025-11-07 14:14:19,004 - INFO - Oracle price: 3422.734977 USDST per ETHST
2025-11-07 14:14:19,004 - INFO - Price diff: 4.722451 USDST (0.13%)
2025-11-07 14:14:19,004 - INFO - No arbitrage opportunity found - Profit too low for Y->X (profit=-0.000177, min_profit=0.01)
2025-11-07 14:14:19,004 - INFO - Pool price: 102541.701361 USDST per BTCST
2025-11-07 14:14:19,004 - INFO - Oracle price: 102489.875571 USDST per BTCST
2025-11-07 14:14:19,004 - INFO - Price diff: -51.825789 USDST (-0.06%)
2025-11-07 14:14:19,004 - INFO - No arbitrage opportunity found - No input available for X->Y (dx_opt=32959367722980, balance_x=0)
2025-11-07 14:14:20,112 - INFO - Liquidatable: borrower=0x1234abcd5678… collateral=0xdeadbeef0000… debt=50000000000000000000
2025-11-07 14:14:20,112 - INFO - Found 1 liquidatable CDP position(s)
2025-11-07 14:14:20,500 - INFO - Liquidation succeeded in 0.39s: {...}
profit.json: Cumulative arbitrage profit tracking file (created automatically){ "cumulative_profit_wei": 10000000000000000, "cumulative_profit_usd": 0.01 }liquidation_profit.json: Cumulative liquidation profit tracking file (created automatically, same format asprofit.json)
This software is for educational purposes only. Trading cryptocurrencies involves substantial risk of loss. Use at your own risk and never trade with more than you can afford to lose.