Skip to content

feat: AAVE V3 reserve-config reads (provider addrs + ABI + bit maps)#20

Merged
chrisli30 merged 2 commits into
mainfrom
feat/aave-v3-reserve-config-reads
Jul 21, 2026
Merged

feat: AAVE V3 reserve-config reads (provider addrs + ABI + bit maps)#20
chrisli30 merged 2 commits into
mainfrom
feat/aave-v3-reserve-config-reads

Conversation

@chrisli30

Copy link
Copy Markdown
Member

Adds the addresses and ABI a health-factor / liquidation solver needs to
read AAVE V3 per-reserve risk config and a user's per-reserve position,
per issue #19 (the scale optimization).

  • aaveV3.poolAddressesProvider + aaveV3.uiPoolDataProvider per-chain maps
    (Mainnet, Sepolia, Base, Base Sepolia, BNB). PoolAddressesProvider
    addresses verified on-chain (getPool() == catalog pool); UiPoolDataProvider
    verified as deployed bytecode.
  • Extend poolMethodsAbi with the version-stable Pool config reads
    getConfiguration(asset) / getUserConfiguration(user) / getReserveData(asset).
  • Export reserveConfigurationBits + userConfigurationBits (ReserveConfigurationMap
    / UserConfigurationMap bit layouts) so consumers decode the bitmaps without
    hardcoding offsets. Only version-stable low bits (0-167) are exported.

Non-goal (issue #19): governance-mutable, HF-critical values are NOT baked into
the static AaveV3Reserve catalog -- ship the address to read from, not the value.
The UiPoolDataProvider return-struct ABI is intentionally omitted because that
tuple is periphery-version-specific and already differs across covered chains
(Ethereum/Base/BNB/Base Sepolia return the v3.3 layout, Sepolia an earlier one);
pair the address with a version-aware ABI at the call site. A test guards the
reserve catalog against a stale LTV/liqThreshold bake.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

🤖 Generated with Claude Code

…oolAddressesProvider addresses + config-read ABI + bit layouts)

Adds the addresses and ABI a health-factor / liquidation solver needs to
read AAVE V3 per-reserve risk config and a user's per-reserve position,
per issue #19 (the scale optimization).

- aaveV3.poolAddressesProvider + aaveV3.uiPoolDataProvider per-chain maps
  (Mainnet, Sepolia, Base, Base Sepolia, BNB). PoolAddressesProvider
  addresses verified on-chain (getPool() == catalog pool); UiPoolDataProvider
  verified as deployed bytecode.
- Extend poolMethodsAbi with the version-stable Pool config reads
  getConfiguration(asset) / getUserConfiguration(user) / getReserveData(asset).
- Export reserveConfigurationBits + userConfigurationBits (ReserveConfigurationMap
  / UserConfigurationMap bit layouts) so consumers decode the bitmaps without
  hardcoding offsets. Only version-stable low bits (0-167) are exported.

