Skip to content

[WONT MERGE]: Exclude deprecated markets from PoolLens#553

Draft
Debugger022 wants to merge 8 commits into
developfrom
feat/VPD-915
Draft

[WONT MERGE]: Exclude deprecated markets from PoolLens#553
Debugger022 wants to merge 8 commits into
developfrom
feat/VPD-915

Conversation

@Debugger022
Copy link
Copy Markdown
Collaborator

@Debugger022 Debugger022 commented Mar 31, 2026

Summary

  • Added _getActiveMarkets filter that excludes unlisted markets and markets with both MINT and BORROW actions paused

Changes

PoolLens (contracts/Lens/PoolLens.sol)

  • Added _getActiveMarkets() helper that filters getAllMarkets() in a single loop, excluding markets where isListed == false or both MINT and BORROW are paused
  • Added _isActiveMarket() helper encapsulating the active market check
  • Updated getPoolDataFromVenusPool(), getPendingRewards(), and getPoolBadDebt() to use _getActiveMarkets() instead of getAllMarkets()

Fork test (tests/hardhat/Fork/PoolLensForkTest.ts)

  • Added fork tests covering all affected functions: getAllPools, getPoolByComptroller, getPendingRewards, getPoolBadDebt, vTokenMetadataAll, getPoolDataFromVenusPool
  • Added explicit test verifying deprecated markets are excluded from results

Summary by CodeRabbit

  • New Features

    • PoolLens accepts a designated core pool comptroller so core markets are always included in pool reports.
  • Bug Fixes

    • Market enumeration refined: non-core pools now only surface markets with available cash, improving rewards, bad-debt, and pool data accuracy.
  • Tests

    • Added gated forked-network test suite validating PoolLens behaviors, core vs non-core expectations, and on-chain market metadata.
  • Chores

    • Deployment and test configs updated to support the new constructor input, verification handling, and expanded network constants.

Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@Debugger022 Debugger022 self-assigned this Mar 31, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added an immutable corePoolComptroller to PoolLens and a helper _getMarkets(ComptrollerInterface); view functions call getAllMarkets() and return full results for the core comptroller or an in-memory filtered list (markets with internalCash() > 0) for non-core comptrollers. Tests and deploy scripts updated for the new constructor argument.

Changes

Cohort / File(s) Summary
PoolLens contract
contracts/Lens/PoolLens.sol
Added address public immutable corePoolComptroller and expanded constructor; introduced _getMarkets(ComptrollerInterface) which calls getAllMarkets() and returns full list for core comptroller or filters markets to those with internalCash() > 0; routed getPendingRewards, getPoolBadDebt, and getPoolDataFromVenusPool to use _getMarkets(...).
Fork tests
tests/hardhat/Fork/PoolLensForkTest.ts
Added a fork-only test suite (gated by FORK === "true") that deploys PoolLens on a fork (passing CORE_COMPTROLLER), asserts non-reverting calls and structural invariants for getAllPools, getPoolByComptroller, getPendingRewards, getPoolBadDebt, vTokenMetadataAll, and getPoolDataFromVenusPool; includes core-inclusion and non-core filtering checks.
Fork constants
tests/hardhat/Fork/constants.ts
Added CORE_COMPTROLLER entries for multiple networks, updated several BLOCK_NUMBER values, and added new network entries (basemainnet, opmainnet, unichainmainnet).
Unit/test fixture
tests/hardhat/Lens/PoolLens.ts, tests/hardhat/Lens/RewardsSummary.ts
Updated PoolLens deployments in fixtures to include the new third constructor argument (ethers.constants.AddressZero in fixture and comptroller.address in rewards fixtures).
Deployment script
deploy/007-deploy-pool-lens.ts
Now retrieves Comptroller_Core and passes its address as the third constructor arg; sets func.skip to skip on non-live networks; uses skipIfAlreadyDeployed: true; captures deployment result and runs contract verification for newly deployed instances, treating "Already Verified" as non-error.

Sequence Diagram(s)

sequenceDiagram
  participant Caller as Caller
  participant PoolLens as PoolLens
  participant Comptroller as Comptroller
  participant VToken as VToken

  Caller->>PoolLens: call view (e.g., getPoolByComptroller / getPoolBadDebt)
  PoolLens->>Comptroller: getAllMarkets()
  alt comptroller == corePoolComptroller
    Comptroller-->>PoolLens: all markets
    PoolLens-->>Caller: return full markets list
  else
    Comptroller-->>PoolLens: all markets
    loop for each market
      PoolLens->>VToken: call internalCash()
      VToken-->>PoolLens: internalCash value
    end
    PoolLens-->>Caller: return filtered markets (internalCash() > 0)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I hopped to the core and checked every gate,
Kept whole markets warm and trimmed the quiet slate.
Forks ran the tests, deploys brought a cheer,
Non-core seeds filtered, core gardens stay near.
A rabbit's small patch, tidy and clear.

🚥 Pre-merge checks | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ⚠️ Warning The title mentions excluding deprecated markets, but the actual implementation filters markets by internalCash (non-zero) or includes all markets from the core comptroller, which differs from the stated approach of excluding unlisted/paused markets. Update the title to accurately reflect the core change: filtering markets by internalCash for non-core comptrollers, or add a core comptroller parameter for market inclusion logic.
Description check ❓ Inconclusive The PR description clearly outlines the changes made to PoolLens and includes fork test additions, but the checklist section is incomplete with all items unchecked. Complete the checklist by marking items as done or noting if they are not applicable to this PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/VPD-915

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
contracts/Lens/PoolLens.sol (1)

249-263: ⚠️ Potential issue | 🟠 Major

Don't reuse the active-market filter for accounting endpoints.

At Line 253 and Line 281, getPendingRewards() and getPoolBadDebt() now skip markets that are unlisted or fully paused. Offboarding a market does not clear existing balances, so those markets can still contribute user reward deltas and non-zero badDebt(). That turns both methods into active-only subsets while their names still read as full pool/account summaries. I’d keep _getActiveMarkets() on metadata/listing paths and leave these aggregations on the full market set, or expose separate active-only variants if that API change is intentional.

