Skip to content

fix(flashloan): correct Aave V3 BSC PoolDataProvider + tolerate truncated getReserveData (closes #419)#421

Merged
obchain merged 2 commits intomainfrom
fix/419-aave-bsc-data-provider
May 3, 2026
Merged

fix(flashloan): correct Aave V3 BSC PoolDataProvider + tolerate truncated getReserveData (closes #419)#421
obchain merged 2 commits intomainfrom
fix/419-aave-bsc-data-provider

Conversation

@obchain
Copy link
Copy Markdown
Owner

@obchain obchain commented May 3, 2026

Summary

Two related defects on the Aave V3 BSC flash-loan path that together silenced the only flash-loan source on every fork demo and live run:

  1. `config/default.toml` and `config/fork.toml` baked the PoolDataProvider as `0x41393e5e337606dc3821075Af65AeE84D7688CBD` — that address has no code on BSC mainnet (`cast code` returns `0x`). Calls returned an empty buffer, surfaced as `buffer overrun` decode errors at every quote step.
  2. With the right data provider in place, `getReserveData` returns 12 fields on BSC, not the 15 our `sol!` ABI declares (newer-Aave fields `accruedToTreasury`, `unbacked`, `isolationModeTotalDebt` absent on BSC). Strict typed decoder still rejected the truncated tuple.

Fix

  • Update both configs to `0xc90Df74A7c16245c5F5C5870327Ceb38Fe5d5328` (sourced via `IPoolAddressesProvider.getPoolDataProvider()` on BSC).
  • Add `read_uint256_first_word` helper for `getReserveData` — we only consume the leading `configuration` word for paused/frozen bitmap, so issue the call ourselves and lift first 32 bytes. `getReserveConfigurationData` stays on typed decode (its 10-tuple matches BSC).

Test plan

obchain added 2 commits May 3, 2026 22:16
…ated getReserveData (closes #419)

Two related defects on the Aave V3 BSC flash-loan path that together
silenced the only flash-loan source on every fork demo and live run:

1. `config/default.toml` and `config/fork.toml` baked the
   PoolDataProvider as 0x41393e5e337606dc3821075Af65AeE84D7688CBD,
   which has no code on BSC mainnet — `cast code` returns 0x at
   any block. Calls returned an empty buffer and surfaced as
   "buffer overrun" decode errors at every quote step. Sourced the
   correct address from IPoolAddressesProvider.getPoolDataProvider()
   on BSC: 0xc90Df74A7c16245c5F5C5870327Ceb38Fe5d5328. Updated both
   profiles with a comment pointing at the on-chain source-of-truth
   so future drift is easier to spot.

2. With the right data provider in place, `getReserveData` returns
   12 fields on BSC, not the 15 our `sol!` ABI declares — newer-Aave
   fields (`accruedToTreasury`, `unbacked`, `isolationModeTotalDebt`)
   are absent on BSC's deploy. The strict typed decoder still rejects
   the truncated tuple, breaking every paused/frozen-bitmap probe.
   We only consume the leading `configuration` word for that check,
   so issue the call ourselves and lift the first 32 bytes via a new
   `read_uint256_first_word` helper. `getReserveConfigurationData`
   stays on the typed decode (its 10-tuple matches BSC).

Local validation: replay against block 91323624 with the four
documented seed borrowers now reaches the flash-loan quote stage
without buffer-overrun warnings (build pending in companion test
branch that also carries #418's vToken decoder relaxation).
@obchain obchain merged commit cd8ebbf into main May 3, 2026
4 checks passed
@obchain obchain deleted the fix/419-aave-bsc-data-provider branch May 3, 2026 16:56
obchain added a commit that referenced this pull request May 6, 2026
…gate (#427)

* feat: multi-protocol trait, Aave V3 on Ethereum, bps margin profit gate

Three coupled changes that ship v0.2 of the bot.

1. min_profit_margin_bps replaces the absolute USD floor

The old min_profit_usd_1e6 = $5 floor scaled poorly: loose on small trades,
meaningless on large ones. Replaced with a basis-points margin gate:

    gross_swap_output_wei >= total_cost_wei * (10_000 + min_profit_margin_bps) / 10_000

Default 1000 bps (10% margin), validated <= 10_000. Drop reason
BelowMinMargin. Field added to BotConfig with serde default; fork profile
lowers to 100 bps for demo staging.

2. LendingProtocol trait + ProtocolKind factory

Pipeline now holds Arc<dyn LendingProtocol> and never names a concrete
adapter. ProtocolKind enum is #[non_exhaustive] so adding variants is
non-breaking. Factory in charon-protocols/src/lib.rs matches on the kind
and returns a trait object.

VenusAdapter migrated to impl LendingProtocol unchanged behaviourally.
Scanner, executor, profit calc, queue, simulator, submitter, metrics
emitter, and Grafana dashboard are protocol-agnostic.

3. Aave V3 adapter + Ethereum support

AaveV3Adapter implements LendingProtocol against the Aave V3 Pool and
PoolDataProvider. Tolerates Ethereum's 15-field getReserveData tuple via
the same lenient decoder used for BSC's truncated 12-field tuple (PR #421).

CharonLiquidatorAave.sol is the on-chain twin: Aave flashLoanSimple ->
Pool.liquidationCall -> Uniswap V3 exactInputSingle -> repay Aave + 5 bps
premium -> sweep residual to immutable cold wallet.

config/fork-eth.toml ships a complete Ethereum fork profile pinned at
block 20459016 (Aug 5 2024 yen-unwind cascade). deploy/compose/local-stack-eth.yml
runs Prometheus + Grafana on parallel ports (9093 / 3001) so BSC and ETH
stacks can run side-by-side without collision.

Demo numbers reproducible:

  cargo run -p charon-cli --release -- --config config/fork-eth.toml \
    replay --protocol aave_v3_eth --block 20459016 \
    --borrower-file /tmp/seed-eth.txt --hold-secs 600

emits 2 / 4 seeded borrowers, total predicted net profit $14,538.74. The
two silent drops between profit gate and queue (LINK collateral, USDC->WETH
single-hop) are tracked as a follow-up debugging task.

Integration tests aave_v3_connect and aave_v3_fetch exercise the adapter
against a live anvil ETH fork; both pass on the pinned block.

Closes the v0.2 milestone: multi-chain (BSC + ETH), multi-protocol
(Venus + Aave V3), single shared pipeline.

* style: apply rustfmt on aave_v3 + executor + cli + tests
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.

1 participant