Non-goal (issue #19): governance-mutable, HF-critical values are NOT baked into
the static AaveV3Reserve catalog -- ship the address to read from, not the value.
The UiPoolDataProvider return-struct ABI is intentionally omitted because that
tuple is periphery-version-specific and already differs across covered chains
(Ethereum/Base/BNB/Base Sepolia return the v3.3 layout, Sepolia an earlier one);
pair the address with a version-aware ABI at the call site. A test guards the
reserve catalog against a stale LTV/liqThreshold bake.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Aave V3 “scale-optimization” read support to the catalog by shipping the additional per-chain provider addresses, the stable Pool ABI fragments needed for per-reserve/user configuration reads, and exported bitmap layouts so consumers can decode Aave’s config maps without hardcoding offsets.

Changes:

  • Add per-chain aaveV3.poolAddressesProvider and aaveV3.uiPoolDataProvider address maps for all currently covered chains.
  • Extend aaveV3.poolMethodsAbi with version-stable read methods: getConfiguration(asset), getUserConfiguration(user), and getReserveData(asset).
  • Export aaveV3.reserveConfigurationBits and aaveV3.userConfigurationBits, and add tests/docs to ensure correct decoding and prevent baking governance-mutable risk params into the static reserves catalog.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
tests/catalog.test.ts Adds coverage for new ABI fragments, provider address presence across chains, bitmap decode helpers, and a guard against baking mutable risk values into the static reserves catalog.
src/protocols/aave-v3.ts Introduces provider address maps, extends Pool method ABI with stable config reads, and exports Reserve/User configuration bitmap layouts.
README.md Documents how to read/decode reserve risk config and clarifies provider usage and ABI/versioning expectations.
.changeset/aave-v3-data-provider-addresses.md Publishes a minor release note describing the new Aave V3 read surface and non-goals.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@chrisli30

Copy link
Copy Markdown
Member Author

Audit vs #19 (and the repay follow-up, studio#1369) — LGTM, this over-delivers

Checked against the issue's asks:

#19 ask Status
poolAddressesProvider + uiPoolDataProvider per-chain addresses ✅ all 5 chains; PoolAddressesProvider verified on-chain (getPool() == pool)
Config-read ABI getConfiguration / getUserConfiguration / getReserveData in poolMethodsAbi
Bit-layout constants reserveConfigurationBits + userConfigurationBits
Non-goal: don't bake mutable values ✅ respected + documented

Two calls I especially like:

  1. Shipping the UiPoolDataProvider address WITHOUT its return-struct ABI is the right move — better than what the issue suggested. The AggregatedReserveData / UserReserveData tuples are periphery-version-specific (v3.3 vs an earlier layout on Sepolia), so a single baked ABI would silently mis-decode on some markets. Pairing the address with the version-stable Pool getConfiguration / getReserveData path (+ the note to bring a version-aware ABI for the whole-market sweep) is exactly correct.
  2. Low-bits-only (0–167) bit map, with the higher volatile bits intentionally omitted + documented — avoids the stale-decode trap across concurrently-deployed V3 versions.

It also closes the repay path (studio#1369), not just the collateral solver. getUserConfiguration + userConfigurationBits give which reserves the user borrows, and getReserveData returns variableDebtTokenAddress + id + the liquidity/borrow indices — everything the repay-side math needs. One PR unblocks both halves.

Studio-side follow-up (FYI): once this lands + bumps, studio's app/lib/positions/aaveReserveConfig.ts can drop its hand-written getConfiguration ABI fragment and hardcoded bit offsets and use Protocols.aaveV3.poolMethodsAbi + reserveConfigurationBits. Cross-check: studio's current offsets (liqThreshold≫16, active 56, frozen 57, paused 60) match reserveConfigurationBits exactly — nice validation.

Two minor heads-ups (non-blocking):

  • ReserveDataLegacy.stableDebtTokenAddress is deprecated (zero on V3.1+ markets) — a repay path should read variableDebtTokenAddress. Fine to keep in the ABI for back-compat; just flagging for consumers.
  • Isolation-mode / eMode bits are (correctly) omitted — worth a one-liner in the README's HF example that a freshly-supplied isolation-mode asset may not count as collateral, so a top-up solver sizing off liquidationThreshold alone can over-estimate the HF lift in that edge case.

Ready to merge from studio's side — I'll wire studio onto it after the version bump.

…ode HF caveat

Addresses non-blocking review heads-ups on PR #20:
- Note in the getReserveData ABI comment that stableDebtTokenAddress is
  deprecated (zero on V3.1+ markets); consumers repay via variableDebtTokenAddress.
- Add a README caveat that liquidationThreshold alone underspecifies collateral
  in isolation-mode / eMode cases (those bits are intentionally omitted from the
  version-stable low-bit map), so a top-up solver should also read the user
  collateral flags and the market contracts for those bits.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chrisli30
chrisli30 merged commit b8bcb3f into main Jul 21, 2026
6 checks passed
@chrisli30
chrisli30 deleted the feat/aave-v3-reserve-config-reads branch July 21, 2026 04:45
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.

2 participants