Also applies to: 276-299

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/Lens/PoolLens.sol` around lines 249 - 263, getPendingRewards() and
getPoolBadDebt() wrongly use _getActiveMarkets(), which filters out
unlisted/paused markets and therefore omits balances and rewards from offboarded
markets; replace the active-market filter with the full market set when
computing aggregations by calling the comptroller's full-market accessor (e.g.,
ComptrollerInterface(comptrollerAddress).getAllMarkets() or the equivalent
getAllMarkets() on ComptrollerViewInterface) and use that result instead of
_getActiveMarkets(); keep _getActiveMarkets() for listing/metadata endpoints
only or add separate active-only variants if intended.
🧹 Nitpick comments (1)
tests/hardhat/Fork/PoolLensForkTest.ts (1)

78-89: Assert the full active-market predicate in these cases.

At Line 86 and Line 147, these checks only verify isListed. A market that is still listed but has both MINT and BORROW paused would still pass here, so these tests do not validate the exact _isActiveMarket behavior added by the contract for getAllPools() and getPoolDataFromVenusPool(). Reuse isActiveMarket() for each returned vToken.

Also applies to: 139-149

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hardhat/Fork/PoolLensForkTest.ts` around lines 78 - 89, The tests
calling poolLens.getAllPools and getPoolDataFromVenusPool currently only assert
vToken.isListed but must assert the full active-market predicate; update the
assertions to call and assert the same logic as the contract's isActiveMarket
(i.e., replace or augment checks that vToken.isListed in the loops with a call
to the helper/isActiveMarket predicate used by the contract or reimplement that
predicate in the test and assert it returns true for each returned vToken),
ensuring both MINT and BORROW pause flags and listed status are validated for
each vToken returned by getAllPools and getPoolDataFromVenusPool.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/hardhat/Fork/PoolLensForkTest.ts`:
- Around line 15-18: The module currently destructures POOL_REGISTRY,
COMPTROLLER, ACC1, BLOCK_NUMBER from getContractAddresses(FORKED_NETWORK) at
load time which will throw if getContractAddresses returns undefined for
unsupported names; change to first validate FORKED_NETWORK (e.g., check against
the known network list or ensure getContractAddresses(FORKED_NETWORK) !==
undefined) or delay calling getContractAddresses until inside the FORK guard, by
assigning its return to a temporary (e.g., addresses) and only destructuring
POOL_REGISTRY, COMPTROLLER, ACC1, BLOCK_NUMBER after confirming addresses is
defined; ensure the same pattern is applied to the other destructurings
mentioned around lines 21–30.

---

Outside diff comments:
In `@contracts/Lens/PoolLens.sol`:
- Around line 249-263: getPendingRewards() and getPoolBadDebt() wrongly use
_getActiveMarkets(), which filters out unlisted/paused markets and therefore
omits balances and rewards from offboarded markets; replace the active-market
filter with the full market set when computing aggregations by calling the
comptroller's full-market accessor (e.g.,
ComptrollerInterface(comptrollerAddress).getAllMarkets() or the equivalent
getAllMarkets() on ComptrollerViewInterface) and use that result instead of
_getActiveMarkets(); keep _getActiveMarkets() for listing/metadata endpoints
only or add separate active-only variants if intended.

---

Nitpick comments:
In `@tests/hardhat/Fork/PoolLensForkTest.ts`:
- Around line 78-89: The tests calling poolLens.getAllPools and
getPoolDataFromVenusPool currently only assert vToken.isListed but must assert
the full active-market predicate; update the assertions to call and assert the
same logic as the contract's isActiveMarket (i.e., replace or augment checks
that vToken.isListed in the loops with a call to the helper/isActiveMarket
predicate used by the contract or reimplement that predicate in the test and
assert it returns true for each returned vToken), ensuring both MINT and BORROW
pause flags and listed status are validated for each vToken returned by
getAllPools and getPoolDataFromVenusPool.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a27bb62b-36e6-4dcc-8659-b11549750158

📥 Commits

Reviewing files that changed from the base of the PR and between cdc9185 and 84ef62b.

📒 Files selected for processing (2)
  • contracts/Lens/PoolLens.sol
  • tests/hardhat/Fork/PoolLensForkTest.ts

Comment thread tests/hardhat/Fork/PoolLensForkTest.ts Outdated
Comment on lines +15 to +18
const FORK = process.env.FORK === "true";
const FORKED_NETWORK = process.env.FORKED_NETWORK || "bscmainnet";

const { POOL_REGISTRY, COMPTROLLER, ACC1, BLOCK_NUMBER } = getContractAddresses(FORKED_NETWORK as string);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard unsupported FORKED_NETWORK values before destructuring.

Line 18 destructures getContractAddresses(...) at module load time, but that helper returns undefined for names missing from tests/hardhat/Fork/constants.ts. Since TIME_BASED_NETWORKS already includes several unsupported names, setting FORKED_NETWORK to one of them will crash before the if (FORK) guard runs.

Example guard
-const { POOL_REGISTRY, COMPTROLLER, ACC1, BLOCK_NUMBER } = getContractAddresses(FORKED_NETWORK as string);
+let POOL_REGISTRY!: string;
+let COMPTROLLER!: string;
+let ACC1: string | undefined;
+let BLOCK_NUMBER!: number;
+
+if (FORK) {
+  const addresses = getContractAddresses(FORKED_NETWORK);
+  if (!addresses) {
+    throw new Error(`Unsupported FORKED_NETWORK: ${FORKED_NETWORK}`);
+  }
+
+  ({ POOL_REGISTRY, COMPTROLLER, ACC1, BLOCK_NUMBER } = addresses);
+}

Also applies to: 21-30

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hardhat/Fork/PoolLensForkTest.ts` around lines 15 - 18, The module
currently destructures POOL_REGISTRY, COMPTROLLER, ACC1, BLOCK_NUMBER from
getContractAddresses(FORKED_NETWORK) at load time which will throw if
getContractAddresses returns undefined for unsupported names; change to first
validate FORKED_NETWORK (e.g., check against the known network list or ensure
getContractAddresses(FORKED_NETWORK) !== undefined) or delay calling
getContractAddresses until inside the FORK guard, by assigning its return to a
temporary (e.g., addresses) and only destructuring POOL_REGISTRY, COMPTROLLER,
ACC1, BLOCK_NUMBER after confirming addresses is defined; ensure the same
pattern is applied to the other destructurings mentioned around lines 21–30.

Core pools should return all markets (including paused ones) since
deprecated market filtering was only intended for isolated pools.
Adds corePoolComptroller immutable to skip filtering for the core pool.
Add CORE_COMPTROLLER to fork test constants and verify that all
markets are returned for core pools while deprecated filtering
still applies to isolated pools.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
tests/hardhat/Fork/PoolLensForkTest.ts (1)

18-20: ⚠️ Potential issue | 🟠 Major

Guard getContractAddresses(...) before destructuring.

This still runs at module load time, so an unsupported FORKED_NETWORK throws before the if (FORK) guard can skip the suite. That is still easy to hit here because TIME_BASED_NETWORKS already contains names that getContractAddresses(...) does not serve.

Example fix
-const { POOL_REGISTRY, COMPTROLLER, CORE_COMPTROLLER, ACC1, BLOCK_NUMBER } = getContractAddresses(
-  FORKED_NETWORK as string,
-);
+let POOL_REGISTRY!: string;
+let COMPTROLLER!: string;
+let CORE_COMPTROLLER!: string;
+let ACC1!: string;
+let BLOCK_NUMBER!: number;
+
+if (FORK) {
+  const addresses = getContractAddresses(FORKED_NETWORK as string);
+  if (!addresses) {
+    throw new Error(`Unsupported FORKED_NETWORK: ${FORKED_NETWORK}`);
+  }
+
+  ({ POOL_REGISTRY, COMPTROLLER, CORE_COMPTROLLER, ACC1, BLOCK_NUMBER } = addresses);
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hardhat/Fork/PoolLensForkTest.ts` around lines 18 - 20, The
destructuring call to getContractAddresses(...) is executed at module load and
can throw for unsupported FORKED_NETWORK; instead, guard it before destructuring
by first checking the FORK flag (or whether FORKED_NETWORK is supported) and
only call getContractAddresses(...) inside that conditional, or call it into a
temporary variable and validate it before extracting POOL_REGISTRY, COMPTROLLER,
CORE_COMPTROLLER, ACC1, BLOCK_NUMBER; update references in PoolLensForkTest.ts
so getContractAddresses is never invoked at module load time.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@contracts/Lens/PoolLens.sol`:
- Around line 289-291: The code is filtering out unlisted/paused markets by
calling _getMarkets(...), which understates badDebt and totalBadDebtUsd; replace
the filtered call with the comptroller's full market list (call getAllMarkets()
on ComptrollerViewInterface(comptrollerAddress)) instead of
_getMarkets(ComptrollerInterface(comptrollerAddress)) so you iterate every
VToken returned (including unlisted/paused) and include each token's badDebt()
and its USD contribution when computing badDebts and totalBadDebtUsd
(referencing ComptrollerViewInterface, getAllMarkets, _getMarkets, VToken[],
comptrollerAddress, and badDebt()).

