Skip to content

feat(core): add TOML config loader with ${ENV_VAR} substitution#29

Merged
obchain merged 3 commits into
mainfrom
feat/04-toml-config-loader
Apr 24, 2026
Merged

feat(core): add TOML config loader with ${ENV_VAR} substitution#29
obchain merged 3 commits into
mainfrom
feat/04-toml-config-loader

Conversation

@obchain
Copy link
Copy Markdown
Owner

@obchain obchain commented Apr 21, 2026

Closes #5

Loads config/default.toml, substitutes ${ENV_VAR} placeholders from the environment at load time, and parses into strongly-typed structs.

  • Config — top-level (bot, chain, protocol, flashloan, liquidator)
  • BotConfigmin_profit_usd, max_gas_gwei, scan interval
  • ChainConfig, ProtocolConfig, FlashLoanConfig, LiquidatorConfig
  • .env.example documents the expected variables; real secrets never touch TOML

Default v0.1 config targets Venus on BNB Chain (single chain, single protocol, single flash-loan source).

Depends on #4 (feat/03-lending-protocol-trait).

Introduce the Config struct hierarchy covering bot-level knobs, per-chain
RPC endpoints, per-protocol addresses, flash-loan sources, and deployed
liquidator contracts. Keyed by short names (HashMap<String, T>) so adding
new chains/protocols later is a config change rather than a schema change.

Config::load(path):
  1. reads the TOML file
  2. substitutes \${VAR} placeholders from process env (errors if unset)
  3. deserializes into Config via serde

Ship config/default.toml with real BSC addresses for Venus Unitroller and
Aave V3 Pool (flashLoanSimple source). Liquidator contract address is a
placeholder until CharonLiquidator.sol is deployed.

.env.example documents the two required env vars (BNB_WS_URL, BNB_HTTP_URL)
with public-node defaults for testing.
…dation, ConfigError

- Integer money: BotConfig.min_profit_usd -> min_profit_usd_1e6: u64
  (USD × 1e6 fixed-point); BotConfig.max_gas_gwei -> max_gas_wei: U256
  via decimal-or-hex string deser. Removes f64 precision/NaN risk and
  lets gas caps express sub-gwei priority fees.
- Secret redaction: ChainConfig and Config now have manual Debug impls
  that print '<redacted>' for ws_url / http_url and '<N chains redacted>'
  so the log sink and panic messages cannot leak API keys embedded in
  RPC URLs.
- Cross-reference validation: Config::load now calls validate() which
  rejects protocol/flashloan/liquidator entries whose  does not
  exist in [chain.*] and rejects zero addresses. Empty [chain.*] errors.
- #[serde(deny_unknown_fields)] on every config struct so typos (e.g.
  ) error at load instead of silently defaulting the
  profit floor to zero.
- Env-var substitution is now TOML-escape-aware (\, ", \n, \r, \t
  in values do not break the enclosing string), supports
  default, and rejects invalid env-var names.
- Structured ConfigError (NotFound / Io / UnsetEnvVar / InvalidEnvVarName
  / UnterminatedInterp / Parse / Parse / Validation) with #[non_exhaustive]
  so the CLI can map to exit codes and operators see actionable messages.
- Config::from_str added for unit tests; config/default.toml updated to
  the new field names and the zero-address liquidator placeholder is
  removed (validation now rejects it).

Closes #75 #76 #77 #78 #79 #80 #81
…oader

# Conflicts:
#	Cargo.lock
#	crates/charon-core/Cargo.toml
#	crates/charon-core/src/lib.rs
@obchain obchain merged commit 68f0b72 into main Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[core] TOML config loader with ${ENV_VAR} substitution

1 participant