In `@deploy/007-deploy-pool-lens.ts`:
- Around line 16-21: The deployment currently calls deploy("PoolLens", ...) with
skipIfAlreadyDeployed: true which prevents updating existing PoolLens instances
after adding the new required constructor arg corePoolComptroller; update the
deploy logic so networks with an existing PoolLens get the new constructor
value: either remove skipIfAlreadyDeployed from the deploy(...) call to force
redeployment with the new constructorArgs (ensuring deployer/args are correct),
or implement an explicit upgrade path (use a proxy/upgrade mechanism to replace
PoolLens implementation while preserving storage) and wire corePoolComptroller
into the new implementation; locate references to PoolLens, constructorArgs,
corePoolComptroller, and skipIfAlreadyDeployed to make the change.
- Around line 13-14: Replace deployments.get("Comptroller_Core") with await
deployments.getOrNull("Comptroller_Core") and handle the null case: assign
corePoolComptrollerAddress = corePoolComptroller?.address ??
ethers.constants.AddressZero (or otherwise skip/queue this deploy) so
constructorArgs = [isTimeBased, blocksPerYear, corePoolComptrollerAddress];
ensure the code checks for a null corePoolComptroller returned by getOrNull
before accessing .address to avoid failures on first rollout.

---

Duplicate comments:
In `@tests/hardhat/Fork/PoolLensForkTest.ts`:
- Around line 18-20: The destructuring call to getContractAddresses(...) is
executed at module load and can throw for unsupported FORKED_NETWORK; instead,
guard it before destructuring by first checking the FORK flag (or whether
FORKED_NETWORK is supported) and only call getContractAddresses(...) inside that
conditional, or call it into a temporary variable and validate it before
extracting POOL_REGISTRY, COMPTROLLER, CORE_COMPTROLLER, ACC1, BLOCK_NUMBER;
update references in PoolLensForkTest.ts so getContractAddresses is never
invoked at module load time.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7c870f68-8512-44d5-9c0b-185450464f1b

📥 Commits

Reviewing files that changed from the base of the PR and between 84ef62b and 3ba76ad.

📒 Files selected for processing (5)
  • contracts/Lens/PoolLens.sol
  • deploy/007-deploy-pool-lens.ts
  • tests/hardhat/Fork/PoolLensForkTest.ts
  • tests/hardhat/Fork/constants.ts
  • tests/hardhat/Lens/PoolLens.ts

Comment on lines +289 to +291
// Get every listed market in the pool
ComptrollerViewInterface comptroller = ComptrollerViewInterface(comptrollerAddress);
VToken[] memory markets = comptroller.getAllMarkets();
VToken[] memory markets = _getMarkets(ComptrollerInterface(comptrollerAddress));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Keep bad-debt accounting on getAllMarkets().

A market can still carry badDebt() after it is unlisted or fully paused. Filtering with _getMarkets(...) here will understate both badDebts and totalBadDebtUsd for isolated pools—the exact markets most likely to have bad debt are the ones being dropped.

Suggested fix
-        VToken[] memory markets = _getMarkets(ComptrollerInterface(comptrollerAddress));
+        VToken[] memory markets = comptroller.getAllMarkets();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Get every listed market in the pool
ComptrollerViewInterface comptroller = ComptrollerViewInterface(comptrollerAddress);
VToken[] memory markets = comptroller.getAllMarkets();
VToken[] memory markets = _getMarkets(ComptrollerInterface(comptrollerAddress));
// Get every listed market in the pool
ComptrollerViewInterface comptroller = ComptrollerViewInterface(comptrollerAddress);
VToken[] memory markets = comptroller.getAllMarkets();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/Lens/PoolLens.sol` around lines 289 - 291, The code is filtering
out unlisted/paused markets by calling _getMarkets(...), which understates
badDebt and totalBadDebtUsd; replace the filtered call with the comptroller's
full market list (call getAllMarkets() on
ComptrollerViewInterface(comptrollerAddress)) instead of
_getMarkets(ComptrollerInterface(comptrollerAddress)) so you iterate every
VToken returned (including unlisted/paused) and include each token's badDebt()
and its USD contribution when computing badDebts and totalBadDebtUsd
(referencing ComptrollerViewInterface, getAllMarkets, _getMarkets, VToken[],
comptrollerAddress, and badDebt()).

Comment on lines +13 to +14
const corePoolComptroller = await deployments.get("Comptroller_Core");
const constructorArgs = [isTimeBased, blocksPerYear, corePoolComptroller.address];
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, explore the deploy directory structure and find related files
fd . deploy/ --type f --name "*.ts" | head -20

Repository: VenusProtocol/isolated-pools

Length of output: 322


🏁 Script executed:

# Read the specific file mentioned in the review
wc -l deploy/007-deploy-pool-lens.ts

Repository: VenusProtocol/isolated-pools

Length of output: 105


🏁 Script executed:

# Read the full context of deploy/007-deploy-pool-lens.ts
cat -n deploy/007-deploy-pool-lens.ts

Repository: VenusProtocol/isolated-pools

Length of output: 1857


🏁 Script executed:

# Search for how Comptroller_Core is used in other deploy scripts
rg "Comptroller_Core" deploy/ -A 3 -B 3

Repository: VenusProtocol/isolated-pools

Length of output: 598


🏁 Script executed:

# Check hardhat.config.ts to see network definitions and which are marked as live
cat -n hardhat.config.ts | head -100

Repository: VenusProtocol/isolated-pools

Length of output: 5299


🏁 Script executed:

# Look for skipIfAlreadyDeployed pattern in other deploy scripts
rg "skipIfAlreadyDeployed" deploy/ -B 5 -A 2

Repository: VenusProtocol/isolated-pools

Length of output: 13685


🏁 Script executed:

# Look for where Comptroller_Core is deployed
rg "Comptroller_Core" . --type ts -B 5 -A 5

Repository: VenusProtocol/isolated-pools

Length of output: 9286


🏁 Script executed:

# Check deploy/008 which deploys comptrollers
cat -n deploy/008-deploy-comptrollers.ts

Repository: VenusProtocol/isolated-pools

Length of output: 2554


🏁 Script executed:

# Search for getOrNull pattern in the codebase
rg "getOrNull|deployments\.get" deploy/ -A 2 -B 2

Repository: VenusProtocol/isolated-pools

Length of output: 5685


🏁 Script executed:

# Check the deploymentConfig to see what pools are configured
rg "Core" helpers/deploymentConfig -A 3 -B 3

Repository: VenusProtocol/isolated-pools

Length of output: 136


🏁 Script executed:

# Look for where pools are defined and if "Core" is a pool id
fd deploymentConfig.ts

Repository: VenusProtocol/isolated-pools

Length of output: 99


🏁 Script executed:

# Check if there are references to which pools should be deployed
cat -n helpers/deploymentConfig.ts | head -150

Repository: VenusProtocol/isolated-pools

Length of output: 7298


🏁 Script executed:

# Search for all pool definitions to understand pool naming
rg "pool.id|poolId" helpers/deploymentConfig.ts -B 2 -A 2

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Check what getUnregisteredPools does - it determines which comptrollers get deployed
rg "getUnregisteredPools" helpers/ -A 10

Repository: VenusProtocol/isolated-pools

Length of output: 987


🏁 Script executed:

# Check deployment configurations for BSC networks to see if "Core" pool is defined
rg -A 500 "bscmainnet:" helpers/deploymentConfig.ts | head -150

Repository: VenusProtocol/isolated-pools

Length of output: 4733


🏁 Script executed:

# Check bsctestnet config
rg -A 500 "bsctestnet:" helpers/deploymentConfig.ts | head -150

Repository: VenusProtocol/isolated-pools

Length of output: 4680


🏁 Script executed:

# Look for where poolConfig gets the "Core" pool definition
rg "\"Core\"" helpers/deploymentConfig.ts

Repository: VenusProtocol/isolated-pools

Length of output: 659


🏁 Script executed:

# Check all deployment configuration files
fd deploymentConfig -t f

Repository: VenusProtocol/isolated-pools

Length of output: 99


🏁 Script executed:

# Look for where pool configs are actually defined with the Core pool
rg "id.*Core|Core.*poolConfig" . --type ts | head -20

Repository: VenusProtocol/isolated-pools

Length of output: 934


🏁 Script executed:

# Check the full deploymentConfig to understand when Core pool is configured
wc -l helpers/deploymentConfig.ts

Repository: VenusProtocol/isolated-pools

Length of output: 104


🏁 Script executed:

# Check the section with actual pool config definitions to see if Core is always configured
sed -n '150,500p' helpers/deploymentConfig.ts

Repository: VenusProtocol/isolated-pools

Length of output: 13887


🏁 Script executed:

# Look at deploy scripts to understand execution order - hardhat-deploy executes in numeric order
ls -la deploy/ | grep "^-" | head -30

Repository: VenusProtocol/isolated-pools

Length of output: 1866


🏁 Script executed:

# Check if deploy/007 depends on deploy/008's output
rg "dependsOn|tags.*il|func.tags" deploy/007-deploy-pool-lens.ts

Repository: VenusProtocol/isolated-pools

Length of output: 103


🏁 Script executed:

# Check deploy/008 tags
rg "dependsOn|tags.*il|func.tags" deploy/008-deploy-comptrollers.ts

Repository: VenusProtocol/isolated-pools

Length of output: 107


🏁 Script executed:

# Check if Comptroller_Core might be from external deployments in venus-protocol
rg "Comptroller_Core" node_modules/@venusprotocol/venus-protocol/deployments/ 2>/dev/null | head -20

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Verify hardhat-deploy execution order - does it execute by numeric filename?
# Check if there are any explicit dependencies between 007 and 008
rg "dependsOn" deploy/007-deploy-pool-lens.ts deploy/008-deploy-comptrollers.ts

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Look at how deploy/004-swap-router handles getting Comptroller_DeFi which is deployed in 008
cat -n deploy/004-swap-router.ts | head -50

Repository: VenusProtocol/isolated-pools

Length of output: 2406


🏁 Script executed:

# Check if Comptroller_DeFi actually exists or if it's also from external deployments
rg "Comptroller_DeFi" helpers/deploymentConfig.ts -B 3 -A 3

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Search for how hardhat-deploy handles the execution when getting deployments that don't exist yet
# Check if there's any code that ensures deploy/008 runs before 007
rg "run\|tags\|il" deploy/ --type ts -B 2 -A 2 | grep -A 5 -B 5 "tags.*il"

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Look for any hardhat.config overrides for deployment order
rg "deploymentDependencies|namedAccounts|deploy.*order" hardhat.config.ts

Repository: VenusProtocol/isolated-pools

Length of output: 90


🏁 Script executed:

# Check what happens when running deploy scripts - does deploy 008 need to run first?
# Look for any documentation or test that shows execution order
fd README -o DEPLOYMENT_ORDER -o deployment.md

Repository: VenusProtocol/isolated-pools

Length of output: 223


🏁 Script executed:

# Verify which pool names map to which comptroller deployments in deploy/008
grep -n "pool.id\|pool.name\|Comptroller_" deploy/008-deploy-comptrollers.ts

Repository: VenusProtocol/isolated-pools

Length of output: 119


🏁 Script executed:

# Check if there's a specific way the scripts are meant to be run
cat -n package.json | grep -A 5 -B 5 "deploy"

Repository: VenusProtocol/isolated-pools

Length of output: 2196


🏁 Script executed:

# Check if Comptroller_Core is provided by external venus-protocol deployments or only deployed locally
rg "Comptroller_Core" node_modules/@venusprotocol/ 2>/dev/null | head -5

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Look at the actual pool configurations to confirm Core pool is in every network's config
grep -A 50 "export const globalConfig" helpers/deploymentConfig.ts | grep -A 20 "bscmainnet:"

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Check if there's a deployment execution order documented or if tags affect order
cat -n deploy/006-deploy-pool-registry.ts | tail -10

Repository: VenusProtocol/isolated-pools

Length of output: 284


🏁 Script executed:

# Key insight: Check if deploy scripts that have "il" tag all need to run in sequence
# See if any deployment script references both "il" tag and a previous numbered script's deployment
rg "func.tags.*il" deploy/ -B 2 -A 5

Repository: VenusProtocol/isolated-pools

Length of output: 4164


🏁 Script executed:

# Check actual behavior - are there any snapshots or artifacts showing deployment order?
fd "deployments" --type d | head -5

Repository: VenusProtocol/isolated-pools

Length of output: 84


🏁 Script executed:

# Final confirmation: Check if hardhat-deploy truly executes numerically
# Look at the actual behavior documentation in hardhat-deploy to confirm execution order
cat -n node_modules/hardhat-deploy/package.json | grep -A 2 -B 2 "version"

Repository: VenusProtocol/isolated-pools

Length of output: 281


Use getOrNull() to handle missing Comptroller_Core on first deployment.

deployments.get("Comptroller_Core") will fail when deploying to live networks for the first time. Hardhat-deploy executes scripts numerically, so script 007 runs before script 008, which creates the Comptroller_Core deployment. On initial rollout, this artifact does not yet exist.

Possible fix
-  const corePoolComptroller = await deployments.get("Comptroller_Core");
-  const constructorArgs = [isTimeBased, blocksPerYear, corePoolComptroller.address];
+  const corePoolComptroller = await deployments.getOrNull("Comptroller_Core");
+  if (!corePoolComptroller) {
+    throw new Error("Comptroller_Core deployment not found. Run deploy/008-deploy-comptrollers.ts first.");
+  }
+  const constructorArgs = [isTimeBased, blocksPerYear, corePoolComptroller.address];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deploy/007-deploy-pool-lens.ts` around lines 13 - 14, Replace
deployments.get("Comptroller_Core") with await
deployments.getOrNull("Comptroller_Core") and handle the null case: assign
corePoolComptrollerAddress = corePoolComptroller?.address ??
ethers.constants.AddressZero (or otherwise skip/queue this deploy) so
constructorArgs = [isTimeBased, blocksPerYear, corePoolComptrollerAddress];
ensure the code checks for a null corePoolComptroller returned by getOrNull
before accessing .address to avoid failures on first rollout.

Comment on lines +16 to +21
const poolLens = await deploy("PoolLens", {
from: deployer,
args: [isTimeBased, blocksPerYear],
args: constructorArgs,
log: true,
autoMine: true,
skipIfAlreadyDeployed: true,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, check the deploy script file
cat -n deploy/007-deploy-pool-lens.ts

Repository: VenusProtocol/isolated-pools

Length of output: 1857


🏁 Script executed:

# Check if there are constructor args changes in this PR
git diff HEAD~1 deploy/007-deploy-pool-lens.ts 2>/dev/null || echo "Git diff not available, will check file directly"

Repository: VenusProtocol/isolated-pools

Length of output: 120


🏁 Script executed:

# Search for any references to "core-pool exemption" in the codebase
rg "core-pool" --type ts --type js -i

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Check what PoolLens contract does and if constructor args relate to exemptions
rg "PoolLens" --type ts --type js -A 3 -B 3 | head -100

Repository: VenusProtocol/isolated-pools

Length of output: 6575


🏁 Script executed:

# Search for the PoolLens contract definition to understand the constructor
fd "PoolLens.sol" -type f

Repository: VenusProtocol/isolated-pools

Length of output: 242


🏁 Script executed:

# Search for "exemption" in the codebase to find what this refers to
rg "exemption" -i --type ts --type js --type sol -B 2 -A 2

Repository: VenusProtocol/isolated-pools

Length of output: 99


🏁 Script executed:

# Check other deploy scripts for comparison with PoolLens deployment pattern
rg "skipIfAlreadyDeployed" deploy/ --type ts -B 5 -A 5 | head -80

Repository: VenusProtocol/isolated-pools

Length of output: 5215


🏁 Script executed:

# Look for recent changes or PR context in version control
git log --oneline deploy/007-deploy-pool-lens.ts 2>/dev/null | head -5

Repository: VenusProtocol/isolated-pools

Length of output: 139


🏁 Script executed:

# Find the PoolLens contract definition
find . -name "PoolLens.sol" -o -name "PoolLens.ts" | grep -v node_modules | grep -v test

Repository: VenusProtocol/isolated-pools

Length of output: 101


🏁 Script executed:

# Search for corePoolComptroller to understand its usage
rg "corePoolComptroller" -B 3 -A 3

Repository: VenusProtocol/isolated-pools

Length of output: 50387


🏁 Script executed:

# Check what the comment says in the git commit
git show 3ba76ad --stat 2>/dev/null | head -20

Repository: VenusProtocol/isolated-pools

Length of output: 1065


🏁 Script executed:

# Look at the PoolLens contract to understand the constructor and what the core comptroller parameter does
rg "contract PoolLens" -A 30 --type-list

Repository: VenusProtocol/isolated-pools

Length of output: 461


🏁 Script executed:

# Read the PoolLens.sol contract to understand the constructor and parameter
cat contracts/Lens/PoolLens.sol | head -150

Repository: VenusProtocol/isolated-pools

Length of output: 5183


🏁 Script executed:

# Search specifically for corePoolComptroller or coreComptroller usage in PoolLens
rg "corePoolComptroller\|coreComptroller" contracts/Lens/PoolLens.sol -A 5 -B 2

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Look for the constructor in PoolLens
ast-grep --pattern 'contract PoolLens { $$$
  constructor($_) { $$$
  }
}'

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Search for any previous versions or references to PoolLens constructor without corePoolComptroller
rg "PoolLens\(" tests/ -B 2 -A 2 | head -40

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Check if there are any comments or git history about when corePoolComptroller was added
git log --all --oneline --grep="PoolLens" 2>/dev/null | head -10

Repository: VenusProtocol/isolated-pools

Length of output: 659


🏁 Script executed:

# Search for the actual usage of corePoolComptroller in PoolLens to understand the behavior
rg "corePoolComptroller" contracts/Lens/PoolLens.sol -A 10 | head -60

Repository: VenusProtocol/isolated-pools

Length of output: 1540


🏁 Script executed:

# Check if PoolLens was previously deployed and what the constructor looked like before this commit
git show 3ba76ad^:contracts/Lens/PoolLens.sol 2>/dev/null | grep -A 15 "constructor" | head -20

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Check deployments directory to see if PoolLens is already deployed on existing networks
ls -la deployments/ | grep -E "^d" | head -20

Repository: VenusProtocol/isolated-pools

Length of output: 1227


🏁 Script executed:

# Check if PoolLens was deployed in prior deployment scripts
fd "deploy.*pool.*lens" deploy/ -i

Repository: VenusProtocol/isolated-pools

Length of output: 102


🏁 Script executed:

# Verify if there's an existing deployment artifact for PoolLens
find deployments -name "PoolLens.json" 2>/dev/null | head -5

Repository: VenusProtocol/isolated-pools

Length of output: 264


🏁 Script executed:

# Check what the previous version of PoolLens constructor looked like
git show 3ba76ad~1:contracts/Lens/PoolLens.sol 2>/dev/null | grep -A 20 "constructor" | head -25

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Check one of the existing deployment artifacts to see if it has the new constructor args
cat deployments/bscmainnet/PoolLens.json | jq '.args // .constructorArgs' 2>/dev/null

Repository: VenusProtocol/isolated-pools

Length of output: 95


🏁 Script executed:

# Get a clearer picture of what changed - check the diff for the PoolLens contract
git diff 3ba76ad~1 3ba76ad -- contracts/Lens/PoolLens.sol 2>/dev/null | head -80

Repository: VenusProtocol/isolated-pools

Length of output: 54


🏁 Script executed:

# Let's check the full git commit to see what all changed
git show 3ba76ad --stat 2>/dev/null | head -30

Repository: VenusProtocol/isolated-pools

Length of output: 1685


🏁 Script executed:

# Check if there's a deployment helper or if PoolLens gets deployed elsewhere or upgraded
rg "PoolLens" deploy/ --type ts -l

Repository: VenusProtocol/isolated-pools

Length of output: 102


🏁 Script executed:

# Verify that skipIfAlreadyDeployed really does skip when contract exists
rg "skipIfAlreadyDeployed" -B 5 -A 5 --type ts | grep -A 10 "deploy\(" | head -40

Repository: VenusProtocol/isolated-pools

Length of output: 95


🏁 Script executed:

# Check if there's an upgrade mechanism for PoolLens
rg "upgrade\|Upgrade" deploy/007-deploy-pool-lens.ts -i

Repository: VenusProtocol/isolated-pools

Length of output: 54


Constructor signature change blocks deployment on networks with existing PoolLens.

The PR adds corePoolComptroller as a required constructor parameter (changing signature from 2 to 3 args), but skipIfAlreadyDeployed: true prevents redeployment on existing networks. PoolLens is already deployed on mainnet chains (BSC, Ethereum, Arbitrum, etc.) with the old 2-parameter constructor. When this deploy script runs on those networks, it will skip entirely, leaving the old deployment in place without the corePoolComptroller parameter. This means the core-pool market filtering logic won't activate on those networks.

Either remove skipIfAlreadyDeployed: true to allow re-deployment, or implement an upgrade path using a proxy if storage changes are a concern.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deploy/007-deploy-pool-lens.ts` around lines 16 - 21, The deployment
currently calls deploy("PoolLens", ...) with skipIfAlreadyDeployed: true which
prevents updating existing PoolLens instances after adding the new required
constructor arg corePoolComptroller; update the deploy logic so networks with an
existing PoolLens get the new constructor value: either remove
skipIfAlreadyDeployed from the deploy(...) call to force redeployment with the
new constructorArgs (ensuring deployer/args are correct), or implement an
explicit upgrade path (use a proxy/upgrade mechanism to replace PoolLens
implementation while preserving storage) and wire corePoolComptroller into the
new implementation; locate references to PoolLens, constructorArgs,
corePoolComptroller, and skipIfAlreadyDeployed to make the change.

Comment thread tests/hardhat/Fork/constants.ts Outdated
VTOKEN1: ArbOneContracts.VToken_vWETH_Core.address,
VTOKEN2: ArbOneContracts.VToken_vARB_Core.address,
COMPTROLLER: ArbOneContracts.Comptroller_Core.address,
CORE_COMPTROLLER: ArbOneContracts.Comptroller_Core.address,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

arb

Comment thread tests/hardhat/Fork/constants.ts Outdated
VTOKEN1: OpBnbMainnetContracts.VToken_vUSDT_Core.address,
VTOKEN2: OpBnbMainnetContracts.VToken_vFDUSD_Core.address,
COMPTROLLER: OpBnbMainnetContracts.Comptroller_Core.address,
CORE_COMPTROLLER: OpBnbMainnetContracts.Comptroller_Core.address,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

opbnb

Comment thread tests/hardhat/Fork/constants.ts Outdated
VTOKEN1: EthereumContracts.VToken_vcrvUSD_Curve.address,
VTOKEN2: EthereumContracts.VToken_vCRV_Curve.address,
COMPTROLLER: EthereumContracts.Comptroller_Curve.address,
CORE_COMPTROLLER: EthereumContracts.Comptroller_Core.address,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

eth

Comment thread contracts/Lens/PoolLens.sol Outdated
if (address(comptroller) == corePoolComptroller) {
return comptroller.getAllMarkets();
}
return _getActiveMarkets(comptroller);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i prefer return empty list instead of this as we already deprecated this part

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

…PoolLens

All non-core pool markets are deprecated, so replace the active market
filtering logic with an empty array return. Remove _getActiveMarkets
and _isActiveMarket functions. Update fork tests accordingly and add
base, optimism, and unichain network configs.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/hardhat/Fork/constants.ts (1)

229-229: Verify ACC1 placeholder address for Unichain.

ACC1 is set to address(1) which is typically a precompile/system address. While the test has a fallback (ACC1 || AddressZero), getPendingRewards may return empty results if called with an account that has no positions. Consider using an actual account address with existing positions on Unichain mainnet for more meaningful test coverage.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hardhat/Fork/constants.ts` at line 229, ACC1 is currently a placeholder
(address(1)) which may produce empty results for getPendingRewards; update the
ACC1 constant in constants.ts to a real Unichain mainnet address that holds
positions/rewards (or a known funded test account on your fork) so
getPendingRewards returns meaningful data, ensure the address is checksummed and
keep the existing fallback (ACC1 || AddressZero) if needed for safety.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/hardhat/Fork/constants.ts`:
- Around line 214-231: The three new network objects (basemainnet, opmainnet,
unichainmainnet) are missing the COMPTROLLER key which PoolLensForkTest (it
destructures COMPTROLLER at multiple places) expects; add a COMPTROLLER property
to each network object in the constants (e.g., set COMPTROLLER to the same value
as CORE_COMPTROLLER if the network has a single core pool) so
PoolLensForkTest.ts can destructure and use COMPTROLLER without runtime errors.

---

Nitpick comments:
In `@tests/hardhat/Fork/constants.ts`:
- Line 229: ACC1 is currently a placeholder (address(1)) which may produce empty
results for getPendingRewards; update the ACC1 constant in constants.ts to a
real Unichain mainnet address that holds positions/rewards (or a known funded
test account on your fork) so getPendingRewards returns meaningful data, ensure
the address is checksummed and keep the existing fallback (ACC1 || AddressZero)
if needed for safety.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9f723cc5-a0fc-4b3c-bb3e-c11635aa1b05

📥 Commits

Reviewing files that changed from the base of the PR and between 3ba76ad and b8bd185.

📒 Files selected for processing (3)
  • contracts/Lens/PoolLens.sol
  • tests/hardhat/Fork/PoolLensForkTest.ts
  • tests/hardhat/Fork/constants.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • contracts/Lens/PoolLens.sol

Comment on lines +214 to 231
basemainnet: {
CORE_COMPTROLLER: "0x0C7973F9598AA62f9e03B94E92C967fD5437426C",
POOL_REGISTRY: "0xeef902918DdeCD773D4B422aa1C6e1673EB9136F",
ACC1: "0xcdac0d6c6c59727a65f871236188350531885c43",
BLOCK_NUMBER: 44070000,
},
opmainnet: {
CORE_COMPTROLLER: "0x5593FF68bE84C966821eEf5F0a988C285D5B7CeC",
POOL_REGISTRY: "0x147780799840d541C1d7c998F0cbA996d11D62bb",
ACC1: "0xacD03D601e5bB1B275Bb94076fF46ED9D753435A",
BLOCK_NUMBER: 149670000,
},
unichainmainnet: {
CORE_COMPTROLLER: "0xe22af1e6b78318e1Fe1053Edbd7209b8Fc62c4Fe",
POOL_REGISTRY: "0x0C52403E16BcB8007C1e54887E1dFC1eC9765D7C",
ACC1: "0x0000000000000000000000000000000000000001",
BLOCK_NUMBER: 44190000,
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Missing COMPTROLLER field will cause test failures.

The new network entries (basemainnet, opmainnet, unichainmainnet) are missing the COMPTROLLER field, but PoolLensForkTest.ts destructures and uses it at multiple locations (lines 64, 80, 104, 127). Running tests with FORKED_NETWORK=basemainnet (or the other new networks) will cause runtime errors.

If these networks have a single core pool, COMPTROLLER should likely equal CORE_COMPTROLLER.

Proposed fix
   basemainnet: {
     CORE_COMPTROLLER: "0x0C7973F9598AA62f9e03B94E92C967fD5437426C",
+    COMPTROLLER: "0x0C7973F9598AA62f9e03B94E92C967fD5437426C",
     POOL_REGISTRY: "0xeef902918DdeCD773D4B422aa1C6e1673EB9136F",
     ACC1: "0xcdac0d6c6c59727a65f871236188350531885c43",
     BLOCK_NUMBER: 44070000,
   },
   opmainnet: {
     CORE_COMPTROLLER: "0x5593FF68bE84C966821eEf5F0a988C285D5B7CeC",
+    COMPTROLLER: "0x5593FF68bE84C966821eEf5F0a988C285D5B7CeC",
     POOL_REGISTRY: "0x147780799840d541C1d7c998F0cbA996d11D62bb",
     ACC1: "0xacD03D601e5bB1B275Bb94076fF46ED9D753435A",
     BLOCK_NUMBER: 149670000,
   },
   unichainmainnet: {
     CORE_COMPTROLLER: "0xe22af1e6b78318e1Fe1053Edbd7209b8Fc62c4Fe",
+    COMPTROLLER: "0xe22af1e6b78318e1Fe1053Edbd7209b8Fc62c4Fe",
     POOL_REGISTRY: "0x0C52403E16BcB8007C1e54887E1dFC1eC9765D7C",
     ACC1: "0x0000000000000000000000000000000000000001",
     BLOCK_NUMBER: 44190000,
   },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
basemainnet: {
CORE_COMPTROLLER: "0x0C7973F9598AA62f9e03B94E92C967fD5437426C",
POOL_REGISTRY: "0xeef902918DdeCD773D4B422aa1C6e1673EB9136F",
ACC1: "0xcdac0d6c6c59727a65f871236188350531885c43",
BLOCK_NUMBER: 44070000,
},
opmainnet: {
CORE_COMPTROLLER: "0x5593FF68bE84C966821eEf5F0a988C285D5B7CeC",
POOL_REGISTRY: "0x147780799840d541C1d7c998F0cbA996d11D62bb",
ACC1: "0xacD03D601e5bB1B275Bb94076fF46ED9D753435A",
BLOCK_NUMBER: 149670000,
},
unichainmainnet: {
CORE_COMPTROLLER: "0xe22af1e6b78318e1Fe1053Edbd7209b8Fc62c4Fe",
POOL_REGISTRY: "0x0C52403E16BcB8007C1e54887E1dFC1eC9765D7C",
ACC1: "0x0000000000000000000000000000000000000001",
BLOCK_NUMBER: 44190000,
},
basemainnet: {
CORE_COMPTROLLER: "0x0C7973F9598AA62f9e03B94E92C967fD5437426C",
COMPTROLLER: "0x0C7973F9598AA62f9e03B94E92C967fD5437426C",
POOL_REGISTRY: "0xeef902918DdeCD773D4B422aa1C6e1673EB9136F",
ACC1: "0xcdac0d6c6c59727a65f871236188350531885c43",
BLOCK_NUMBER: 44070000,
},
opmainnet: {
CORE_COMPTROLLER: "0x5593FF68bE84C966821eEf5F0a988C285D5B7CeC",
COMPTROLLER: "0x5593FF68bE84C966821eEf5F0a988C285D5B7CeC",
POOL_REGISTRY: "0x147780799840d541C1d7c998F0cbA996d11D62bb",
ACC1: "0xacD03D601e5bB1B275Bb94076fF46ED9D753435A",
BLOCK_NUMBER: 149670000,
},
unichainmainnet: {
CORE_COMPTROLLER: "0xe22af1e6b78318e1Fe1053Edbd7209b8Fc62c4Fe",
COMPTROLLER: "0xe22af1e6b78318e1Fe1053Edbd7209b8Fc62c4Fe",
POOL_REGISTRY: "0x0C52403E16BcB8007C1e54887E1dFC1eC9765D7C",
ACC1: "0x0000000000000000000000000000000000000001",
BLOCK_NUMBER: 44190000,
},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hardhat/Fork/constants.ts` around lines 214 - 231, The three new
network objects (basemainnet, opmainnet, unichainmainnet) are missing the
COMPTROLLER key which PoolLensForkTest (it destructures COMPTROLLER at multiple
places) expects; add a COMPTROLLER property to each network object in the
constants (e.g., set COMPTROLLER to the same value as CORE_COMPTROLLER if the
network has a single core pool) so PoolLensForkTest.ts can destructure and use
COMPTROLLER without runtime errors.

…urning empty list

PoolLens._getMarkets now returns only markets with internalCash > 0 for
non-core pools, avoiding reverts on deprecated markets while still
exposing active ones. This removes the need to redeploy PoolLens after
calling syncCash on remaining vTokens.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
tests/hardhat/Fork/PoolLensForkTest.ts (1)

18-20: ⚠️ Potential issue | 🟡 Minor

Guard unsupported FORKED_NETWORK values before destructuring.

Line 18 destructures getContractAddresses(...) at module load time, but that helper returns undefined for network names missing from constants.ts. Since TIME_BASED_NETWORKS includes networks not in contractAddresses (e.g., zksyncsepolia, opsepolia, basesepolia, unichainsepolia), setting FORKED_NETWORK to one of them will crash before the if (FORK) guard runs.

Example guard
-const { POOL_REGISTRY, COMPTROLLER, CORE_COMPTROLLER, ACC1, BLOCK_NUMBER } = getContractAddresses(
-  FORKED_NETWORK as string,
-);
+let POOL_REGISTRY: string;
+let COMPTROLLER: string | undefined;
+let CORE_COMPTROLLER: string;
+let ACC1: string | undefined;
+let BLOCK_NUMBER: number;
+
+const addresses = getContractAddresses(FORKED_NETWORK as string);
+if (addresses) {
+  ({ POOL_REGISTRY, COMPTROLLER, CORE_COMPTROLLER, ACC1, BLOCK_NUMBER } = addresses);
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hardhat/Fork/PoolLensForkTest.ts` around lines 18 - 20, The test file
destructures getContractAddresses(FORKED_NETWORK) at module load, which will
crash when getContractAddresses returns undefined for unsupported networks;
change the code to guard before destructuring by checking FORK and that
FORKED_NETWORK is present in TIME_BASED_NETWORKS or that
getContractAddresses(FORKED_NETWORK) returns a value, and only then call
getContractAddresses and destructure POOL_REGISTRY, COMPTROLLER,
CORE_COMPTROLLER, ACC1, BLOCK_NUMBER; alternatively, call getContractAddresses
into a const (e.g., addresses) and validate addresses !== undefined and throw or
skip tests with a clear message if missing to avoid the pre-guard crash.
tests/hardhat/Fork/constants.ts (1)

214-231: ⚠️ Potential issue | 🟡 Minor

Missing COMPTROLLER field will cause test issues.

The new network entries (basemainnet, opmainnet, unichainmainnet) are missing the COMPTROLLER field, but PoolLensForkTest.ts destructures and uses it at line 131. If these networks only have a single core pool, COMPTROLLER should equal CORE_COMPTROLLER.

Proposed fix
   basemainnet: {
     CORE_COMPTROLLER: "0x0C7973F9598AA62f9e03B94E92C967fD5437426C",
+    COMPTROLLER: "0x0C7973F9598AA62f9e03B94E92C967fD5437426C",
     POOL_REGISTRY: "0xeef902918DdeCD773D4B422aa1C6e1673EB9136F",
     ACC1: "0xcdac0d6c6c59727a65f871236188350531885c43",
     BLOCK_NUMBER: 44070000,
   },
   opmainnet: {
     CORE_COMPTROLLER: "0x5593FF68bE84C966821eEf5F0a988C285D5B7CeC",
+    COMPTROLLER: "0x5593FF68bE84C966821eEf5F0a988C285D5B7CeC",
     POOL_REGISTRY: "0x147780799840d541C1d7c998F0cbA996d11D62bb",
     ACC1: "0xacD03D601e5bB1B275Bb94076fF46ED9D753435A",
     BLOCK_NUMBER: 149670000,
   },
   unichainmainnet: {
     CORE_COMPTROLLER: "0xe22af1e6b78318e1Fe1053Edbd7209b8Fc62c4Fe",
+    COMPTROLLER: "0xe22af1e6b78318e1Fe1053Edbd7209b8Fc62c4Fe",
     POOL_REGISTRY: "0x0C52403E16BcB8007C1e54887E1dFC1eC9765D7C",
     ACC1: "0x0000000000000000000000000000000000000001",
     BLOCK_NUMBER: 44190000,
   },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hardhat/Fork/constants.ts` around lines 214 - 231, Add the missing
COMPTROLLER properties for the new network entries (basemainnet, opmainnet,
unichainmainnet) in the constants object so tests using COMPTROLLER (e.g.,
PoolLensForkTest.ts which destructures COMPTROLLER) don't break; set COMPTROLLER
to the same value as CORE_COMPTROLLER for each entry when there is a single core
pool (i.e., for basemainnet, opmainnet, and unichainmainnet assign COMPTROLLER =
CORE_COMPTROLLER).
contracts/Lens/PoolLens.sol (1)

289-291: ⚠️ Potential issue | 🟠 Major

Keep bad-debt accounting on getAllMarkets().

Markets with internalCash == 0 can still carry badDebt(). Using _getMarkets() here will understate both badDebts and totalBadDebtUsd for non-core pools—the exact markets most likely to have bad debt are the ones being filtered out.

Suggested fix
-        VToken[] memory markets = _getMarkets(ComptrollerInterface(comptrollerAddress));
+        VToken[] memory markets = ComptrollerViewInterface(comptrollerAddress).getAllMarkets();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/Lens/PoolLens.sol` around lines 289 - 291, The code uses
_getMarkets(ComptrollerInterface(comptrollerAddress)) which filters out markets
with internalCash == 0 and therefore omits markets that may have badDebt;
replace that call with the full market list via getAllMarkets() on the
comptroller (e.g., use
ComptrollerViewInterface(comptrollerAddress).getAllMarkets() or otherwise call
getAllMarkets() so the local variable markets includes every listed market),
then continue computing badDebt() and totalBadDebtUsd over that complete markets
array; update any references to _getMarkets in this context to avoid filtering
out potentially bad-debt-carrying markets.
🧹 Nitpick comments (1)
tests/hardhat/Fork/PoolLensForkTest.ts (1)

68-127: Tests assume valid CORE_COMPTROLLER but some networks have zero address.

Tests getPoolByComptroller, getPendingRewards, getPoolBadDebt, and getPoolDataFromVenusPool all use CORE_COMPTROLLER directly. For networks where CORE_COMPTROLLER is zero address (bsctestnet, bscmainnet), these tests will fail or produce meaningless results.

Consider adding a guard at the suite level:

before(async () => {
  if (!CORE_COMPTROLLER || CORE_COMPTROLLER === ethers.constants.AddressZero) {
    console.log(`Skipping PoolLens fork tests: no CORE_COMPTROLLER for ${FORKED_NETWORK}`);
    return;
  }
  // ... rest of setup
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hardhat/Fork/PoolLensForkTest.ts` around lines 68 - 127, The tests
assume CORE_COMPTROLLER is a valid non-zero address but some forked networks set
it to ethers.constants.AddressZero, causing meaningless failures in
getPoolByComptroller, getPendingRewards, getPoolBadDebt and
getPoolDataFromVenusPool; add a suite-level before(async () => { ... }) guard
that checks if CORE_COMPTROLLER is falsy or equals ethers.constants.AddressZero,
logs a message including FORKED_NETWORK, and returns early (skipping the rest of
test setup) so those tests are not run on networks without a valid
CORE_COMPTROLLER.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/hardhat/Fork/PoolLensForkTest.ts`:
- Line 65: The test unconditionally calls
Comptroller__factory.connect(CORE_COMPTROLLER, ethers.provider) which creates an
invalid instance when CORE_COMPTROLLER is the zero address; change the setup to
only call Comptroller__factory.connect when CORE_COMPTROLLER is not the zero
address (compare against ethers.constants.AddressZero) and set comptroller to
undefined/null otherwise, and then guard any tests that call
comptroller.getAllMarkets() (e.g. vTokenMetadataAll) by checking comptroller
exists and skipping/returning the test early when it does not.

---

Duplicate comments:
In `@contracts/Lens/PoolLens.sol`:
- Around line 289-291: The code uses
_getMarkets(ComptrollerInterface(comptrollerAddress)) which filters out markets
with internalCash == 0 and therefore omits markets that may have badDebt;
replace that call with the full market list via getAllMarkets() on the
comptroller (e.g., use
ComptrollerViewInterface(comptrollerAddress).getAllMarkets() or otherwise call
getAllMarkets() so the local variable markets includes every listed market),
then continue computing badDebt() and totalBadDebtUsd over that complete markets
array; update any references to _getMarkets in this context to avoid filtering
out potentially bad-debt-carrying markets.

In `@tests/hardhat/Fork/constants.ts`:
- Around line 214-231: Add the missing COMPTROLLER properties for the new
network entries (basemainnet, opmainnet, unichainmainnet) in the constants
object so tests using COMPTROLLER (e.g., PoolLensForkTest.ts which destructures
COMPTROLLER) don't break; set COMPTROLLER to the same value as CORE_COMPTROLLER
for each entry when there is a single core pool (i.e., for basemainnet,
opmainnet, and unichainmainnet assign COMPTROLLER = CORE_COMPTROLLER).

In `@tests/hardhat/Fork/PoolLensForkTest.ts`:
- Around line 18-20: The test file destructures
getContractAddresses(FORKED_NETWORK) at module load, which will crash when
getContractAddresses returns undefined for unsupported networks; change the code
to guard before destructuring by checking FORK and that FORKED_NETWORK is
present in TIME_BASED_NETWORKS or that getContractAddresses(FORKED_NETWORK)
returns a value, and only then call getContractAddresses and destructure
POOL_REGISTRY, COMPTROLLER, CORE_COMPTROLLER, ACC1, BLOCK_NUMBER; alternatively,
call getContractAddresses into a const (e.g., addresses) and validate addresses
!== undefined and throw or skip tests with a clear message if missing to avoid
the pre-guard crash.

---

Nitpick comments:
In `@tests/hardhat/Fork/PoolLensForkTest.ts`:
- Around line 68-127: The tests assume CORE_COMPTROLLER is a valid non-zero
address but some forked networks set it to ethers.constants.AddressZero, causing
meaningless failures in getPoolByComptroller, getPendingRewards, getPoolBadDebt
and getPoolDataFromVenusPool; add a suite-level before(async () => { ... })
guard that checks if CORE_COMPTROLLER is falsy or equals
ethers.constants.AddressZero, logs a message including FORKED_NETWORK, and
returns early (skipping the rest of test setup) so those tests are not run on
networks without a valid CORE_COMPTROLLER.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7803902a-a395-49e4-8ab8-7a659b11b791

📥 Commits

Reviewing files that changed from the base of the PR and between b8bd185 and 14d14cc.

📒 Files selected for processing (3)
  • contracts/Lens/PoolLens.sol
  • tests/hardhat/Fork/PoolLensForkTest.ts
  • tests/hardhat/Fork/constants.ts

);
await poolLens.deployed();

comptroller = Comptroller__factory.connect(CORE_COMPTROLLER, ethers.provider);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Comptroller connection will fail for networks with zero-address CORE_COMPTROLLER.

For bsctestnet and bscmainnet, CORE_COMPTROLLER is 0x0000..., so connecting to it creates an invalid contract instance. Tests like vTokenMetadataAll (line 111) that call comptroller.getAllMarkets() will fail.

Proposed fix
-      comptroller = Comptroller__factory.connect(CORE_COMPTROLLER, ethers.provider);
+      if (CORE_COMPTROLLER && CORE_COMPTROLLER !== ethers.constants.AddressZero) {
+        comptroller = Comptroller__factory.connect(CORE_COMPTROLLER, ethers.provider);
+      }

Then guard tests that use comptroller with a check for its existence.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hardhat/Fork/PoolLensForkTest.ts` at line 65, The test unconditionally
calls Comptroller__factory.connect(CORE_COMPTROLLER, ethers.provider) which
creates an invalid instance when CORE_COMPTROLLER is the zero address; change
the setup to only call Comptroller__factory.connect when CORE_COMPTROLLER is not
the zero address (compare against ethers.constants.AddressZero) and set
comptroller to undefined/null otherwise, and then guard any tests that call
comptroller.getAllMarkets() (e.g. vTokenMetadataAll) by checking comptroller
exists and skipping/returning the test early when it does not.

@fred-venus
Copy link
Copy Markdown
Contributor

lgtm

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/hardhat/Lens/RewardsSummary.ts (1)

58-58: Consider adding a non-core fixture path in this suite.

Both fixtures set corePoolComptroller == comptroller, so this file only exercises the core branch. A small additional case with a different corePoolComptroller would improve unit coverage of the filtered-market branch.

Also applies to: 171-171

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hardhat/Lens/RewardsSummary.ts` at line 58, The test currently only
covers the core branch because both fixtures set corePoolComptroller ==
comptroller; add a second fixture in the RewardsSummary suite that deploys
poolLens via poolLensFactory.deploy(isTimeBased, blocksPerYear,
comptroller.address) but sets corePoolComptroller to a different address (e.g.,
deploy a mockComptroller or use an alternate signer) so the code path where
corePoolComptroller != comptroller (the filtered-market branch) is exercised;
create a small test that uses that non-core fixture and asserts behavior
specific to the filtered-market branch to improve coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/hardhat/Lens/RewardsSummary.ts`:
- Line 58: The test currently only covers the core branch because both fixtures
set corePoolComptroller == comptroller; add a second fixture in the
RewardsSummary suite that deploys poolLens via
poolLensFactory.deploy(isTimeBased, blocksPerYear, comptroller.address) but sets
corePoolComptroller to a different address (e.g., deploy a mockComptroller or
use an alternate signer) so the code path where corePoolComptroller !=
comptroller (the filtered-market branch) is exercised; create a small test that
uses that non-core fixture and asserts behavior specific to the filtered-market
branch to improve coverage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 189a741f-be48-4fe3-ae19-cd109535f0f0

📥 Commits

Reviewing files that changed from the base of the PR and between 14d14cc and 9e94943.

📒 Files selected for processing (15)
  • deployments/arbitrumone/PoolLens.json
  • deployments/arbitrumone/solcInputs/09f8b2889a382752688c03578bc27f8d.json
  • deployments/basemainnet/PoolLens.json
  • deployments/basemainnet/solcInputs/09f8b2889a382752688c03578bc27f8d.json
  • deployments/ethereum/PoolLens.json
  • deployments/ethereum/solcInputs/09f8b2889a382752688c03578bc27f8d.json
  • deployments/opbnbmainnet/PoolLens.json
  • deployments/opbnbmainnet/solcInputs/09f8b2889a382752688c03578bc27f8d.json
  • deployments/opmainnet/PoolLens.json
  • deployments/opmainnet/solcInputs/09f8b2889a382752688c03578bc27f8d.json
  • deployments/unichainmainnet/PoolLens.json
  • deployments/unichainmainnet/solcInputs/09f8b2889a382752688c03578bc27f8d.json
  • deployments/zksyncmainnet/PoolLens.json
  • deployments/zksyncmainnet/solcInputs/10818118264cbc82e2eea514eb3f075b.json
  • tests/hardhat/Lens/RewardsSummary.ts

@github-actions
Copy link
Copy Markdown

Code Coverage

Package Line Rate Branch Rate Health
contracts 83% 72%
contracts.Gateway 98% 68%
contracts.Gateway.Interfaces 100% 100%
contracts.Lens 96% 70%
contracts.Lens.legacy 0% 0%
contracts.Pool 100% 92%
contracts.Rewards 96% 70%
contracts.Shortfall 100% 85%
contracts.legacy.RiskFund 0% 0%
contracts.lib 100% 89%
Summary 72% (1581 / 2202) 63% (523 / 832)

@fred-venus fred-venus marked this pull request as draft April 2, 2026 02:19
@fred-venus
Copy link
Copy Markdown
Contributor

We won't merge this, as its for a temporary usage

@fred-venus fred-venus changed the title [VPD-915]: Exclude deprecated markets from PoolLens [WONT MERGE]: Exclude deprecated markets from PoolLens Apr 2, 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.

2 participants